diff --git a/bsnes/data/bsnes.ico b/bsnes/data/bsnes.ico deleted file mode 100644 index 54acded4..00000000 Binary files a/bsnes/data/bsnes.ico and /dev/null differ diff --git a/bsnes/data/bsnes.png b/bsnes/data/bsnes.png deleted file mode 100644 index 02986ba8..00000000 Binary files a/bsnes/data/bsnes.png and /dev/null differ diff --git a/bsnes/nds/Makefile b/bsnes/nds/Makefile deleted file mode 100644 index 43007231..00000000 --- a/bsnes/nds/Makefile +++ /dev/null @@ -1,16 +0,0 @@ -nds_objects := nds-interface -nds_objects += nds-cpu nds-apu nds-ppu nds-gpu nds-video -nds_objects += nds-memory nds-system nds-slot1 nds-slot2 nds-wifi -objects += $(nds_objects) - -obj/nds-interface.o: $(nds)/interface/interface.cpp $(call rwildcard,$(nds)/interface) -obj/nds-cpu.o: $(nds)/cpu/cpu.cpp $(call rwildcard,$(nds)/cpu) -obj/nds-apu.o: $(nds)/apu/apu.cpp $(call rwildcard,$(nds)/apu) -obj/nds-ppu.o: $(nds)/ppu/ppu.cpp $(call rwildcard,$(nds)/ppu) -obj/nds-gpu.o: $(nds)/gpu/gpu.cpp $(call rwildcard,$(nds)/gpu) -obj/nds-video.o: $(nds)/video/video.cpp $(call rwildcard,$(nds)/video) -obj/nds-memory.o: $(nds)/memory/memory.cpp $(call rwildcard,$(nds)/memory) -obj/nds-system.o: $(nds)/system/system.cpp $(call rwildcard,$(nds)/system) -obj/nds-slot1.o: $(nds)/slot1/slot1.cpp $(call rwildcard,$(nds)/slot1) -obj/nds-slot2.o: $(nds)/slot2/slot2.cpp $(call rwildcard,$(nds)/slot2) -obj/nds-wifi.o: $(nds)/wifi/wifi.cpp $(call rwildcard,$(nds)/wifi) \ No newline at end of file diff --git a/bsnes/nds/apu/apu.cpp b/bsnes/nds/apu/apu.cpp deleted file mode 100644 index 3e80d320..00000000 --- a/bsnes/nds/apu/apu.cpp +++ /dev/null @@ -1,403 +0,0 @@ -#include - -namespace NintendoDS { - -APU apu; - - -void APU::power() { - for(unsigned n = 0; n < 16; n++) { - auto &v = voices[n]; - - v.enable = false; - v.hold = false; - v.running = false; - v.format = Voice::PCM8; - v.duty = 0; - v.limit = 0; - v.panning = 0x40; - v.volumeBase = 0x7f; - v.volumeExp = 0; - v.amplitude = 0x7f0; - - v.source = 0; - v.length = 0; - v.counter = 0; - v.sample = 0; - - v.init.source = 0; - v.init.counter = 0; - v.init.length1 = 0; - v.init.length2 = 0; - - v.event.action = [&, n]() { stepVoice(n); }; - } - // Audio runs at 16.8MHz. I've somewhat arbitrarily set - // it up so that things run in the following order: - // - channel read + update (+0) - // - mixer (+1) - // - eventually, capture (+2) - // - // Mixer runs at 33Khz = 66 MHz / 2048 - mixEvent.action = [&]() { stepMixer(); }; - arm7.event.queue.add(2048+1, mixEvent); - - powered = true; -} - -void APU::stepMixer() { - arm7.event.queue.add(2048, mixEvent); - - int64 l = 0, r = 0; - - for(unsigned n = 0; n < 16; n++) { - auto &v = voices[n]; - int64 s = v.sample * v.amplitude; - - l += s * (128 - v.panning); - r += s * (0 + v.panning); - } - l = sclamp<16>(l / 0x80000); - r = sclamp<16>(r / 0x80000); - - interface->audioSample(l, r); -} - -void APU::stepVoice(unsigned no) { - auto &v = voices[no]; - - uint32 t = arm7.event.queue.time; - - if(v.format == Voice::PCM8) stepPCM8(no); - else if(v.format == Voice::PCM16) stepPCM16(no); - else if(v.format == Voice::ADPCM4) stepADPCM4(no); - else if(v.format == Voice::PSG && no >= 14) stepNoise(no); - else if(v.format == Voice::PSG && no >= 8) stepPulse(no); - - v.counter = v.init.counter; - - uint32 fetchTime = arm7.event.queue.time - t; - uint32 nextSample = 4*(0x10000 - v.counter); - - nextSample -= fetchTime; - if(unsigned k = t & 3) - nextSample += 4 - k; - - // When this happens, the buffering can't keep up. It isn't clear - // what the real system will do, but it can't be anything good... - if(nextSample >= 0x80000000) - nextSample = 0; - - // This requires further thought and investigation. - // Do buffering issues delay the playback timer? (hopefully not) - // Do audio DMAs interleave in any way? (doubtful; it'd be 10x slower) - if(v.running) - arm7.event.queue.add(nextSample, v.event); -} - -void APU::stepPulse(unsigned no) { - auto &v = voices[no]; - uint3 step = v.state--; - - v.sample = step > v.duty? -0x7fff : +0x7fff; -} - -void APU::stepNoise(unsigned no) { - auto &v = voices[no]; - bool out = v.state & 1; - - v.state >>= 1; - v.state ^= 0x6000*out; - v.sample = out? -0x7fff : +0x7fff; -} - -void APU::stepPCM8(unsigned no) { - auto &v = voices[no]; - - checkLength(no); - fillBuffer(no); - v.sample = 0x100*int8(v.buffer[v.index/8] >> 4*(v.index & 6)); - v.index += 2; - v.length -= 1; -} - -void APU::stepPCM16(unsigned no) { - auto &v = voices[no]; - - checkLength(no); - fillBuffer(no); - v.sample = int16(v.buffer[v.index/8] >> 4*(v.index & 4)); - v.index += 4; - v.length -= 2; -} - -void APU::stepADPCM4(unsigned no) { - auto &v = voices[no]; - - static const int16 table[] = { - 0x0007,0x0008,0x0009,0x000a,0x000b,0x000c,0x000d,0x000e, - 0x0010,0x0011,0x0013,0x0015,0x0017,0x0019,0x001c,0x001f, - 0x0022,0x0025,0x0029,0x002d,0x0032,0x0037,0x003c,0x0042, - 0x0049,0x0050,0x0058,0x0061,0x006b,0x0076,0x0082,0x008f, - 0x009d,0x00ad,0x00be,0x00d1,0x00e6,0x00fd,0x0117,0x0133, - 0x0151,0x0173,0x0198,0x01c1,0x01ee,0x0220,0x0256,0x0292, - 0x02d4,0x031c,0x036c,0x03c3,0x0424,0x048e,0x0502,0x0583, - 0x0610,0x06ab,0x0756,0x0812,0x08e0,0x09c3,0x0abd,0x0bd0, - 0x0cff,0x0e4c,0x0fba,0x114c,0x1307,0x14ee,0x1706,0x1954, - 0x1bdc,0x1ea5,0x21b6,0x2515,0x28ca,0x2cdf,0x315b,0x364b, - 0x3bb9,0x41b2,0x4844,0x4f7e,0x5771,0x602f,0x69ce,0x7462, - 0x7fff - }; - - checkLength(no); - fillBuffer(no); - - if(v.state == 0x7fff) { - uint32 header = v.buffer[0]; - - // Minimum length is 4 words anyway, but check this later.. - v.sample = header>>0; - v.state = min(88, header>>16 & 0x7f); - v.index += 8; - v.length -= 4; - } - - int4 s = v.buffer[v.index/8] >> 4*(v.index & 7); - int16 x = table[v.state--]; - - int16 delta = x/8; - if(s & 1) delta += x/4; - if(s & 2) delta += x/2; - if(s & 4) delta += x/1, v.state += 2*(s & 3) + 3; - - if(s < 0) v.sample = max(-0x7fff, v.sample - delta); - else v.sample = min(+0x7fff, v.sample + delta); - - v.state = max(0, min(88, v.state)); - - if(++v.index & 1) return; - v.length -= 1; -} - - - -void APU::stopVoice(unsigned no) { - auto &v = voices[no]; - - arm7.event.queue.remove(v.event); - v.running = false; - if(v.hold == false) - v.sample = 0; -} - -void APU::fillBuffer(unsigned no) { - auto &v = voices[no]; - if(v.index) return; - - for(unsigned i = 0; i < 4; i++, v.source += 4) - v.buffer[i] = arm7.read(v.source, Word, true); -} - -void APU::checkLength(unsigned no) { - auto &v = voices[no]; - if(v.length) return; - - if(v.loop.source == 0xffffffff) { - // We're passing the loop point for the first time. In particular - // the hardware will store the ADPCM state. For this reason it's not - // possible to stream ADPCM audio without software assist. :( - v.length = v.loop.length; - v.loop.sample = v.sample; - v.loop.state = v.state; - v.loop.source = v.source; - if(v.index) // Account for buffer - v.loop.source += 4*(v.index/8 - 4); - - if(v.limit && v.length < 4) - return stopVoice(no); - } - else { - if(v.limit & Voice::once) - return stopVoice(no); - - // There are still issues with loops here.. or possibly - // readback of the voice status. - if(v.limit & Voice::looped) { - v.source = v.loop.source; - v.length = v.loop.length; - v.sample = v.loop.sample; - v.state = v.loop.state; - v.index = 0; - } - } -} - -void APU::checkEnable(unsigned no) { - auto &v = voices[no]; - - // maxmod's interpolated mode expects this undocumented behavior. Instead - // of software mixing, it resamples each voice's audio into a small buffer. - // Master enable is used to trigger every voice at the same time. - if(v.running == (enable && v.enable)) return; - - stopVoice(no); - v.running = enable && v.enable; - if(!v.running) return; - - uint32 next = 4*(0x10000 - v.init.counter); - - if(unsigned k = arm7.event.queue.time & 3) - next += 4 - k; // Align to 16MHz audio clock - - arm7.event.queue.add(next, v.event); - - // After 1 sample.. - v.length = 1; - v.event.action = [&, no]() { - uint32 period = 4*(0x10000 - v.init.counter); - - // Start the channel. From testing, it seems impossible to adjust - // length1/2 afterwards, so the settings must be latched somewhere. - // The loop flags can be changed though. - v.source = v.init.source; - v.counter = v.init.counter; - v.length = 4*v.init.length1; - v.loop.length = 4*v.init.length2; - v.loop.source = 0xffffffff; - v.sample = 0; - v.index = 0; - v.state = 0x7fff; - - // PCM has a couple more samples of startup latency. - // ADPCM takes a further 8 samples to process the header.. - switch(v.format) { - case Voice::PCM8: // add further startup latency - case Voice::PCM16: period = 3*period; break; - case Voice::ADPCM4: period = 11*period; break; - case Voice::PSG: period = 1*period; break; - } - - unsigned k = arm7.event.queue.time & 3; - if(k) period += 4 - k; - - arm7.event.queue.add(period, v.event); - v.event.action = [&, no]() { stepVoice(no); }; - }; -} - - -uint32 APU::regControl() { - return volume<<0 | output[0]<<8 | output[1]<<10 | muteDsp[0]<<12 | muteDsp[1]<<13 | enable<<15; -} - -uint32 APU::regBias() { - return bias; -} - -uint32 APU::regCaptureControl() { - return capture[0]<<7 | capture[1]<<15; -} - -uint32 APU::regCaptureDest(unsigned no) { - return captureDest[no]; -} - - - -void APU::regControl(uint32 data, uint32 mask) { - if(mask & 0x00ff) { - volume = data >> 0; - } - if(mask & 0xff00) { - output[0] = data >> 8; - output[1] = data >> 10; - muteDsp[0] = data >> 12; - muteDsp[1] = data >> 13; - enable = data >> 15; - - if(enable) { - // Start any pending voices - maxmod uses this for interpolated mode. - // What it does is: - // - clear the master enable - // - enable all 16 channels (won't do anything yet) - // - set the master enable (this will trigger all 16 at once) - // - wait ~16K clocks @ 33Mhz (16 samples), then set the mixing timer. - for(unsigned no = 0; no < 16; no++) - checkEnable(no); - } - } -} - -void APU::regBias(uint32 data, uint32 mask) { - bias = data; -} - -void APU::regCaptureControl(uint32 data, uint32 mask) { - capture[0] = data>>7; - capture[1] = data>>15; -} - -void APU::regCaptureDest(unsigned no, uint32 data, uint32 mask) { - captureDest[no] = data; -} - -void APU::regCaptureLength(unsigned no, uint32 data, uint32 mask) { - captureLength[no] = data; -} - - - -uint32 APU::regVoiceControl(unsigned no) { - auto &v = voices[no]; - - return v.volumeBase<<0 | v.volumeExp<<8 | v.hold<<15 | v.panning<<16 - | v.duty<<24 | v.limit<<27 | v.format<<29 | (v.running)<<31; -} - -void APU::regVoiceControl(unsigned no, uint32 data, uint32 mask) { - auto &v = voices[no]; - - int exponent[] = { 4, 3, 2, 0 }; - - if(mask & 0x0000007f) { - v.volumeBase = data >> 0; - v.amplitude = v.volumeBase << exponent[v.volumeExp]; - } - if(mask & 0x00008300) { - v.volumeExp = data >> 8; - v.hold = data >> 15; - v.amplitude = v.volumeBase << exponent[v.volumeExp]; - } - if(mask & 0x007f0000) { - v.panning = data >> 16; - } - if(mask & 0xff000000) { - v.duty = data >> 24; - v.limit = data >> 27; - v.format = data >> 29; - v.enable = data >> 31; - - checkEnable(no); - } -} - -void APU::regVoiceSource(unsigned no, uint32 data, uint32 mask) { - auto &v = voices[no]; - - v.init.source = data & 0x07fffffc; -} - -void APU::regVoicePeriod(unsigned no, uint32 data, uint32 mask) { - auto &v = voices[no]; - - if(mask & 0x0000ffff) v.init.counter ^= (v.init.counter ^ data>>0) & mask>>0; - if(mask & 0xffff0000) v.init.length1 ^= (v.init.length1 ^ data>>16) & mask>>16; -} - -void APU::regVoiceLength(unsigned no, uint32 data, uint32 mask) { - auto &v = voices[no]; - - v.init.length2 ^= (v.init.length2 ^ data) & mask & 0x3fffff; -} - -} diff --git a/bsnes/nds/apu/apu.hpp b/bsnes/nds/apu/apu.hpp deleted file mode 100644 index 7673fad7..00000000 --- a/bsnes/nds/apu/apu.hpp +++ /dev/null @@ -1,100 +0,0 @@ - -struct APU { - void power(); - - void stepMixer(); - - void stepVoice(unsigned no); - void stepPCM8(unsigned no); - void stepPCM16(unsigned no); - void stepADPCM4(unsigned no); - void stepPulse(unsigned no); - void stepNoise(unsigned no); - - void stopVoice(unsigned no); - void fillBuffer(unsigned no); - void checkLength(unsigned no); - void checkEnable(unsigned no); - - - uint32 regControl(); - uint32 regBias(); - uint32 regCaptureControl(); - uint32 regCaptureDest(unsigned no); - uint32 regVoiceControl(unsigned no); - - void regControl(uint32 data, uint32 mask); - void regBias(uint32 data, uint32 mask); - void regCaptureControl(uint32 data, uint32 mask); - void regCaptureDest(unsigned no, uint32 data, uint32 mask); - void regCaptureLength(unsigned no, uint32 data, uint32 mask); - - void regVoiceControl(unsigned no, uint32 data, uint32 mask); - void regVoiceSource(unsigned no, uint32 data, uint32 mask); - void regVoicePeriod(unsigned no, uint32 data, uint32 mask); - void regVoiceLength(unsigned no, uint32 data, uint32 mask); - - - - struct Voice { - uint1 enable, hold, running; - uint2 format; enum { PCM8, PCM16, ADPCM4, PSG }; - uint3 duty; - uint2 limit; enum { looped=1, once=2 }; - uint7 panning; - - // Volume is essentially some kind of float format. - // The effective value is base * 2^-(4 >> (3-exponent)). - uint7 volumeBase; - uint2 volumeExp; - - struct { - uint32 source; - uint16 counter; - uint16 length1; - uint32 length2; - } init; - - struct { - uint32 source; - uint32 length; - int16 sample; - int16 state; - } loop; - - uint32 source; - uint32 length; - uint16 counter; - - Event event; - - uint5 index; // nibble index into 16-byte buffer - uint32 buffer[4]; // holds 8, 16, or 32 buffered samples - int16 state; // used for pulse, noise, and ADPCM - - int32 amplitude; - int16 sample; - } voices[16]; - - Event mixEvent; - - // Voices 0 + 2 (L,R) are designated here as streaming audio. - // Voices 1 + 3 (L,R) are meant for DSP effects. Both are optional though. - uint1 powered; - uint1 enable; - uint10 bias; - uint7 volume; - uint2 output[2]; enum { srcMixer, srcDspL, srcDspR, srcDspMono }; - uint1 muteDsp[2]; // Don't send 1+3 to the mixer - avoids feedback. - uint1 dspToStream[3]; // Mix 1+3 back into 0+2. - - // Capture enables writing mixed audio to RAM - and in conjunction with - // voices 1 + 3, allows software DSP such as filtering or echo effects. - uint1 capture[2]; // Enable capturing - uint1 captureStream[2]; // ..otherwise mixer outputs - uint32 captureDest[2]; - uint32 captureLength[2]; - uint32 captureCount[2]; -}; - -extern APU apu; \ No newline at end of file diff --git a/bsnes/nds/cpu/arm.cpp b/bsnes/nds/cpu/arm.cpp deleted file mode 100644 index d47eb0b3..00000000 --- a/bsnes/nds/cpu/arm.cpp +++ /dev/null @@ -1,230 +0,0 @@ - -void ARMCore::armWritePsr(uint1 opcode, uint4 mask, uint32 rm) { - r[15] += 4; - - if(opcode == 0) return writeCpsr(rm, mask); - if(opcode == 1) { - if(mode == USR || mode == SYS) return; - - uint32 update = 0xff000000*(mask>>3) | 0xff*(mask&1); - spsr() ^= (spsr() ^ rm) & update; - } -} - -void ARMCore::armReadPsr(uint1 opcode, uint4 ird) { - r[15] += 4; - - if(opcode == 0) r[ird] = readCpsr(); - if(opcode == 1) { - if(mode == USR || mode == SYS) return; - r[ird] = spsr(); - } - if(ird == 15) branch(0, r[15]); -} - -void ARMCore::armBranch(uint1 link, uint1 exch, int26 offset) { - if(link) r[14] = r[15] - 4; - branch(exch, r[15] + offset); -} - -void ARMCore::armBranchEx(uint1 link, uint4 irm) { - if(link) r[14] = r[15] - 4; - branch(r[irm] & 1, r[irm]); -} - -void ARMCore::armClz(uint4 ird, uint4 irm) { - auto &rd = r[ird], rm = r[irm]; - r[15] += 4; - - if(rm == 0) { rd = 32; return; } - - rd = 0; - while(~rm & 1<<31) - rm <<= 1, rd++; -} - -void ARMCore::armDspAdd(uint2 opcode, uint4 ird, uint4 irn, uint4 irm) { - auto &rd = r[ird], rn = r[irn], rm = r[irm]; - r[15] += 4; - - if(opcode & 2) { // qdadd/qdsub - rd = rm, rm += rm; - if(oflow(rm,rd,rd) & 1<<31) - Qf = -1, rm = 0x80000000 - (rm>>31); - } - if(opcode & 1) rd = rn - rm, (rm = ~rm); // qsub - else rd = rn + rm; // qadd - - if(oflow(rd,rn,rm) & 1<<31) - Qf = -1, rd = 0x80000000 - (rd>>31); - - if(ird == 15) branch(0, r[15]); -} - -void ARMCore::armDspMul(uint2 opcode, uint2 xy, uint4 ird, uint4 irn, uint4 irm, uint4 irs) { - auto rn = r[irn]; - r[15] += 4; - - if(opcode == 1) { // smulwy, smlawy - int32 rm = r[irm]; - int16 rs = r[irs] >> 16*(xy>>1); - uint32 rd = (int64) rm * rs >> 16; - - if(xy & 1) { - uint32 ra = rd + rn; - Qf |= oflow(ra,rd,rn); - rd = ra; - } - r[ird] = rd; - } - else { // smulxy(3), smlaxy(0), smlalxy(2) - int16 rm = r[irm] >> 16*(xy & 1); - int16 rs = r[irs] >> 16*(xy>>1); - int64 rd = (int64) rm * rs; - - if(opcode == 0) Qf |= oflow(rd+rn, rd, rn); // smlaxy - if(opcode != 3 /*accumulate*/) rd += rn; // smlaxy, smlalxy - if(opcode == 2 /*long*/) { - r[irn] = rd; rd >>= 32; - rd += r[ird]; - if(irn == 15) branch(0, r[15]); - } - r[ird] = rd; - } - if(ird == 15) branch(0, r[15]); -} - -void ARMCore::armMultiply(uint4 opcode, uint4 ird, uint4 irn, uint4 irm, uint4 irs) { - bool long_mul = opcode & 8, accumulate = opcode & 2; - bool signed_mul = opcode & 4, setf = opcode & 1; - - auto rm = r[irm], rs = r[irs], rn = r[irn]; - int64 rd = (uint64) rm * rs; - r[15] += 4; - - if(setf) Zf = 0; - if(accumulate) rd += rn; - if(long_mul) { - r[irn] = rd; rd >>= 32; - - if(setf) Zf |= r[irn]; - if(accumulate) rd += r[ird]; - if(signed_mul) { - if(rm & 1<<31) rd -= rs; - if(rs & 1<<31) rd -= rm; - } - } - r[ird] = rd; - if(setf) Nf = r[ird], Zf |= r[ird]; - if(ird == 15) branch(0, r[15]); -} - -void ARMCore::armData(uint5 opcode, uint4 ird, uint4 irn, SOut rm) { - auto rn = r[irn]; - r[15] += 4; - - alu(opcode, r[ird], rn, rm); - - if(ird == 15 && (opcode & 1)) writeCpsr(spsr(), 0xf); - if(ird == 15) branch(Tf, r[15]); // use Tf here because MOVS/SUBS changes it -} - -void ARMCore::armDataRs(uint5 opcode, uint4 ird, uint4 irn, uint4 irm, uint2 sh, uint4 irs) { - auto rs = r[irs]; - r[15] += 4; - - if(sh == 0) alu(opcode, r[ird], r[irn], lsl(r[irm], rs)); - if(sh == 1) alu(opcode, r[ird], r[irn], lsr(r[irm], rs)); - if(sh == 2) alu(opcode, r[ird], r[irn], asr(r[irm], rs)); - if(sh == 3) alu(opcode, r[ird], r[irn], ror(r[irm], rs)); - - if(ird == 15 && (opcode & 1)) writeCpsr(spsr(), 0xf); - if(ird == 15) branch(Tf, r[15]); -} - -void ARMCore::armMemSwap(uint1 opcode, uint4 ird, uint4 irn, uint4 irm) { - auto rn = r[irn]; - r[15] += 4; - - uint32 rd = load(rn, opcode? Byte : Word); - store(rn, opcode? Byte : Word, r[irm]); - r[ird] = rd; - if(ird == 15) branch(r[15] & 1, r[15]); -} - -void ARMCore::armMem(uint5 opcode, uint4 ird, uint4 irn, uint32 rm) { - auto &rd = r[ird], &rn = r[irn]; - uint32 update = opcode & 0x08? rn+rm : rn-rm; - uint32 addr = opcode & 0x10? update : rn; - r[15] += 4; - - if((opcode & 2) || !(opcode & 0x10)) rn = update; - - if(opcode & 1) rd = load(addr, opcode & 4? Byte : Word); // ldr, ldrb - else store(addr, opcode & 4? Byte : Word, rd); // str, strb - - if(ird == 15) branch(r[15] & 1, r[15]); -} - -void ARMCore::armMem_v4(uint5 opcode, uint2 sh, uint4 ird, uint4 irn, uint32 rm) { - auto &rd = r[ird], &rn = r[irn]; - uint32 update = opcode & 0x08? rn+rm : rn-rm; - uint32 addr = opcode & 0x10? update : rn; - r[15] += 4; - - if((opcode & 2) || !(opcode & 0x10)) rn = update; - - if(opcode & 1) { - if(sh == 1) rd = load(addr, Half); // ldrh - if(sh == 3) rd = (int16) load(addr, Half); // ldrsh - if(sh == 2) rd = (int8) load(addr, Byte); // ldrsb - if(ird == 15) branch(r[15] & 1, r[15]); - } else { - if(sh == 1) store(addr, Half, rd); // strh - } -} - -void ARMCore::armMem_v5(uint5 opcode, uint2 sh, uint4 ird, uint4 irn, uint32 rm) { - auto &rd = r[ird], &rn = r[irn]; - uint32 update = opcode & 0x08? rn+rm : rn-rm; - uint32 addr = opcode & 0x10? update : rn; - r[15] += 4; - - if((opcode & 2) || !(opcode & 0x10)) rn = update; - - if(~opcode & 1) { - if(sh == 3) { store(addr, Word, r[ird&~1]); store(addr+4, Word, r[ird|1]); } // strd - if(sh == 2) { r[ird&~1] = load(addr, Word); r[ird|1] = load(addr+4, Word); // ldrd - if(ird >= 14) branch(r[15] & 1, r[15]); } - } -} - -void ARMCore::armBlock(uint5 opcode, uint4 irn, uint16 rlist) { - unsigned index = opcode & 0x18, up = opcode & 0x08; - bool writeback = opcode & 0x02, ld = opcode & 0x01; - bool user = (opcode & 4) && !(ld && (rlist & 1<<15)); - auto &rn = r[irn]; - uint32 addr = rn, base = rn, size = 4*bit::count(rlist); - r[15] += 4; - - if(index == 0x00) addr += 4 - size; // da - if(index == 0x10) addr += 0 - size; // db - if(index == 0x18) addr += 4; // ib - - if(user) swapBank(mode); - - for(unsigned b = 0, s = 0; b < 16; b++) { - if(~rlist & 1<= 0; j--) - crc = crc>>1 ^ (crc&1) * (table[j] << j); - } - return crc; -} - -void ARM7TDMI::main() { - if(auto card = slot1.card) { - // ARM7 BIOS and firmware should be doing this, but it requires - // clock, card emulation and fancy things like that. - uint32 arm9src = card->rom.read(0x20, Word), arm7src = card->rom.read(0x30, Word); - uint32 arm9entry = card->rom.read(0x24, Word), arm7entry = card->rom.read(0x34, Word); - uint32 arm9dest = card->rom.read(0x28, Word), arm7dest = card->rom.read(0x38, Word); - uint32 arm9size = card->rom.read(0x2c, Word), arm7size = card->rom.read(0x3c, Word); - - // Copy user settings to RAM - // - Homebrew and games (?) both require this. libnds actually attempts - // to read the settings from flash, but the struct contains a bitfield - // that GCC expands by 2 bytes, throwing the size and checksum off. - for(unsigned n = 0; n < 0x70; n += 1) { - store(0x02fffc80+n, Byte, system.firmware.read(0x3fe00+n, Byte)); - } - - // Check CRCs on firmware data and warn if incorrect - uint8 *wifiData = &system.firmware.data[0x0002a]; - - uint8 *wfcData[3] = { - &system.firmware.data[0x3fa00], - &system.firmware.data[0x3fb00], - &system.firmware.data[0x3fc00], - }; - uint8 *userData[2] = { - &system.firmware.data[0x3fe00], - &system.firmware.data[0x3ff00], - }; - - // MAC address + Wifi chipset programming data - uint32 wifiDataLen = wifiData[2] | wifiData[3]<<8; - uint32 wifiDataExpected = wifiData[0] | wifiData[1]<<8; - uint32 wifiDataActual = crc16(wifiData+2, wifiDataLen, 0); - - if(wifiDataExpected != wifiDataActual) - print("Warning: Wifi chipset data: crc is ", - hex<4>(wifiDataActual),"; expected ",hex<4>(wifiDataExpected),"\n"); - - // Nintendo Wifi Connection - access point IDs + WEP passwords - for(unsigned i = 0; i < 3; i++) { - uint32 expected = wfcData[i][0xfe] | wfcData[i][0xff]<<8; - uint32 actual = crc16(wfcData[i], 0xfe, 0); - - if(expected != actual) - print("Warning: WFC access point #",i,": crc is ", - hex<4>(actual),"; expected ",hex<4>(expected),"\n"); - } - - // User settings area - nickname, birthday, favorite color etc. - for(unsigned i = 0; i < 2; i++) { - uint32 expected = userData[i][0x72] | userData[i][0x73]<<8; - uint32 actual = crc16(userData[i], 0x70, 0xffff); - - if(expected != actual) - print("Warning: User settings #",i,": crc is ", - hex<4>(actual),"; expected ",hex<4>(expected),"\n"); - } - - // Copy header into RAM - for(unsigned n = 0; n < 0x200; n += 4) { - write(0x02fffe00+n, Word, 0, card->rom.read(n, Word)); - } - - // Copy executables - if(0x200 <= arm9src && arm9src + arm9size <= card->rom.size) { - if(0x02000000 <= arm9dest && arm9dest + arm9size <= 0x023bfe00) { - for(unsigned n = 0; n < arm9size; n += 4) - write(arm9dest + n, Word, 0, card->rom.read(arm9src + n, Word)); - } - } - if(0x200 <= arm7src && arm7src + arm7size <= card->rom.size) { - if(0x02000000 <= arm7dest && arm7dest + arm7size <= 0x023bfe00 - || 0x037f8000 <= arm7dest && arm7dest + arm7size <= 0x03807e00) { - for(unsigned n = 0; n < arm7size; n += 4) - write(arm7dest + n, Word, 0, card->rom.read(arm7src + n, Word)); - } - } - // Should write the card's ROM ID to RAM too... where is it again? - arm7.booted = 0; - arm9.booted = 0; - - arm7.writeCpsr(0xdf, 0xf); - arm7.branch(arm7entry & 1, arm7entry); - arm7.r[15] = arm7entry; // pc - arm7.r[14] = arm7entry; // lr - arm7.r[13] = 0x03007f00; // sp - arm7.r_irq[0] = 0x03007fa0; // sp_irq - arm7.r_svc[0] = 0x03007fe0; // sp_svc - - arm9.writeCpsr(0xdf, 0xf); - arm9.branch(arm9entry & 1, arm9entry); - arm9.r[15] = arm9entry; // pc - arm9.r[14] = arm9entry; // lr - arm9.r[13] = 0x00803ec0; // sp - arm9.r_irq[0] = 0x00803fa0; // sp_irq - arm9.r_svc[0] = 0x00803fc0; // sp_svc - } - - arm7.event.queue.time -= arm7.clock; - for(unsigned n=1; n <= arm7.event.queue.size; n++) - arm7.event.queue.items[n]->time -= arm7.clock; - - arm7.clock = 0; - - for(;;) { - if(arm7.clock >= 256) - co_switch(arm9.thread); - - event.irq = interrupt.gate && (interrupt.enable & interrupt.flags); - //if(event.irq && !If) { - // print("arm7: irq (if=",hex<8>(interrupt.flags),")\n"); - //} - - if(Tf) execTHUMB(); - else execARM(); - } -} - -void ARM7TDMI::istep(unsigned clocks) { - arm7.clock += 2*clocks; - event.queue.step(2*clocks); -} - -void ARM7TDMI::step(unsigned clocks) { - return istep(clocks); -} - - - -void ARM7TDMI::execARM() { - if(branched) { - //if(r[15] == 0) print(hex<8>(r[14]), ": jump to nullptr!\n"); - branched = false; r[15] &= ~3; - iexecute = fetch(r[15], Word, 0); r[15] += 4; - idecode = fetch(r[15], Word, 1); r[15] += 4; - } else { - iexecute = idecode, idecode = ifetch; - } - ifetch = fetch(r[15], Word, 1); - uint32 i = iexecute; - - if(event.irq && !If) return irq(); - //if(trace && r[15] >= 0x2000000) traceInsn(); - - if(!evalCond(i>>28)) { r[15] += 4; return; } - - // opcode, sh, Rd, Rn, Rm, Rs - if(imatch("00x10xx0/////")) { - if(imatch("00110r10/// ..../")) return armWritePsr(i>>22, i>>16, armImmed(i, i>>8)); - if(imatch("00010r10/// 0000/")) return armWritePsr(i>>22, i>>16, armRm(i)); - if(imatch("00010r00/// 0000/")) return armReadPsr (i>>22, i>>12); - if(imatch("00010010/// 00l1/")) return armBranchEx( i>>5, i); - if(imatch("00010b00/// 1001/")) return armMemSwap (i>>22, i>>12, i>>16, i); - } - if(imatch("000...../// 1..1/")) { - if(imatch("0000luas/// 1001/")) return armMultiply(i>>20, i>>16, i>>12, i, i>>8); - if(imatch("000pu0wl/// 1sh1/")) return armMem_v4 (i>>20, i>>5, i>>12, i>>16, armRm(i)); - if(imatch("000pu1wl/// 1sh1/")) return armMem_v4 (i>>20, i>>5, i>>12, i>>16, armOffset8(i, i>>8)); - } - if(imatch("001aaaas/// ..../")) return armData (i>>20, i>>12, i>>16, armImmed(i, i>>8)); - if(imatch("000aaaas/// .sh0/")) return armData (i>>20, i>>12, i>>16, shiftImm(i, i>>5, i>>7)); - if(imatch("010pubwl/// ..../")) return armMem (i>>20, i>>12, i>>16, armOffset12(i)); - if(imatch("011pubwl/// ...0/")) return armMem (i>>20, i>>12, i>>16, shiftImm(i, i>>5, i>>7)); - if(imatch("100puswl/// ..../")) return armBlock (i>>20, i>>16, i); - if(imatch("101l..../// ..../")) return armBranch (i>>24, 0, i<<2); - if(imatch("000aaaas/// 0sh1/")) return armDataRs (i>>20, i>>12, i>>16, i, i>>5, i>>8); - - if(imatch("1111..../// ..../")) return swi (); - return undefined(); -} - -void ARM7TDMI::execTHUMB() { - if(branched) { - //if(r[15] == 0) print(hex<8>(r[14]), ": jump to nullptr!\n"); - branched = false; r[15] &= ~1; - iexecute = fetch(r[15], Half, 0) >> 8*(r[15] & 2) & 0xffff; r[15] += 2; - idecode = fetch(r[15], Half, 1) >> 8*(r[15] & 2) & 0xffff; r[15] += 2; - } else { - iexecute = idecode, idecode = ifetch; - } - ifetch = fetch(r[15], Half, 1) >> 8*(r[15] & 2) & 0xffff; - uint16 i = iexecute; - - if(event.irq && !If) return irq(); - //if(trace && r[15] >= 0x2000000) traceInsn(); - - if(imatch("00011ismmmnnnddd")) return thumbAddSub (i>>9, i, i>>3, i>>6); - if(imatch("000ssiiiiimmmddd")) return thumbShiftImm(i>>11, i, i>>3, i>>6); - if(imatch("001oodddiiiiiiii")) return thumbDataImm (i>>11, i>>8, i); - if(imatch("010000oooommmddd")) return thumbDataLo (i>>6, i, i>>3); - if(imatch("010001oodmmmmddd")) return thumbDataHi (i>>8, (i&7)+(i>>4&8), i>>3); - - if(imatch("0101ooommmnnnddd")) return thumbMemReg (i>>9, i, i>>3, i>>6); - if(imatch("011bliiiiinnnddd")) return thumbMemImm (i>>11, i, i>>3, i>>6); - if(imatch("1000liiiiinnnddd")) return thumbMemImm (i>>11, i, i>>3, i>>6); - - if(imatch("10110000siiiiiii")) return thumbAddSP ( i>>7, i); - if(imatch("01001dddrrrrrrrr")) return thumbRelative(i>>11, i>>8, i); - if(imatch("1001odddrrrrrrrr")) return thumbRelative(i>>11, i>>8, i); - if(imatch("1010odddrrrrrrrr")) return thumbRelative(i>>11, i>>8, i); - - if(imatch("1101ccccrrrrrrrr")) return thumbCond ( i>>8, i); - if(imatch("11100rrrrrrrrrrr")) return thumbBranch (i); - if(imatch("11110rrrrrrrrrrr")) return thumbBh (i); - if(imatch("11111rrrrrrrrrrr")) return thumbBlx (1, i); - - if(imatch("1o..lnnnrrrrrrrr")) return thumbBlock (i>>11, i>>8, i); - - return undefined(); -} - - - -uint32 ARM7TDMI::fetch(uint32 addr, uint32 size, bool s) { - return read(addr, size, s); -} - -uint32 ARM7TDMI::read(uint32 addr, uint32 size, bool s) { - const int h = size==Word? 2 : 1; // 16-bit bus timing - const int e = 8*!s + h; // EWRAM timing - - //if((addr & 0xf3ff000) == 0x23ff000) { - // istep(e); - // uint32 data = system.ewram.read(addr % 0x400000, size); - // print(hex<8>(arm7.event.queue.time), " ",hex<8>(r[15])," arm7: r ",hex<8>(addr),":",size," = ",hex<8>(data),"\n"); - // return data; - //} - - switch(addr >> 23) { - case 0x00>>3: - case 0x08>>3: istep(1); addr &= bios.size-1; return bios.read(addr, size); - case 0x20>>3: - case 0x28>>3: istep(e); addr %= 0x400000; return system.ewram.read(addr, size); - case 0x30>>3: istep(1); addr %= 0x008000; return system.swram[addr>>14].read(addr % 0x4000, size); - case 0x38>>3: istep(1); addr %= 0x010000; return system.iwram.read(addr, size); - case 0x40>>3: istep(1); { // return readReg(addr, size); - uint32 data = readReg(addr, size); - //print(hex<8>(arm7.event.queue.time), " ", hex<8>(r[15])," arm7: r ",hex<8>(addr),":",size," = ",hex<8>(data),"\n"); - return data; - } - case 0x48>>3: istep(1); return wifi.read(addr, size); - case 0x60>>3: - case 0x68>>3: istep(h); addr %= 0x040000; return system.vmap.arm7[addr>>14].read(addr, size); - } - istep(1); - return 0; -} - -void ARM7TDMI::write(uint32 addr, uint32 size, bool s, uint32 data) { - const int h = size==Word? 2 : 1; // 16-bit bus timing - const int e = 8*!s + h; // EWRAM timing - - //if((addr & 0xf3ff000) == 0x23ff000) - // print(hex<8>(arm7.event.queue.time), " ",hex<8>(r[15]), " arm7: w ",hex<8>(addr),":",size," = ",hex<8>(data),"\n"); - - switch(addr >> 23) { - case 0x20>>3: - case 0x28>>3: istep(e); addr %= 0x400000; return system.ewram.write(addr, size, data); - case 0x30>>3: istep(1); addr %= 0x008000; return system.swram[addr>>14].write(addr % 0x4000, size, data); - case 0x38>>3: istep(1); addr %= 0x010000; return system.iwram.write(addr, size, data); - case 0x40>>3: istep(1); { // return writeReg(addr, size, data); - //if(addr != 0x4000301) - // print(hex<8>(arm7.event.queue.time), " ", hex<8>(r[15])," arm7: w ",hex<8>(addr),":",size," = ",hex<8>(data),"\n"); - writeReg(addr, size, data); - return; - } - case 0x48>>3: istep(1); return wifi.write(addr, size, data); - case 0x60>>3: - case 0x68>>3: istep(h); addr %= 0x040000; if(size > Byte) return system.vmap.arm7[addr>>14].write(addr, size, data); - // STRB - special case, only works on ARM7 - auto &page = system.vmap.arm7[addr>>14]; - page[addr] &= addr & 1? 0x00ff : 0xff00; - page[addr] |= addr & 1? data & 0xff00 : data & 0x00ff; - return; - } - istep(1); -} - -void ARM7TDMI::dataCop(uint4 cpno, uint4 op1, uint4 ird, uint4 irn, uint4 irm, uint4 op2) { - return undefined(); -} - - - -uint32 ARM7TDMI::readReg(uint32 addr, uint32 size) { - switch(addr-0x4000000 & ~3) { - - case 0x134: { - // Aux GPIO - // - missing link port (SI pin = clock /IRQ) - // - misc inputs - uint8 keys = 0; - for(unsigned n = 10; n < 16; n++) { - if(interface->inputPoll(ID::Port::Buttons, 0, n)) - keys += 1 << n-10; - } - if(system.touchscreen.penDown()) keys += 1<<6; - if(interface->inputPoll(ID::Port::Sensors, 0, ID::Sensors::Lid)==0) keys += 1<<7; - return (keys ^ 0xff)<<16 | regSio()<<0; - } - - case 0x138: return regRtc(); // GPIO - system clock - case 0x1c0: return regSpi(); // SPI - power, touch, firmware flash - - // Memory status, slot 2 - case 0x204: return arm9.ramPriority<<15 | arm9.slot1access<<11 - | arm9.slot2access<< 7 | regSlot2Control(); - // Wifi waitstates - case 0x206: break; - - case 0x240: break; // VRAM status - case 0x241: break; // SWRAM status - - case 0x300: return flag300<<1 | booted<<0; - case 0x304: return apu.powered<<0 | wifi.powered<<1; - - case 0x400: case 0x410: case 0x420: case 0x430: - case 0x440: case 0x450: case 0x460: case 0x470: - case 0x480: case 0x490: case 0x4a0: case 0x4b0: - case 0x4c0: case 0x4d0: case 0x4e0: case 0x4f0: - return apu.regVoiceControl(addr>>4 & 15); - - case 0x500: return apu.regControl(); - case 0x504: return apu.regBias(); - case 0x508: return apu.regCaptureControl(); - case 0x510: return apu.regCaptureDest(0); - case 0x518: return apu.regCaptureDest(1); - - } - return CPUCore::readReg(addr, size); -} - -void ARM7TDMI::writeReg(uint32 addr, uint32 size, uint32 data) { - uint32 mask = 0xffffffff; - if(size == Half) mask = 0xffff << 8*(addr & 2); - if(size == Byte) mask = 0xff << 8*(addr & 3); - - data &= mask; - - switch(addr-0x4000000 & ~3) { - - case 0x134: return regSio(data, mask); // GPIO - missing link port - case 0x138: return regRtc(data, mask); // GPIO - system clock - case 0x1c0: return regSpi(data, mask); // SPI - power, touch, firmware flash - - case 0x204: return regSlot2Control(data, mask); - case 0x206: break; // Wifi waitstates - - case 0x300: // System mode - booted |= data & 1; // not possible to clear it - if(mask & 0xff) - flag300 = data >> 1; - - // 0x4000: halt arm9 and enter GBA mode - // 0x8000: halt arm7 and wait for IRQ - // 0xc000: halt system and wait for IRQ (low-power sleep mode) - // - // Nearly everything is frozen in sleep mode, including timers. Only - // a few things can generate interrupts to bring it back out: - // - lid sensor, buttons - // - alarm from real-time clock - // - wireless chipset (?) - // - cart in slot 1 or 2 (?) - if(data & 0xc000) { - //print("arm7: wait (ime=",interrupt.gate,", ie=",hex<8>(interrupt.enable),")\n"); - powerState = waiting; - for(;;) { - if((interrupt.enable & interrupt.flags)) { - powerState = running; - break; - } - istep(256); - if(arm7.clock >= 256) - co_switch(arm9.thread); - } - } - return; - - case 0x304: // Power - if(mask & 0xff) { - apu.powered = data>>0; - wifi.powered = data>>1; - } - return; - - case 0x308: break; // BIOS protection - - case 0x400: case 0x410: case 0x420: case 0x430: - case 0x440: case 0x450: case 0x460: case 0x470: - case 0x480: case 0x490: case 0x4a0: case 0x4b0: - case 0x4c0: case 0x4d0: case 0x4e0: case 0x4f0: - return apu.regVoiceControl(addr>>4 & 15, data, mask); - - case 0x404: case 0x414: case 0x424: case 0x434: - case 0x444: case 0x454: case 0x464: case 0x474: - case 0x484: case 0x494: case 0x4a4: case 0x4b4: - case 0x4c4: case 0x4d4: case 0x4e4: case 0x4f4: - return apu.regVoiceSource(addr>>4 & 15, data, mask); - - case 0x408: case 0x418: case 0x428: case 0x438: - case 0x448: case 0x458: case 0x468: case 0x478: - case 0x488: case 0x498: case 0x4a8: case 0x4b8: - case 0x4c8: case 0x4d8: case 0x4e8: case 0x4f8: - return apu.regVoicePeriod(addr>>4 & 15, data, mask); - - case 0x40c: case 0x41c: case 0x42c: case 0x43c: - case 0x44c: case 0x45c: case 0x46c: case 0x47c: - case 0x48c: case 0x49c: case 0x4ac: case 0x4bc: - case 0x4cc: case 0x4dc: case 0x4ec: case 0x4fc: - return apu.regVoiceLength(addr>>4 & 15, data, mask); - - case 0x500: return apu.regControl(data, mask); - case 0x504: return apu.regBias(data, mask); - case 0x508: return apu.regCaptureControl(data, mask); - case 0x510: return apu.regCaptureDest(0, data, mask); - case 0x514: return apu.regCaptureLength(0, data, mask); - case 0x518: return apu.regCaptureDest(1, data, mask); - case 0x51c: return apu.regCaptureLength(1, data, mask); - - } - return CPUCore::writeReg(addr, size, data); -} - - -uint32 ARM7TDMI::regSpi() { - return spi.divider<<0 | spi.device<<8 | spi.size<<10 - | spi.hold<<11 | spi.irq<<14 | spi.enable<<15 - | spi.data<<16; -} - -void ARM7TDMI::regSpi(uint32 data, uint32 mask) { - if(mask & 0x000000ff) { - spi.divider = data>>0; - } - if(mask & 0x0000ff00) { - spi.device = data>>8; - spi.size = data>>10; - spi.hold = data>>11; - spi.irq = data>>14; - spi.enable = data>>15; - - if(spi.enable == false) { - // Hrm, must be implicit as libnds does not release the hold - // before last transfer - or is spi.hold not delayed after all? - system.firmware.select(false); - system.powerMgr.select(false); - system.touchscreen.select(false); - } - } - if(mask & 0xffff0000) { - if(!spi.enable) return; - - SPIDevice* device = nullptr; - if(spi.device == SPI::flash) device = &system.firmware; - if(spi.device == SPI::power) device = &system.powerMgr; - if(spi.device == SPI::touch) device = &system.touchscreen; - - if(device) { - // SPI transfers are bidirectional so there's always a read+write. - device->select(true); - spi.data = device->transfer(data>>16); - device->select(spi.hold); - } - } -} - - - -uint32 ARM7TDMI::regRtc() { - // I've blithely assumed: pin = (out | ~dir) & in - // - // Something like that is necessary because Nintendo read-modify-writes - // the output pins. - return uint4( (rtc.out[0] | ~rtc.dir[0]) & rtc.in[0] )<<0 | rtc.dir[0]<<4 - | uint4( (rtc.out[1] | ~rtc.dir[1]) & rtc.in[1] )<<8 | rtc.dir[1]<<12; -} - -void ARM7TDMI::regRtc(uint32 data, uint32 mask) { - // It would've been nice if the clock was on the SPI bus, like the touchpad, - // firmware and power chips.. it seems that wasn't possible because of the - // bi-directional data pin. Software has to bit-bang the GPIO pins instead. - - if(mask & 0x00ff) { - rtc.out[0] = data>>0; // if dir==1, use output from the DS side. - rtc.dir[0] = data>>4; // if dir==0, use as input with pullup (?) - } - if(mask & 0xff00) { - rtc.out[1] = data>>0; // these may exist, but don't appear to be used. - rtc.dir[1] = data>>4; - } - // All pins can be either inputs or outputs. - // "in" is the value being driven externally (or 1, if not). - uint4 pins = (rtc.out[0] | ~rtc.dir[0]) & rtc.in[0]; - rtc.in[0] = system.clock.io(pins); -} - - - -uint32 ARM7TDMI::regSio() { - return sio.in<<0 | sio.dir<<4 | sio.irq<<8 | sio.mode<<14; -} - -void ARM7TDMI::regSio(uint32 data, uint32 mask) { - sio.out = data>>0; - sio.dir = data>>4; - sio.irq = data>>8; - sio.mode = data>>14; -} - diff --git a/bsnes/nds/cpu/arm946es.cpp b/bsnes/nds/cpu/arm946es.cpp deleted file mode 100644 index e3b24577..00000000 --- a/bsnes/nds/cpu/arm946es.cpp +++ /dev/null @@ -1,697 +0,0 @@ - -ARM946ES::ARM946ES() { - itcm.data = new uint32_t[(itcm.size = 0x8000)/4]; - dtcm.data = new uint32_t[(dtcm.size = 0x4000)/4]; - bios.data = new uint32[(bios.size = 0x001000)/4](); - memset(bios.data, 0, bios.size); -} - -void ARM946ES::Thread() { arm9.main(); } - -void ARM946ES::power() { - // 2 * 33513982 MHz - if(thread) co_delete(thread); - thread = co_create(262144 * sizeof(void*), ARM946ES::Thread); - - vectorBase = 0xffff0000; - bxWithLoadedPC = true; - insnLatch = 0; - - memset(itcm.data, 0, itcm.size); - memset(dtcm.data, 0, dtcm.size); - - divMode = 0; rootMode = 0; - divByZero = 0; rootBusy = 0; - divBusy = 0; square = 0; - numerator = 0; squareRoot = 0; - denominator = 0; - quotient = 0; - remainder = 0; - - booted = 0; - flag300 = 0; - - slot1access = 1; - slot2access = 1; - ramPriority = 1; - - CPUCore::power(); - trace = false; - - control.mmu = false; - control.dcache = false; - control.icache = false; - - control.dtcm = false; - control.itcm = false; - control.dtcmLoad = false; - control.itcmLoad = false; - - control.endian = CR::little; - control.cachePolicy = CR::random; -} - -void ARM946ES::istep(unsigned clocks) { - arm7.clock -= clocks; - event.queue.step(clocks); -} - -void ARM946ES::step(unsigned clocks) { - return istep(clocks); -} - - - -void ARM946ES::main() { - itcmRegion = 0x00000000 | 14<<1; control.itcm = true; - dtcmRegion = 0x00800000 | 14<<1; control.dtcm = true; - updateTcm(); - - for(;;) { - if(arm7.clock < -256) - co_switch(arm7.thread); - - event.irq = interrupt.gate && (interrupt.enable & interrupt.flags); - //if(event.irq && !If) { - // print("arm9: irq (if=",hex<8>(interrupt.flags),")\n"); - //} - - if(Tf) execTHUMB(); - else execARM(); - } -} - - - -void ARM946ES::execARM() { - if(branched) { - //if(r[15] == 0) print(hex<8>(r[14]), ": jump to nullptr!\n"); - branched = false; r[15] &= ~3; - iexecute = fetch(r[15], Word, 0); r[15] += 4; - idecode = fetch(r[15], Word, 0); r[15] += 4; - } else { - iexecute = idecode, idecode = ifetch; - } - ifetch = fetch(r[15], Word, 1); - uint32 i = iexecute; - if(event.irq && !If) return irq(); - //if(trace) traceInsn(); - - if(i < 0xe0000000 && !evalCond(i>>28)) { r[15] += 4; return; } - - // opcode, sh, Rd, Rn, Rm, Rs - if(imatch("1111......../////")) { - if(imatch("111101x1u101/////")) { r[15] += 4; return; } // pld - reportedly NOP on DS? - if(imatch("1111101l..../////")) return armBranch (1, 1, i<<2 | (i>>23 & 2)); - return undefined(); - } - if(imatch("00x10xx0/////")) { - if(imatch("00110r10/// ..../")) return armWritePsr(i>>22, i>>16, armImmed(i, i>>8)); - if(imatch("00010r10/// 0000/")) return armWritePsr(i>>22, i>>16, armRm(i)); - if(imatch("00010r00/// 0000/")) return armReadPsr (i>>22, i>>12); - if(imatch("00010010/// 00l1/")) return armBranchEx( i>>5, i); - if(imatch("00010010/// 0111/")) return pfabort (); // bkpt - if(imatch("00010110/// 0001/")) return armClz ( i>>12, i); - if(imatch("00010ds0/// 0101/")) return armDspAdd (i>>21, i>>12, i>>16, i); - if(imatch("00010oo0/// 1yx0/")) return armDspMul (i>>21, i>>5, i>>16, i>>12, i, i>>8); - if(imatch("00010b00/// 1001/")) return armMemSwap (i>>22, i>>12, i>>16, i); - } - if(imatch("000...../// 1..1/")) { - if(imatch("0000luas/// 1001/")) return armMultiply(i>>20, i>>16, i>>12, i, i>>8); - if(imatch("000pu0w0/// 11s1/")) return armMem_v5 (i>>20, i>>5, i>>12, i>>16, armRm(i)); - if(imatch("000pu0wl/// 1sh1/")) return armMem_v4 (i>>20, i>>5, i>>12, i>>16, armRm(i)); - if(imatch("000pu1w0/// 11s1/")) return armMem_v5 (i>>20, i>>5, i>>12, i>>16, armOffset8(i, i>>8)); - if(imatch("000pu1wl/// 1sh1/")) return armMem_v4 (i>>20, i>>5, i>>12, i>>16, armOffset8(i, i>>8)); - } - if(imatch("001aaaas/// ..../")) return armData (i>>20, i>>12, i>>16, armImmed(i, i>>8)); - if(imatch("000aaaas/// .sh0/")) return armData (i>>20, i>>12, i>>16, shiftImm(i, i>>5, i>>7)); - if(imatch("010pubwl/// ..../")) return armMem (i>>20, i>>12, i>>16, armOffset12(i)); - if(imatch("011pubwl/// ...0/")) return armMem (i>>20, i>>12, i>>16, shiftImm(i, i>>5, i>>7)); - if(imatch("100puswl/// ..../")) return armBlock (i>>20, i>>16, i); - if(imatch("101l..../// ..../")) return armBranch (i>>24, 0, i<<2); - if(imatch("000aaaas/// 0sh1/")) return armDataRs (i>>20, i>>12, i>>16, i, i>>5, i>>8); - - if(imatch("1110..../// ..../")) return dataCop (i>>8, i>>20, i>>12, i>>16, i, i>>4); - if(imatch("1111..../// ..../")) return swi(); - return undefined(); -} - -void ARM946ES::execTHUMB() { - if(branched) { - //if(r[15] == 0) print(hex<8>(r[14]), ": jump to nullptr!\n"); - branched = false; r[15] &= ~1; - iexecute = fetch(r[15], Half, 0) >> 8*(r[15] & 2) & 0xffff; r[15] += 2; - idecode = fetch(r[15], Half, 1) >> 8*(r[15] & 2) & 0xffff; r[15] += 2; - } else { - iexecute = idecode, idecode = ifetch; - } - ifetch = fetch(r[15], Half, 1) >> 8*(r[15] & 2) & 0xffff; - uint16 i = iexecute; - - if(event.irq && !If) return irq(); - //if(trace) traceInsn(); - - if(imatch("00011ismmmnnnddd")) return thumbAddSub (i>>9, i, i>>3, i>>6); - if(imatch("000ssiiiiimmmddd")) return thumbShiftImm(i>>11, i, i>>3, i>>6); - if(imatch("001oodddiiiiiiii")) return thumbDataImm (i>>11, i>>8, i); - if(imatch("010000oooommmddd")) return thumbDataLo (i>>6, i, i>>3); - if(imatch("010001oodmmmmddd")) return thumbDataHi (i>>8, (i&7)+(i>>4&8), i>>3); - - if(imatch("0101ooommmnnnddd")) return thumbMemReg (i>>9, i, i>>3, i>>6); - if(imatch("011bliiiiinnnddd")) return thumbMemImm (i>>11, i, i>>3, i>>6); - if(imatch("1000liiiiinnnddd")) return thumbMemImm (i>>11, i, i>>3, i>>6); - - if(imatch("10111110........")) return pfabort(); // bkpt - if(imatch("10110000siiiiiii")) return thumbAddSP ( i>>7, i); - if(imatch("01001dddrrrrrrrr")) return thumbRelative(i>>11, i>>8, i); - if(imatch("1001odddrrrrrrrr")) return thumbRelative(i>>11, i>>8, i); - if(imatch("1010odddrrrrrrrr")) return thumbRelative(i>>11, i>>8, i); - - if(imatch("1101ccccrrrrrrrr")) return thumbCond ( i>>8, i); - if(imatch("11100rrrrrrrrrrr")) return thumbBranch (i); - if(imatch("11110rrrrrrrrrrr")) return thumbBh (i); - if(imatch("111t1rrrrrrrrrrr")) return thumbBlx (i>>12, i); - - if(imatch("1o..lnnnrrrrrrrr")) return thumbBlock (i>>11, i>>8, i); - - return undefined(); -} - - - -uint32 ARM946ES::fetch(uint32 addr, uint32 size, bool s) { - istep(1); // Assume cached for now - - if(itcmRCompare == (itcmRMask & addr)) { return itcm.read(addr % 0x8000, size); } - /* DTCM is not executable */ - - switch(addr >> 24) { - case 0x2: return system.ewram.read(addr % 0x400000, size); - case 0x3: return system.swram[addr>>14 & 1].read(addr % 0x4000, size); - case 0x6: return system.vmap.arm9[addr>>21 & 7][addr>>14 & 63].read(addr, size); - } - if(addr >= 0xffff0000) return bios.read(addr & bios.size-1, size); - return 0; -} - -uint32 ARM946ES::read(uint32 addr, uint32 size, bool s) { - if(itcmRCompare == (itcmRMask & addr)) { istep(1); return itcm.read(addr % 0x8000, size); } - if(dtcmRCompare == (dtcmRMask & addr)) { return dtcm.read(addr % 0x4000, size); } - - const int w = 6*!s + 2; // 32-bit bus timing - const int h = 6*!s + (size==Word? 4 : 2); // 16-bit bus timing - //const int e = 2*!s + h; // EWRAM timing - - //if((addr & 0xf3ff000) == 0x23ff000) { - // istep(e); - // uint32 data = system.ewram.read(addr % 0x400000, size); - // print(hex<8>(arm9.event.queue.time), " ",hex<8>(r[15])," arm9: r ",hex<8>(addr),":",size," = ",hex<8>(data),"\n"); - // return data; - //} - - switch(addr >> 24) { - case 0x2: istep(3); return system.ewram.read(addr % 0x400000, size); - case 0x3: istep(w); return system.swram[addr>>14 & 1].read(addr % 0x4000, size); - case 0x4: istep(w); { //return readReg(addr, size); { - uint32 data = readReg(addr, size); - //if(addr != 0x40001a0 && addr != 0x40001a4 && addr != 0x4100010) - // print(hex<8>(arm9.event.queue.time), " ",hex<8>(r[15])," arm9: r ",hex<8>(addr),":",size," = ",hex<8>(data),"\n"); - return data; - } - case 0x5: istep(h); return ppu[addr>>10 & 1].readPalette(addr % 0x400); - case 0x6: istep(h); return system.vmap.arm9[addr>>21 & 7][addr>>14 & 63].read(addr, size); - case 0x7: istep(w); return ppu[addr>>10 & 1].readOam(addr % 0x400); - } - istep(w); if(addr >= 0xffff0000) return bios.read(addr & bios.size-1, size); - return 0; -} - -void ARM946ES::write(uint32 addr, uint32 size, bool s, uint32 data) { - if(itcmWCompare == (itcmWMask & addr)) { istep(1); return itcm.write(addr % 0x8000, size, data); } - if(dtcmWCompare == (dtcmWMask & addr)) { return dtcm.write(addr % 0x4000, size, data); } - - //if((addr & 0xf3ff000) == 0x23ff000) - // print(hex<8>(arm9.event.queue.time), " ",hex<8>(r[15]), " arm9: w ",hex<8>(addr),":",size," = ",hex<8>(data),"\n"); - - const int w = 6*!s + 2; // 32-bit bus timing - const int h = 6*!s + (size==Word? 4 : 2); // 16-bit bus timing - //const int e = 2*!s + h; // EWRAM timing - - switch(addr >> 24) { - case 0x2: istep(3); return system.ewram.write(addr % 0x400000, size, data); - case 0x3: istep(w); return system.swram[addr>>16 & 1].write(addr % 0x4000, size, data); - case 0x4: istep(w); { //return writeReg(addr, size, data); - //if(addr != 0x04000400) - // print(hex<8>(arm9.event.queue.time), " ", hex<8>(r[15])," arm9: w ",hex<8>(addr),":",size," = ",hex<8>(data),"\n"); - writeReg(addr, size, data); - return; - } - case 0x5: istep(h); return ppu[addr>>10 & 1].writePalette(addr % 0x400, size, data); - case 0x6: istep(h); return system.vmap.arm9[addr>>21 & 7][addr>>14 & 63].write(addr, size, data); - case 0x7: istep(w); return ppu[addr>>10 & 1].writeOam(addr % 0x400, size, data); - } - istep(w); -} - -void ARM946ES::dataCop(uint4 cpno, uint4 op1, uint4 ird, uint4 irn, uint4 irm, uint4 op2) { - if(cpno == 15) { - auto &rd = r[ird]; - uint32 rm = r[irm]; - r[15] += 4; - - if(op2 & 1) { // MRC, MCR - switch(op1<<12 | irn<<8 | irm<<4 | op2>>1) { - - case 0x1000: // c0,c0,0 Processor ID - rd = 'A'<<24; // Implementor ARM - rd |= 0<<20; // Variant 0 - rd |= 5<<16; // Architecture v5 - rd |= 0x946<< 4; // Model 946 - rd |= 1<< 0; // Revision 1 - return; - - case 0x1001: // c0,c0,1 Cache information - rd = 0x0f<<24; // type B Harvard - rd |= 0x0d2<<12; // 4K data, 4-way, 32-byte lines - rd |= 0x112<< 0; // 8K insn, 4-way, 32-byte lines - return; - - case 0x1002: // c0,c0,2 TCM information - rd = 5<<18; // 16K dtcm - rd |= 6<< 6; // 32K itcm - return; - - case 0x1100: // c1,c0,0 Control register - rd = control.mmu<<0 | control.dcache<<2 | 1<<3 /*write buffer*/ - | 1<<4 | 1<<5 | 1<<6 /*32 bit only, late abort model*/ - | control.endian<<7 | control.icache<<12 | !!vectorBase<<13 - | control.cachePolicy<<14 | !bxWithLoadedPC<<15 - | control.dtcm<<16 | control.dtcmLoad<<17 - | control.itcm<<18 | control.itcmLoad<<19; - return; - - case 0x0100: - control.mmu = rd >> 0; - control.dcache = rd >> 1; - control.endian = rd >> 7; - control.icache = rd >> 12; - vectorBase = rd & 1<<13? 0xffff0000 : 0; - control.cachePolicy = rd >> 14; - bxWithLoadedPC = rd & 1<<15? false : true; - control.dtcm = rd >> 16; - control.dtcmLoad = rd >> 17; - control.itcm = rd >> 18; - control.itcmLoad = rd >> 19; - - updateTcm(); - return; - - case 0x0900: case 0x1900: // c9,c0,0 Lock dcache - case 0x0901: case 0x1901: // c9,c0,1 Lock icache - return; - - case 0x0910: // c9,c1,0 DTCM mapping - dtcmRegion = rd; - updateTcm(); - return; - case 0x1910: - rd = dtcmRegion; - return; - - case 0x0911: // c9,c1,1 ITCM mapping - itcmRegion = rd; - updateTcm(); - return; - case 0x1911: - rd = itcmRegion; - return; - - case 0x0200: case 0x1200: // c2,c0,0 Region data cache bits - case 0x0201: case 0x1201: // c2,c0,1 Region insn cache bits - case 0x0300: case 0x1300: // c3,c0,0 Region data buffer bits - case 0x0500: case 0x1500: // c5,c0,0 Region data permissions - case 0x0501: case 0x1501: // c5,c0,1 Region insn permissions - case 0x0502: case 0x1502: // c5,c0,2 Region data permissions - extended - case 0x0503: case 0x1503: // c5,c0,3 Region insn permissions - extended - return; - - case 0x0600: case 0x1600: case 0x0601: case 0x1601: // c6,cN,0 Region mappings - case 0x0610: case 0x1610: case 0x0611: case 0x1611: - case 0x0620: case 0x1620: case 0x0621: case 0x1621: - case 0x0630: case 0x1630: case 0x0631: case 0x1631: - case 0x0640: case 0x1640: case 0x0641: case 0x1641: - case 0x0650: case 0x1650: case 0x0651: case 0x1651: - case 0x0660: case 0x1660: case 0x0661: case 0x1661: - case 0x0670: case 0x1670: case 0x0671: case 0x1671: - return; - - case 0x0704: // c7,c0,4 Wait for Interrupt - case 0x0782: // c7,c8,2 (alternate version) - //print("arm9: wait (ime=",interrupt.gate,", ie=",hex<8>(interrupt.enable),")\n"); - powerState = waiting; - for(;;) { - // Because this one is integrated with the ARM9, - // it's "behind" the IRQ line and knows nothing about IME/IE/IF. - if(interrupt.gate && (interrupt.enable & interrupt.flags)) { - powerState = running; - break; - } - istep(256); - if(arm7.clock < -256) - co_switch(arm7.thread); - } - return; - - case 0x0750: // c7, c5,0 Invalidate icache entirely - case 0x0751: // c7, c5,1 Invalidate icache by address - case 0x0752: // c7, c5,2 Invalidate icache by line (?) - case 0x07d1: // c7,c13,1 Preload icache by address - return; - - case 0x0760: // c7, c6,0 Invalidate dcache entirely - case 0x0761: // c7, c6,1 Invalidate dcache by address - case 0x0762: // c7, c6,2 Invalidate dcache by line (? zelda gallery uses this) - - //case 0x07a0://c7,c10,0 Clean dcache entirely (?) - case 0x07a1: // c7,c10,1 Clean dcache by address - case 0x07a2: // c7,c10,2 Clean dcache by line - case 0x07a4: // c7,c10,4 Drain write buffer - - //case 0x07e0://c7,c14,0 Flush dcache entirely (?) - case 0x07e1: // c7,c14,1 Flush dcache by address - case 0x07e2: // c7,c14,2 Flush dcache by line - return; - - case 0x0f00: case 0x1f00: // 0,c15,c0,0 Cache control - case 0x6f00: case 0x7f00: // 3,c15,c0,0 Cache tag/data index - case 0x6f01: case 0x7f01: // 3,c15,c0,1 R/W icache tag - case 0x6f02: case 0x7f02: // 3,c15,c0,2 R/W dcache tag - case 0x6f03: case 0x7f03: // 3,c15,c0,3 R/W icache data - case 0x6f04: case 0x7f04: // 3,c15,c0,4 R/W dcache data - return; - - } - } - } - bool iscdp = op2&1, isld = op1&1; - print("arm9: ",hex<8>(r[15])," undefined ", iscdp? "cdp" : isld? "mrc" : "mcr", " p",cpno,", ", - iscdp? (unsigned)op1 : op1>>1, ", ", iscdp? "cr":"r", ird, ", cr", irn, ", cr", irm, ", ", op2>>1, "\n"); - return undefined(); -} - - - -uint32 ARM946ES::readReg(uint32 addr, uint32 size) { - switch(addr-0x4000000 & ~3) { - - // These registers shouldn't be here - but they contain bits from logically - // separate hardware units, so it's not clear where else to put them. - - case 0x0000: // Display 0 / PPU0 BG, OBJ control - return (video.frameBuffer<<18 & 0xc0000) - | video.source[0]<<16 | ppu[0].regControl(); - - case 0x1000: // Display 1 / PPU1 BG, OBJ control - return video.source[1]<<16 | ppu[1].regControl(); - - case 0x0008: case 0x1008: // BG0,BG1 - case 0x000c: case 0x100c: // BG2,BG3 - return ppu[addr>>12 & 1].regBg((addr>>1 & 2) + 0)<<0 - | ppu[addr>>12 & 1].regBg((addr>>1 & 2) + 1)<<16; - - case 0x0010: case 0x1010: // BG0H,V - case 0x0014: case 0x1014: // BG1H,V - case 0x0018: case 0x1018: // BG2H,V - case 0x001c: case 0x101c: // BG3H,V - return ppu[addr>>12 & 1].regBgOffs(addr>>2 & 3); - - case 0x0048: case 0x1048: // Window area 0,1,out,obj - return ppu[addr>>12 & 1].regWinArea(); - - case 0x0050: case 0x1050: // Blend control - return ppu[addr>>12 & 1].regBlend(); - - // Miscellaneous graphics registers - case 0x0060: return gpu.regRenderOptions(); - case 0x0064: return video.regCapture(); - case 0x006c: return video.regBrightness(0); - - case 0x1060: return 0; - case 0x1064: return 0; - case 0x1068: return 0; - case 0x106c: return video.regBrightness(1); - - // Memory control - case 0x0204: return ramPriority<<15 | slot1access<<11 - | slot2access<<7 | regSlot2Control(); - - case 0x0240: return system.regVmap(0); - case 0x0244: return system.regVmap(1); - case 0x0248: return system.regVmap(2); - - // Math - case 0x0280: return regDivideControl(); - case 0x0290: return regNumerator(0); - case 0x0294: return regNumerator(1); - case 0x0298: return regDenominator(0); - case 0x029c: return regDenominator(1); - case 0x02a0: return regQuotient(0); - case 0x02a4: return regQuotient(1); - case 0x02a8: return regRemainder(0); - case 0x02ac: return regRemainder(1); - - case 0x02b0: return regSquareRootControl(); - case 0x02b4: return regSquareRoot(); - case 0x02b8: return regSquare(0); - case 0x02bc: return regSquare(1); - - case 0x0300: return booted<<0 | flag300<<1; - - // Power - case 0x0304: - return video.screensPowered<< 0 | ppu[0].powered<<1 - | video.ppu0Screen <<15 | ppu[1].powered<<9; - - // Render status - case 0x0320: return gpu.regRenderLoad(); - - // This shouldn't exist, but various games read it nonetheless.. - case 0x04a4: return 0; - - // Geometry status - case 0x0600: return gpu.regGeomStatus(); - case 0x0604: return gpu.regGeomLoad(); - - case 0x0620: case 0x0624: case 0x0628: case 0x062c: - return gpu.regGeomPosition((addr - 0x4000620)/4); - - case 0x0630: case 0x0634: - return gpu.regGeomNormal((addr - 0x4000630)/4); - - case 0x0640: case 0x0644: case 0x0648: case 0x064c: - case 0x0650: case 0x0654: case 0x0658: case 0x065c: - case 0x0660: case 0x0664: case 0x0668: case 0x066c: - case 0x0670: case 0x0674: case 0x0678: case 0x067c: - return gpu.regClipMatrix((addr - 0x4000640)/4); - - case 0x0680: case 0x0684: case 0x0688: - case 0x068c: case 0x0690: case 0x0694: - case 0x0698: case 0x069c: case 0x06a0: - return gpu.regLightMatrix((addr - 0x4000680)/4); - - } - return CPUCore::readReg(addr, size); -} - -void ARM946ES::writeReg(uint32 addr, uint32 size, uint32 data) { - uint32 mask = 0xffffffff; - if(size == Half) mask = 0xffff << 8*(addr & 2); - if(size == Byte) mask = 0xff << 8*(addr & 3); - - data &= mask; - - switch(addr-0x4000000 & ~3) { - - case 0x0000: // Display 0 / PPU0 control - if(mask & 0x000f0000) { - // These bits go to the display controller - not PPU0. - video.frameBuffer &= ~0xc; - video.frameBuffer |= 0xc & data>>16; - video.source[0] = 0x3 & data>>16; - } - ppu[0].regControl(data, mask); - return; - - case 0x1000: // Display 1 / PPU1 control - if(mask & 0x000f0000) { - // Framebuffer/FIFO sources aren't supported here. - video.source[1] = 0x1 & data>>16; - } - ppu[1].regControl(data, mask); - return; - - case 0x0008: case 0x1008: // BGn control - case 0x000c: case 0x100c: // - if(mask & 0x0000ffff) ppu[addr>>12 & 1].regBg((addr>>1 & 2) + 0, data>>0, mask>>0); - if(mask & 0xffff0000) ppu[addr>>12 & 1].regBg((addr>>1 & 2) + 1, data>>16, mask>>16); - return; - - case 0x0010: case 0x1010: // BGn H,V scroll - case 0x0014: case 0x1014: // - case 0x0018: case 0x1018: // - case 0x001c: case 0x101c: return ppu[addr>>12 & 1].regBgOffs(addr>>2 & 3, data, mask); - - case 0x0020: case 0x1020: // BG2 affine A, B, C, D - case 0x0024: case 0x1024: // - case 0x0028: case 0x1028: // BG2 origin X, Y - case 0x002c: case 0x102c: return ppu[addr>>12 & 1].regBgAffine(2, addr>>2 & 3, data, mask); - - case 0x0030: case 0x1030: // BG3 affine A, B, C, D - case 0x0034: case 0x1034: // - case 0x0038: case 0x1038: // BG3 origin X, Y - case 0x003c: case 0x103c: return ppu[addr>>12 & 1].regBgAffine(3, addr>>2 & 3, data, mask); - - case 0x0040: case 0x1040: return ppu[addr>>12 & 1].regWinDims(0, data, mask); // Window 0,1 X range - case 0x0044: case 0x1044: return ppu[addr>>12 & 1].regWinDims(1, data, mask); // 0,1 Y range - case 0x0048: case 0x1048: return ppu[addr>>12 & 1].regWinArea(data, mask); // area 0,1,out,obj - case 0x004c: case 0x104c: return; // Mosaic BG,OBJ X,Y - - case 0x0050: case 0x1050: // Blend control - case 0x0054: case 0x1054: return ppu[addr>>12 & 1].regBlend(addr>>2 & 1, data, mask); - - case 0x0058: case 0x1058: return; // not present, but frequently zeroed anyway - case 0x005c: case 0x105c: return; // - - // Some miscellaneous registers, none of which belong here... hunh. - case 0x0060: return gpu.regRenderOptions(data, mask); - case 0x0064: return video.regCapture(data, mask); - case 0x0068: return video.regFifo(data); - case 0x006c: return video.regBrightness(0, data, mask); - - case 0x1060: return; - case 0x1064: return; - case 0x1068: return; - case 0x106c: return video.regBrightness(1, data, mask); - - // Memory control - case 0x0204: - if(mask & 0x00ff) { - slot2access = !(data & 1<<7); - } - if(mask & 0xff00) { - slot1access = !(data & 1<<11); - ramPriority = !(data & 1<<15); - } - return regSlot2Control(data, mask); - - case 0x0240: return system.regVmap(0, data, mask); - case 0x0244: return system.regVmap(1, data, mask); - case 0x0248: return system.regVmap(2, data, mask); - - // Math - case 0x0280: return regDivideControl(data, mask); - case 0x0290: return regNumerator(0, data, mask); - case 0x0294: return regNumerator(1, data, mask); - case 0x0298: return regDenominator(0, data, mask); - case 0x029c: return regDenominator(1, data, mask); - - case 0x02b0: return regSquareRootControl(data, mask); - case 0x02b8: return regSquare(0, data, mask); - case 0x02bc: return regSquare(1, data, mask); - - case 0x0300: - if(mask & 0xff) { - booted |= data>>0; - flag300 = data>>1; - } - return; - - case 0x0304: // Power control - if(mask & 0x00ff) { - video.screensPowered = data>>0; - ppu[0].powered = data>>1; - //gpu.renderPowered = data>>2; - //gpu.geomPowered = data>>3; - } - if(mask & 0xff00) { - ppu[1].powered = data>>9; - video.ppu0Screen = data>>15; - } - return; - - // Toon edge table - case 0x0330: case 0x0334: case 0x0338: case 0x033c: - return gpu.regRenderEdgeTable((addr - 0x4000330)/4, data, mask); - - // Misc - case 0x0340: return gpu.regRenderMinAlpha(data, mask); - case 0x0350: return gpu.regRenderClearColor(data, mask); - case 0x0354: return gpu.regRenderClearCoord(data, mask); - case 0x0358: return gpu.regRenderFogColor(data, mask); - case 0x035c: return gpu.regRenderFogCoord(data, mask); - - // Fog table - case 0x0360: case 0x0364: case 0x0368: case 0x036c: - case 0x0370: case 0x0374: case 0x0378: case 0x037c: - return gpu.regRenderFogTable((addr - 0x4000360)/4, data, mask); - - // Toon shade table - case 0x0380: case 0x0384: case 0x0388: case 0x038c: - case 0x0390: case 0x0394: case 0x0398: case 0x039c: - case 0x03a0: case 0x03a4: case 0x03a8: case 0x03ac: - case 0x03b0: case 0x03b4: case 0x03b8: case 0x03bc: - return gpu.regRenderToonTable((addr - 0x4000380)/4, data, mask); - - // GPU command pipe - buffered - mirrored to support STM - case 0x0400: case 0x0404: case 0x0408: case 0x040c: case 0x0410: case 0x0414: case 0x0418: case 0x041c: - case 0x0420: case 0x0424: case 0x0428: case 0x042c: case 0x0430: case 0x0434: case 0x0438: case 0x043c: - return gpu.sendGeomBuffered(data); - - // GPU command pipe - immediate - the address itself is used as command number. - case 0x0440: case 0x0444: case 0x0448: case 0x044c: case 0x0450: case 0x0454: case 0x0458: case 0x045c: - case 0x0460: case 0x0464: case 0x0468: case 0x046c: case 0x0470: case 0x0474: case 0x0478: case 0x047c: - case 0x0480: case 0x0484: case 0x0488: case 0x048c: case 0x0490: case 0x0494: case 0x0498: case 0x049c: - case 0x04a0: case 0x04a4: case 0x04a8: case 0x04ac: case 0x04b0: case 0x04b4: case 0x04b8: case 0x04bc: - case 0x04c0: case 0x04c4: case 0x04c8: case 0x04cc: case 0x04d0: case 0x04d4: case 0x04d8: case 0x04dc: - case 0x04e0: case 0x04e4: case 0x04e8: case 0x04ec: case 0x04f0: case 0x04f4: case 0x04f8: case 0x04fc: - case 0x0500: case 0x0504: case 0x0508: case 0x050c: case 0x0510: case 0x0514: case 0x0518: case 0x051c: - case 0x0520: case 0x0524: case 0x0528: case 0x052c: case 0x0530: case 0x0534: case 0x0538: case 0x053c: - case 0x0540: case 0x0544: case 0x0548: case 0x054c: case 0x0550: case 0x0554: case 0x0558: case 0x055c: - case 0x0560: case 0x0564: case 0x0568: case 0x056c: case 0x0570: case 0x0574: case 0x0578: case 0x057c: - case 0x0580: case 0x0584: case 0x0588: case 0x058c: case 0x0590: case 0x0594: case 0x0598: case 0x059c: - case 0x05a0: case 0x05a4: case 0x05a8: case 0x05ac: case 0x05b0: case 0x05b4: case 0x05b8: case 0x05bc: - case 0x05c0: case 0x05c4: case 0x05c8: case 0x05cc: case 0x05d0: case 0x05d4: case 0x05d8: case 0x05dc: - case 0x05e0: case 0x05e4: case 0x05e8: case 0x05ec: case 0x05f0: case 0x05f4: case 0x05f8: case 0x05fc: - return gpu.sendGeomImmediate(addr>>2 & 0x7f, data); - - // Geometry engine - case 0x0600: return gpu.regGeomStatus(data, mask); - case 0x0610: return gpu.regGeomMaxPointDepth(data, mask); - - // zelda gallery writes 0x2468ace0 here - ??? - case 0x0640: break; - } - return CPUCore::writeReg(addr, size, data); -} - - -void ARM946ES::updateTcm() { - uint32 itcmAddr = 0, itcmSize = itcmRegion>>1 & 0x1f; - uint32 dtcmAddr = dtcmRegion & ~0xfff, dtcmSize = dtcmRegion>>1 & 0x1f; - - // Disable by default - itcmRCompare = itcmWCompare = ~0; - dtcmRCompare = dtcmWCompare = ~0; - itcmRMask = itcmWMask = 0; - dtcmRMask = dtcmWMask = 0; - - // Enable bit enables access; load bit disables reading - if(control.itcm) itcmWCompare = itcmAddr, itcmWMask = -1 << 9+itcmSize; - if(control.dtcm) dtcmWCompare = dtcmAddr, dtcmWMask = -1 << 9+dtcmSize; - if(control.itcm && !control.itcmLoad) itcmRCompare = itcmAddr, itcmRMask = -1 << 9+itcmSize; - if(control.dtcm && !control.dtcmLoad) dtcmRCompare = dtcmAddr, dtcmRMask = -1 << 9+dtcmSize; -} - - - -#include "math.cpp" diff --git a/bsnes/nds/cpu/bit.hpp b/bsnes/nds/cpu/bit.hpp deleted file mode 100644 index e03e03c4..00000000 --- a/bsnes/nds/cpu/bit.hpp +++ /dev/null @@ -1,66 +0,0 @@ - -namespace Bit { - - template - constexpr int count(T n) { - return n == 0 || w == 0? n - : count(n>>w & (1<(n & (1< constexpr long lowest_bit_no(long x) { - return !x? -1 : !s? 0 : - x & (1<(x) - : s + lowest_bit_no(x >> s); -} - -constexpr long binary(const char *s) { - return !*s? 0 : (*s=='1') << bitpos(s) | binary(s+1); -} -constexpr long mask(const char *s) { - return !*s? 0 : (*s=='0'||*s=='1') << bitpos(s) | mask(s+1); -} -constexpr long field(const char *s) { - return !*s? 0 : (*s!=' '&& isfield(*s)) << bitpos(s) | field(s+1); -} -constexpr bool match(long data, const char *s) { - return (data & mask(s)) == binary(s); -} - -// Masks all 'bits' from the input and shifts them down into one contiguous -// value. This inlines to a sequence of &, >> and + instructions. -// Example: -// collect(i) -// joins i's 1st, 3rd, and 5th nibbles (0x12345 => 0x135). -template constexpr long collect(long data); -template constexpr long collect_field(long data) { - return (data & (1<> nmask)>(data >> nmask) << nmask*(bits&1)); -} - -template constexpr long collect(long data) { - return collect_field(data); -} -template<> constexpr long collect<0>(long data) { - return 0; -} - -}; diff --git a/bsnes/nds/cpu/core.cpp b/bsnes/nds/cpu/core.cpp deleted file mode 100644 index 1bfcf4f3..00000000 --- a/bsnes/nds/cpu/core.cpp +++ /dev/null @@ -1,214 +0,0 @@ - -void ARMCore::power() { - for(int n = 0; n < 16; n++) r[n] = 0; - for(int n = 0; n < 7; n++) r_fiq[n] = 0; - for(int n = 0; n < 2; n++) r_irq[n] = r_svc[n] = r_abt[n] = r_und[n] = 0; - - spsr_none = spsr_fiq = spsr_irq = spsr_svc = spsr_abt = spsr_und = 0; - carryout = 0; - Nf = Cf = Vf = Qf = 0; - Zf = -1; - - reset(); -} - - - -uint32& ARMCore::spsr() { - return mode == FIQ? spsr_fiq : mode == IRQ? spsr_irq - : mode == SVC? spsr_svc : mode == UND? spsr_und - : mode == ABT? spsr_abt : spsr_none; -} - -uint32 ARMCore::readCpsr() { - uint32 n = Nf & 1<<31, c = Cf & 1<<31; - uint32 v = Vf & 1<<31, q = Qf & 1<<31; - uint32 z = !Zf <<31; - - return n>>0 | z>>1 | c>>2 | v>>3 | q>>4 | If<<7 | Ff<<6 | Tf<<5 | mode<<0; -} - -void ARMCore::writeCpsr(uint32 value, unsigned mask) { - if(mask & 8) { - Nf = value<<0 & 1<<31; Zf = !(value<<1 & 1<<31); - Cf = value<<2 & 1<<31; Vf = value<<3 & 1<<31; - Qf = value<<4 & 1<<31; - } - if(mode == USR) - return; // cpsr_c is privileged - - if(mask & 1) { - swapBank(mode); - If = value>>7 & 1; Ff = value>>6 & 1; - Tf = value>>5 & 1; mode = value & 0x1f; - - mode |= 0x10; // enforce 32-bit addressing - if(mode & 0x0c) - mode |= 0x03; // enforce valid mode bits - swapBank(mode); - } -} - -void ARMCore::vector(uint32 offset, unsigned tomode) { - uint32 psr = readCpsr(); - - swapBank(mode); - swapBank(mode = tomode); - - // vector() is called between the instruction fetch and PC increment.. - // therefore in ARM mode, r15 == PC+8. THUMB requires an adjustment - // (done in the caller). - r[14] = r[15] - 4; - r[15] = vectorBase + offset; - If = 1; - Tf = 0; - spsr() = psr; - branched = true; -} - -void ARMCore::swapBank(unsigned mode) { - uint32 *bank = nullptr, *user = &r[15]; - unsigned count = 0; - - if(mode == FIQ) bank = &r_fiq[count = 7]; - if(mode == IRQ) bank = &r_irq[count = 2]; - if(mode == SVC) bank = &r_svc[count = 2]; - if(mode == ABT) bank = &r_abt[count = 2]; - if(mode == UND) bank = &r_und[count = 2]; - - while(count--) std::swap(*--bank, *--user); -} - - - -bool ARMCore::evalCond(unsigned cond) { - if(cond == 14) return true; - if(cond == 0) return (Zf == 0); // eq - if(cond == 1) return !(Zf == 0); // ne - if(cond == 2) return (Cf < 0); // hs / cs - if(cond == 3) return !(Cf < 0); // lo / cc - if(cond == 8) return (Cf < 0 && Zf); // hi - if(cond == 9) return !(Cf < 0 && Zf); // ls - if(cond == 10) return ((Nf^Vf) >= 0); // ge - if(cond == 11) return !((Nf^Vf) >= 0); // lt - if(cond == 12) return ((Nf^Vf) >= 0 && Zf); // gt - if(cond == 13) return !((Nf^Vf) >= 0 && Zf); // le - if(cond == 4) return (Nf < 0); // mi - if(cond == 5) return !(Nf < 0); // pl - if(cond == 6) return (Vf < 0); // vs - if(cond == 7) return !(Vf < 0); // vc - return false; -} - -void ARMCore::branch(bool tf, uint32 target) { - r[15] = target; - Tf = tf; - branched = true; -} - - - -uint32 ARMCore::load(uint32 addr, uint32 size) { - uint32 data = read(addr, size, false); - data = ror(data, 8*(addr & 3)); - step(1); - - if(size == Half) data &= 0xffff; - if(size == Byte) data &= 0xff; - return data; -} - -void ARMCore::store(uint32 addr, uint32 size, uint32 data) { - if(size == Half) data &= 0xffff, data *= 0x00010001; - if(size == Byte) data &= 0xff, data *= 0x01010101; - - write(addr, size, false, data); -} - - - -ARMCore::SOut ARMCore::lsl(uint32 rm, uint8 rs) { - if(rs == 0) return {rm, Cf}; - else return {rs>31? 0 : rm << rs, - rs>32? 0 : rm << rs-1}; -} -ARMCore::SOut ARMCore::lsr(uint32 rm, uint8 rs) { - if(rs == 0) return {rm, Cf}; - else return {rs>31? 0 : rm >> rs, - rs>32? 0 : rm << 32-rs}; -} -ARMCore::SOut ARMCore::asr(uint32 rm, uint8 rs) { - if(rs == 0) return {rm, Cf}; - else return {rs>31? (int32)rm>>31 : (int32)rm >> rs, - rs>32? rm : rm << 32-rs}; -} -ARMCore::SOut ARMCore::ror(uint32 rm, uint8 rs) { - if(rs == 0) return {rm, Cf}; - if(!(rs &= 31)) return {rm, rm}; // rs == multiple of 32 - else return {rm << 32-rs | rm >> rs, rm << 32-rs}; -} -ARMCore::SOut ARMCore::rrx(uint32 rm) { - return {(Cf & 1<<31) | rm >> 1, rm << 31}; -} - -ARMCore::SOut ARMCore::shiftImm(uint4 irm, uint2 opcode, uint5 rs) { - if(opcode == 0) return lsl(r[irm], rs); - if(opcode == 1) return lsr(r[irm], rs? (uint8)rs : 32); - if(opcode == 2) return asr(r[irm], rs? (uint8)rs : 32); - if(rs != 0) return ror(r[irm], rs); - if(rs == 0) return rrx(r[irm]); -} - -void ARMCore::alu(unsigned opcode, uint32& rd, uint32 rn, SOut rm) { - if(opcode == 13*2+0) return bitf(0, rd = rm, rm); // mov - if(opcode == 2*2+0) return sumf(0, rd = rn - rm, rn,~rm); // sub - if(opcode == 4*2+0) return sumf(0, rd = rn + rm, rn, rm); // add - if(opcode == 0*2+0) return bitf(0, rd = rn & rm, rm); // and - if(opcode == 12*2+0) return bitf(0, rd = rn | rm, rm); // orr - if(opcode == 14*2+0) return bitf(0, rd = rn &~rm, rm); // bic - if(opcode == 1*2+0) return bitf(0, rd = rn ^ rm, rm); // eor - - if(opcode == 13*2+1) return bitf(1, rd = rm, rm); // movs - if(opcode == 10*2+1) return sumf(1, rn - rm, rn,~rm); // cmps - if(opcode == 11*2+1) return sumf(1, rn + rm, rn, rm); // adds - - if(opcode == 2*2+1) return sumf(1, rd = rn - rm, rn,~rm); // subs - if(opcode == 4*2+1) return sumf(1, rd = rn + rm, rn, rm); // adds - if(opcode == 0*2+1) return bitf(1, rd = rn & rm, rm); // ands - if(opcode == 12*2+1) return bitf(1, rd = rn | rm, rm); // orrs - if(opcode == 14*2+1) return bitf(1, rd = rn &~rm, rm); // bics - if(opcode == 1*2+1) return bitf(1, rd = rn ^ rm, rm); // eors - if(opcode == 8*2+1) return bitf(1, rn & rm, rm); // tsts - if(opcode == 9*2+1) return bitf(1, rn ^ rm, rm); // teqs - - if(opcode == 3*2+0) return sumf(0, rd = rm - rn, ~rn, rm); // rsb - if(opcode == 5*2+0) return sumf(0, rd = rn + rm +!!(Cf>>31), rn, rm); // adc - if(opcode == 6*2+0) return sumf(0, rd = rn - rm - !(Cf>>31), rn,~rm); // sbc - if(opcode == 7*2+0) return sumf(0, rd = rm - rn - !(Cf>>31),~rn, rm); // rsc - if(opcode == 15*2+0) return bitf(0, rd = ~rm, rm); // mvn - - if(opcode == 3*2+1) return sumf(1, rd = rm - rn, ~rn, rm); // rsbs - if(opcode == 5*2+1) return sumf(1, rd = rn + rm +!!(Cf>>31), rn, rm); // adcs - if(opcode == 6*2+1) return sumf(1, rd = rn - rm - !(Cf>>31), rn,~rm); // sbcs - if(opcode == 7*2+1) return sumf(1, rd = rm - rn - !(Cf>>31),~rn, rm); // rscs - if(opcode == 15*2+1) return bitf(1, rd = ~rm, rm); // mvns -} - - - -uint32 ARMCore::oflow(uint32 rd, uint32 rn, uint32 rm) { - return ~(rn^rm) & (rn^rd); -} - -void ARMCore::bitf(bool s, uint32 rd, SOut rm) { - if(s) Cf = rm.carry, Nf = Zf = rd; -} - -void ARMCore::sumf(bool s, uint32 rd, uint32 rn, uint32 rm) { - if(s) Vf = oflow(rd,rn,rm), Cf = Vf ^ rd^rn^rm, Nf = Zf = rd; -} - - - -#include "arm.cpp" -#include "thumb.cpp" diff --git a/bsnes/nds/cpu/core.hpp b/bsnes/nds/cpu/core.hpp deleted file mode 100644 index 3838067d..00000000 --- a/bsnes/nds/cpu/core.hpp +++ /dev/null @@ -1,135 +0,0 @@ - -struct ARMCore { - // Model specific implementation - virtual void power(); - virtual void step(unsigned n) = 0; - - // Instruction and data access - virtual uint32 fetch(uint32 addr, uint32 size, bool s) = 0; - virtual uint32 read(uint32 addr, uint32 size, bool s) = 0; - virtual void write(uint32 addr, uint32 size, bool s, uint32 data) = 0; - - // CDP, MCR, MRC - virtual void dataCop(uint4 cpno, uint4 op1, uint4 ird, uint4 irn, uint4 irm, uint4 op2) = 0; - - // Vectors - void reset() { vector(0x000, SVC); Ff = 1; } // THUMB: - void fiq() { vector(0x01c, FIQ); Ff = 1; if(spsr() & 1<<5) r[14] += 4; } // LR = insn+4 - void irq() { vector(0x018, IRQ); if(spsr() & 1<<5) r[14] += 4; } - void swi() { vector(0x008, SVC); if(spsr() & 1<<5) r[14] += 2; } // LR = insn+2 - void undefined() { vector(0x004, UND); if(spsr() & 1<<5) r[14] += 2; } - void pfabort() { vector(0x00c, ABT); if(spsr() & 1<<5) r[14] += 2; } - void abort() { vector(0x010, ABT); if(spsr() & 1<<5) r[14] += 8; } // LR = insn+8 - - // PSRs and mode switching - uint32& spsr(); - uint32 readCpsr(); - void writeCpsr(uint32 value, uint32 mask); - void vector(uint32 offset, unsigned tomode); - void swapBank(unsigned mode); - - alwaysinline bool evalCond(unsigned cond); - - void branch(bool tf, uint32 target); - - // LDR rotation, STR mirroring - uint32 load(uint32 addr, uint32 size); - void store(uint32 addr, uint32 size, uint32 data); - - // Shifts, arithmetic - struct SOut { - // Shifter output - uint32 rm; - int32 carry; - - SOut(uint32 rm) : rm(rm) {} - SOut(uint32 rm, int32 carry) : rm(rm), carry(carry) {} - operator uint32() { return rm; } - }; - alwaysinline SOut lsl(uint32 rm, uint8 rs); - alwaysinline SOut lsr(uint32 rm, uint8 rs); - alwaysinline SOut asr(uint32 rm, uint8 rs); - alwaysinline SOut ror(uint32 rm, uint8 rs); - alwaysinline SOut rrx(uint32 rm); - - alwaysinline SOut shiftImm(uint4 irm, uint2 opcode, uint5 rs); - alwaysinline void alu(unsigned opcode, uint32& rd, uint32 rn, SOut rm); - - // Flags - alwaysinline uint32 oflow(uint32 rd, uint32 rn, uint32 rm); - alwaysinline void bitf(bool s, uint32 rd, SOut rm); - alwaysinline void sumf(bool s, uint32 rd, uint32 rn, uint32 rm); - - // ARM argument Rm - alwaysinline uint32 armRm(uint4 irm) { return r[irm]; } - alwaysinline SOut armImmed(uint8 value, uint4 rs) { return ror(value, 2*rs); } - alwaysinline uint32 armOffset8(uint4 lo, uint4 hi) { return lo | hi<<4; } - alwaysinline uint32 armOffset12(uint12 value) { return value; } - - // ARM handlers - void armWritePsr(uint1 opcode, uint4 mask, uint32 rm); - void armReadPsr(uint1 opcode, uint4 ird); - void armBranch(uint1 link, uint1 exch, int26 offset); - void armBranchEx(uint1 link, uint4 irm); - void armClz(uint4 ird, uint4 irm); - void armDspAdd(uint2 opcode, uint4 ird, uint4 irn, uint4 irm); - void armDspMul(uint2 opcode, uint2 xy, uint4 ird, uint4 irn, uint4 irm, uint4 irs); - void armMultiply(uint4 opcode, uint4 ird, uint4 irn, uint4 irm, uint4 irs); - void armDataRs(uint5 opcode, uint4 ird, uint4 irn, uint4 irm, uint2 sh, uint4 irs); - void armData(uint5 opcode, uint4 ird, uint4 irn, SOut rm); - void armMemSwap(uint1 opcode, uint4 ird, uint4 irn, uint4 irm); - void armMem(uint5 opcode, uint4 ird, uint4 irn, uint32 rm); - void armMem_v4(uint5 opcode, uint2 sh, uint4 ird, uint4 irn, uint32 rm); - void armMem_v5(uint5 opcode, uint2 sh, uint4 ird, uint4 irn, uint32 rm); - void armBlock(uint5 opcode, uint4 irn, uint16 rlist); - - // THUMB handlers - void thumbDataLo(uint4 opcode, uint3 ird, uint3 irm); - void thumbDataHi(uint2 opcode, uint4 ird, uint4 irm); - void thumbDataImm(uint2 opcode, uint3 ird, uint8 rm); - void thumbShiftImm(uint2 opcode, uint3 ird, uint3 irm, uint5 rs); - void thumbAddSub(uint2 opcode, uint3 ird, uint3 irn, uint3 irm); - void thumbMemImm(uint5 opcode, uint3 ird, uint3 irn, uint5 rm); - void thumbMemReg(uint3 opcode, uint3 ird, uint3 irn, uint3 irm); - void thumbRelative(uint5 opcode, uint3 ird, uint8 rm); - void thumbAddSP(uint1 opcode, uint7 rm); - void thumbBlock(uint4 opcode, uint3 irn, uint8 rlist); - void thumbCond(uint4 opcode, int8 offset); - void thumbBranch(int11 offset); - void thumbBh(int11 offset); - void thumbBlx(uint1 link, uint11 offset); - - // CPSR - // NZCVQ are stored in a lazy format: - // - Z is only true when 0. - // - NCVQ are true when < 0 (bit 31 set). - int32 Nf, Zf, Cf, Vf, Qf; - uint8 If, Ff, Tf, mode; - - // Output from shifter - int32 carryout; // same format as Cf - - // Pipeline data - bool branched; - uint32 ifetch, idecode, iexecute; - - // Configuration - uint32 vectorBase; // Address of vector table - bool bxWithLoadedPC; // Does LDR/LDM PC behave as MOV or BX Rm? - - // Register banks - // - r_fiq[n] etc. hold registers in other banks. - // - r[n] holds registers for the active mode - // - This means that in FIQ mode, r_fiq[n] holds shadowed _user_ registers. - // - SPSR is not swapped, use spsr() to access it. - uint32 r[16], spsr_none, r_abt[2], spsr_abt; - uint32 r_fiq[7], spsr_fiq, r_irq[2], spsr_irq; - uint32 r_svc[2], spsr_svc, r_und[2], spsr_und; - - // Exception modes - enum { - USR = 0x10, - FIQ = 0x11, IRQ = 0x12, SVC = 0x13, - UND = 0x1b, ABT = 0x17, SYS = 0x1f, - }; -}; diff --git a/bsnes/nds/cpu/cpu.cpp b/bsnes/nds/cpu/cpu.cpp deleted file mode 100644 index 1b9dd4d1..00000000 --- a/bsnes/nds/cpu/cpu.cpp +++ /dev/null @@ -1,337 +0,0 @@ -#include -#include "bit.hpp" -#define imatch(bits) ((i & force< Bit::mask(bits) >()) \ - == force< Bit::binary(bits) >()) - -template static constexpr uint32 force() { return arg; } - -namespace NintendoDS { - -#include "core.cpp" -#include "disasm.cpp" - -ARM7TDMI arm7; -ARM946ES arm9; - - -CPUCore::CPUCore() { - thread = nullptr; -} - -CPUCore::~CPUCore() { - if(thread) co_delete(thread); -} - -void CPUCore::power() { - ARMCore::power(); - - clock = 0; - trace = false; - - powerState = running; - - config.xorSeeds[0] = 0; - config.xorSeeds[1] = 0; - config.slot2ramTiming = 0; - config.slot2romTiming0 = 0; - config.slot2romTiming1 = 0; - config.slot2phi = 0; - - interrupt.gate = false; - interrupt.enable = false; - interrupt.flags = 0; - - status.inVBlank = false; - status.inHBlank = false; - status.inVMatch = false; - status.irqOnVBlank = false; - status.irqOnHBlank = false; - status.irqOnVMatch = false; - status.vcompare = 0; - - msg.enable = false; - msg.irqOnRecv = false; - msg.irqOnSent = false; - msg.error = 0; - msg.empty = 1; - msg.full = 0; - msg.writeOffset = 0; - msg.readOffset = 0; - for(auto &e : msg.buffer) - e = 0; - - sync.enable = false; - sync.output = 0; - - event.irq = false; - event.anydma = false; - event.queue.reset(); - - for(unsigned n = 0; n < 4; n++) { - dma[n].enable = false; - dma[n].irq = false; - dma[n].size = 0; - dma[n].repeat = false; - dma[n].trigger = 0; - dma[n].srcStep = 0; - dma[n].destStep = 0; - dma[n].source = 0; - dma[n].dest = 0; - dma[n].count = 0; - dma[n].fill = 0; - dma[n].init.source = 0; - dma[n].init.dest = 0; - dma[n].init.count = 0; - - timer[n].enable = false; - timer[n].irq = false; - timer[n].cascade = false; - timer[n].divider = 0; - timer[n].reload = 0; - timer[n].count = 0; - timer[n].lastUpdate = 0; - timer[n].event.action = [&, n]() { updateTimer(n); }; - } -} - -void CPUCore::hdraw() { - status.inHBlank = false; - status.inVMatch = false; - - if(192 == video.line) { - status.inVBlank = true; - if(status.irqOnVBlank) - interrupt.flags |= irqVBlank; - - // Trigger vblank DMAs - dmaTrigger(0xf, 1); - } - if(262 == video.line) { - status.inVBlank = false; - } - - // Trigger peripheral-to-framebuffer DMA - if(config.arm9 && 2 <= video.line && video.line < 192+2) - dmaTrigger(0xf, 3); - - if(status.vcompare == video.line) { - status.inVMatch = true; - if(status.irqOnVMatch) { - interrupt.flags |= irqVMatch; - } - } -} - -void CPUCore::hblank() { - status.inHBlank = true; - if(status.irqOnHBlank) - interrupt.flags |= irqHBlank; - - // Trigger HDMAs - if(config.arm9 && video.line < 192) - dmaTrigger(0xf, 2); -} - - - -string CPUCore::tracePsr(uint32 value) { - return { value & 1<<31? "N":" ", - value & 1<<30? "Z":" ", - value & 1<<29? "C":" ", - value & 1<<28? "V":" ", - value & 1<<27? "Q":" ", - value & 1<< 7? "I":" ", - value & 1<< 6? "F":" ", - value & 1<< 5? "T":" ", - "/", hex<2>(value & 0x1f) }; -} - -void CPUCore::traceInsn() { - for(unsigned n = 0; n < 8; n++) print(hex<1>(n),":",hex<8>(r[n])," "); - - print(tracePsr(readCpsr()), "\n"); - - for(unsigned n = 8; n < 16; n++) print(hex<1>(n),":",hex<8>(r[n])," "); - - if(mode != SYS && mode != USR) print(tracePsr(spsr()), "\n"); - else print("--------:--", "\n"); - - if(Tf) print(hex<8>(r[15] - 4), ": ", hex<4>(iexecute), " ", disasm::thumb(this, iexecute), "\n"); - else print(hex<8>(r[15] - 8), ": ", hex<8>(iexecute), " ", disasm::arm(this, iexecute), "\n"); - - fflush(stdout); -} - - - -uint32 CPUCore::readReg(uint32 addr, uint32 size) { - addr &= ~3; - - //static bool vbl = 0; - switch(addr-0x04000000) { - case 0x0004: // Display status - return video.line << 16 | status.irqOnVMatch<< 5 | status.inVMatch<< 2 - | (status.vcompare & 0x0ff)<< 8 | status.irqOnHBlank<< 4 | status.inHBlank<< 1 - | (status.vcompare & 0x100)>> 1 | status.irqOnVBlank<< 3 | status.inVBlank<< 0; - - case 0x1004: - return 0; - - case 0x00b0: // DMA0 source - case 0x00bc: // DMA1 source - case 0x00c8: // DMA2 source - case 0x00d4: // DMA3 source - return regDmaSource((addr-0x40000b0)/12); - - case 0x00b4: // DMA0 dest - case 0x00c0: // DMA1 dest - case 0x00cc: // DMA2 dest - case 0x00d8: // DMA3 dest - return regDmaDest((addr-0x40000b0)/12); - - case 0x00b8: // DMA0 control - case 0x00c4: // DMA1 control - case 0x00d0: // DMA2 control - case 0x00dc: // DMA3 control - return regDmaControl((addr-0x40000b0)/12); - - case 0x00e0: // DMA0 fill - case 0x00e4: // DMA1 fill - case 0x00e8: // DMA2 fill - case 0x00ec: // DMA3 fill - return regDmaFill(addr>>2 & 3); - - case 0x0100: // Timer 0 - case 0x0104: // Timer 1 - case 0x0108: // Timer 2 - case 0x010c: // Timer 3 - return regTimer(addr>>2 & 3); - - case 0x130: { // Keypad input - unsigned keys = 0; - for(unsigned n = 0; n < 10; n++) { - if(interface->inputPoll(ID::Port::Buttons, 0, n)) - keys += 1<(addr),":",size,": unimplemented\n"); - return 0; -} - - - -void CPUCore::writeReg(uint32 addr, uint32 size, uint32 data) { - uint32 mask = 0xffffffff; - if(size == Half) mask = 0xffff << 8*(addr & 2); - if(size == Byte) mask = 0xff << 8*(addr & 3); - - addr &= ~3, data &= mask; - - switch(addr-0x04000000) { - case 0x0004: // Display status - // It might seem odd to have this here, but each CPU has one. - if(mask & 0xff00) status.vcompare = (status.vcompare & 0x100) | (data>>8 & 0x0ff); - if(mask & 0x0080) status.vcompare = (status.vcompare & 0x0ff) | (data<<1 & 0x100); - if(mask & 0x003f) { - status.irqOnVMatch = data >> 5; - status.irqOnHBlank = data >> 4; - status.irqOnVBlank = data >> 3; - } - return; - - case 0x1004: - return; - - case 0x00b0: // DMA0 source - case 0x00bc: // DMA1 source - case 0x00c8: // DMA2 source - case 0x00d4: // DMA3 source - return regDmaSource((addr-0x40000b0)/12, data, mask); - - case 0x00b4: // DMA0 dest - case 0x00c0: // DMA1 dest - case 0x00cc: // DMA2 dest - case 0x00d8: // DMA3 dest - return regDmaDest((addr-0x40000b0)/12, data, mask); - - case 0x00b8: // DMA0 control - case 0x00c4: // DMA1 control - case 0x00d0: // DMA2 control - case 0x00dc: // DMA3 control - return regDmaControl((addr-0x40000b0)/12, data, mask); - - case 0x00e0: // DMA0 fill - case 0x00e4: // DMA1 fill - case 0x00e8: // DMA2 fill - case 0x00ec: // DMA3 fill - return regDmaFill(addr>>2 & 3, data, mask); - - case 0x0100: // Timer 0 - case 0x0104: // Timer 1 - case 0x0108: // Timer 2 - case 0x010c: // Timer 3 - return regTimer(addr>>2 & 3, data, mask); - - case 0x132: // Keypad interrupt - break; - - // SYNC, message control, send port - case 0x0180: return regSync(data, mask); - case 0x0184: return regMsgControl(data, mask); - case 0x0188: return regMsgSend(data); - - // Slot 1 - case 0x01a0: return regSlot1Control(data, mask); - case 0x01a4: return regSlot1RomControl(data, mask); - case 0x01a8: return regSlot1RomCommand(0, data, mask); - case 0x01ac: return regSlot1RomCommand(1, data, mask); - case 0x01b0: return regSlot1RomSeed(0, data, mask); - case 0x01b4: return regSlot1RomSeed(1, data, mask); - case 0x01b8: return regSlot1RomSeed(2, data, mask); - - // IME, IE, IF - case 0x0208: if(mask & 1) interrupt.gate = data & 1; return; - case 0x0210: interrupt.enable = interrupt.enable & ~mask | data; return; - case 0x0214: interrupt.flags &= ~data; return; - case 0x0218: return; // IE: DSi bits - case 0x021c: return; // IF: DSi bits - } - //print("w ",hex<8>(addr),":",size," = ",hex<8>(data),": unimplemented\n"); -} - -#include "slot.cpp" -#include "message.cpp" -#include "dma.cpp" -#include "timer.cpp" -#include "arm7tdmi.cpp" -#include "arm946es.cpp" - -#undef imatch - -} diff --git a/bsnes/nds/cpu/cpu.hpp b/bsnes/nds/cpu/cpu.hpp deleted file mode 100644 index 061e4568..00000000 --- a/bsnes/nds/cpu/cpu.hpp +++ /dev/null @@ -1,288 +0,0 @@ -#include "core.hpp" - -struct CPUCore : ARMCore { - CPUCore(); - ~CPUCore(); - - void power(); - void hdraw(); - void hblank(); - - string tracePsr(uint32 value); - void traceInsn(); - - uint32 readReg(uint32 addr, uint32 size); - void writeReg(uint32 addr, uint32 size, uint32 data); - - void popMsg(); - void pushMsg(uint32 data); - void clearMsg(); - - uint32 regMsgControl(); - uint32 regMsgRecv(); - uint32 regSync(); - - void regMsgControl(uint32 data, uint32 mask); - void regMsgSend(uint32 data); - void regSync(uint32 data, uint32 mask); - - void dmaTransfer(unsigned no); - bool dmaTrigger(unsigned channels, unsigned value); - - uint32 regDmaControl(unsigned no); - uint32 regDmaSource(unsigned no); - uint32 regDmaDest(unsigned no); - uint32 regDmaFill(unsigned no); - - void regDmaControl(unsigned no, uint32 data, uint32 mask); - void regDmaSource(unsigned no, uint32 data, uint32 mask); - void regDmaDest(unsigned no, uint32 data, uint32 mask); - void regDmaFill(unsigned no, uint32 data, uint32 mask); - - void updateTimer(unsigned no); - uint32 regTimer(unsigned no); - void regTimer(unsigned no, uint32 data, uint32 mask); - - uint32 regSlot1Control(); - uint32 regSlot1RomControl(); - uint32 regSlot1RomCommand(unsigned index); - uint32 regSlot1RomRecv(); - - void regSlot1Control(uint32 data, uint32 mask); - void regSlot1RomControl(uint32 data, uint32 mask); - void regSlot1RomCommand(unsigned index, uint32 data, uint32 mask); - void regSlot1RomSeed(unsigned index, uint32 data, uint32 mask); - - uint32 regSlot2Control(); - void regSlot2Control(uint32 data, uint32 mask); - - enum { - // REG_IE, REG_IF bits - irqVBlank = 1<<0, irqHBlank = 1<<1, - irqVMatch = 1<<2, irqTimer = 1<<3, - irqClock = 1<<7, irqDma = 1<<8, - irqKeypad = 1<<12, irqSlot2 = 1<<13, - - irqSync = 1<<16, - irqMsgSent = 1<<17, irqMsgRecv = 1<<18, - irqCardDone = 1<<19, irqSlot1 = 1<<20, - irqGeomBuf = 1<<21, irqLid = 1<<22, - irqSpi = 1<<23, irqWifi = 1<<24, - }; - - struct { - bool arm7, arm9; - - uint64 xorSeeds[2]; - - uint2 slot2ramTiming; - uint2 slot2romTiming0; - uint1 slot2romTiming1; - uint2 slot2phi; - } config; - - struct { - bool gate; - uint32 enable, flags; - } interrupt; - - struct { - uint1 enable, irqOnRecv, irqOnSent; - uint1 error, empty, full; - uint4 writeOffset, readOffset; - uint32 buffer[16]; - } msg; - - struct { - uint1 enable; - uint4 output; - } sync; - - struct { - uint1 inVBlank, inHBlank, inVMatch; // vblank, hblank, line? - uint1 irqOnVBlank, irqOnHBlank, irqOnVMatch; // virq, hirq, lirq? - uint9 vcompare; // lineCompare? - } status; - - struct { - uint1 enable, irq, size, repeat; - uint3 trigger; - uint2 srcStep, destStep; - uint32 source, dest, count, fill; - struct { - uint32 source, dest, count; - } init; - } dma[4]; - - struct Timer { - uint1 enable, irq, cascade; - uint2 divider; - uint16 reload, count; - uint32 lastUpdate; - - Event event; - - uint32 regRead(); - void regWrite(uint32 data, uint32 mask); - void update(); - void operator()(); - } timer[4]; - - struct Ev { - bool irq; - bool anydma; - - EventQueue queue; - - Ev() : queue(60) {} - } event; - - bool trace; - uint32 insnLatch; - unsigned powerState; - enum { running, waiting, sleeping }; - - WordMemory bios; - - CPUCore* other; - - cothread_t thread; - int32 clock; -}; - - - -struct ARM7TDMI : CPUCore { - static void Thread(); - void main(); - void power(); - void step(unsigned clocks); - - alwaysinline void istep(unsigned clocks); - alwaysinline void execARM(); - alwaysinline void execTHUMB(); - - uint32 fetch(uint32 addr, uint32 size, bool s); - uint32 read(uint32 addr, uint32 size, bool s); - void write(uint32 addr, uint32 size, bool s, uint32 data); - void dataCop(uint4 cpno, uint4 op1, uint4 ird, uint4 irn, uint4 irm, uint4 op2); - - uint32 readReg(uint32 addr, uint32 size); - void writeReg(uint32 addr, uint32 size, uint32 data); - - ARM7TDMI(); - - struct SPI { - uint1 enable, hold, irq, size; - uint2 divider; // 4, 2, 1, 0.5 MHz - uint2 device; enum { power, flash, touch, none }; - uint16 data; - } spi; - - struct RTC { - uint4 in[2]; - uint4 out[2]; - uint4 dir[2]; - uint8 buffer; - uint3 index; - } rtc; - - struct SIO { - uint4 in, out, dir; - uint1 irq; - uint2 mode; - } sio; - - uint1 booted; - uint1 flag300; - - uint32 regSpi(); - void regSpi(uint32 data, uint32 mask); - - uint32 regRtc(); - void regRtc(uint32 data, uint32 mask); - - uint32 regSio(); - void regSio(uint32 data, uint32 mask); -}; - - - -struct ARM946ES : CPUCore { - SRAM itcm; - SRAM dtcm; - uint32 itcmRegion, itcmRCompare, itcmRMask, itcmWCompare, itcmWMask; - uint32 dtcmRegion, dtcmRCompare, dtcmRMask, dtcmWCompare, dtcmWMask; - - struct CR { - uint1 mmu; - uint1 dcache, icache; - uint1 endian; enum { little, big }; - uint1 cachePolicy; enum { random, roundRobin }; - uint1 dtcm, dtcmLoad; - uint1 itcm, itcmLoad; - } control; - - // Math functions - uint2 divMode; enum { div32, div64_32, div64 }; - uint1 divByZero; - uint1 divBusy; - int64 numerator; - int64 denominator; - int64 quotient; - int64 remainder; - - uint1 rootMode; enum { sqrt32, sqrt64 }; - uint1 rootBusy; - uint64 square; - uint32 squareRoot; - - uint1 booted; - uint1 flag300; - uint1 slot1access; - uint1 slot2access; - uint1 ramPriority; - - static void Thread(); - void main(); - void power(); - void step(unsigned clocks); - - alwaysinline void istep(unsigned clocks); - alwaysinline void execARM(); - alwaysinline void execTHUMB(); - - uint32 fetch(uint32 addr, uint32 size, bool s); - uint32 read(uint32 addr, uint32 size, bool s); - void write(uint32 addr, uint32 size, bool s, uint32 data); - void dataCop(uint4 cpno, uint4 op1, uint4 ird, uint4 irn, uint4 irm, uint4 op2); - - uint32 readReg(uint32 addr, uint32 size); - void writeReg(uint32 addr, uint32 size, uint32 data); - - void updateTcm(); - - void regDivideControl(uint32 data, uint32 mask); - void regNumerator(unsigned index, uint32 data, uint32 mask); - void regDenominator(unsigned index, uint32 data, uint32 mask); - void regSquareRootControl(uint32 data, uint32 mask); - void regSquare(unsigned index, uint32 data, uint32 mask); - - uint32 regDivideControl(); - uint32 regNumerator(unsigned index); - uint32 regDenominator(unsigned index); - uint32 regQuotient(unsigned index); - uint32 regRemainder(unsigned index); - uint32 regSquareRootControl(); - uint32 regSquare(unsigned index); - uint32 regSquareRoot(); - - void startDivide(); - void startSquareRoot(); - - ARM946ES(); -}; - - -extern ARM7TDMI arm7; -extern ARM946ES arm9; diff --git a/bsnes/nds/cpu/disasm.cpp b/bsnes/nds/cpu/disasm.cpp deleted file mode 100644 index 75cd55bf..00000000 --- a/bsnes/nds/cpu/disasm.cpp +++ /dev/null @@ -1,411 +0,0 @@ -//#include "bit.hpp" -namespace disasm { - -#define collect(i, bits) (Bit::collect< Bit::field(bits) >((long)i)) -#define match(i, bits) ((i & force< Bit::mask(bits) >()) \ - == force< Bit::binary(bits) >()) - -template static constexpr uint32 force() { return arg; } - -static string conds[] = { - "eq","ne","cs","cc","mi","pl","vs","vc","hi","ls","ge","lt","gt","le","","" -}; -static string regs[] = { - "r0","r1","r2","r3","r4","r5","r6","r7","r8","r9","r10","r11","r12","sp","lr","pc" -}; -static string aluops[] = { - "and","eor","sub","rsb","add","adc","sbc","rsc","tst","teq","cmp","cmn","orr","mov","bic","mvn" -}; -static string shiftops[] = { - "lsl","lsr","asr","ror" -}; -static string blockops[] = { - "da","ia","db","ib" -}; - -string armAddr(uint2 index, uint4 rn, string u, string rm) { - if(index < 2) return {"[", regs[rn], "], ", u, rm}; - if(index == 2) return {"[", regs[rn], ", ", u, rm, "]"}; - if(index == 3) return {"[", regs[rn], ", ", u, rm, "]!"}; -} - -string armImmed(uint8 imm, uint4 rs) { - if(!rs) return {"#0x",hex<8>(imm)}; - if(imm & 0x03) return {"#0x",hex<8>(imm << 32-2*rs | imm >> 2*rs)}; - else return {"#0x",hex<2>(imm), ", ", 2*rs}; -} - -string armOffset8(uint4 lo, uint4 hi) { - return {"#0x",hex<2>(hi<<4 | lo)}; -} - -string armOffset12(uint12 offset) { - return {"#0x",hex<3>(offset)}; -} - -string armRm(uint4 rm) { - return regs[rm]; -} - -string armShiftImm(uint4 rm, uint2 sh, uint5 imm) { - if(sh==0 && imm==0) return regs[rm]; - if(sh==3 && imm==0) return {regs[rm], ", rrx"}; - return {regs[rm], ", ", shiftops[sh], " #", imm==0? 32u : (unsigned)imm}; -} - -string armShiftReg(uint4 rm, uint2 sh, uint4 rs) { - return {regs[rm], ", ", shiftops[sh], " ", regs[rs]}; -} - -string armUndefined(uint32 i) { - return {" #0x", hex<8>(i)}; -} - -string armBkpt(uint4 cc, uint12 hi, uint4 lo) { - return {"bkpt", conds[cc], " #0x", hex<4>(hi<<4 | lo)}; -} - -string armSwi(uint4 cc, uint24 immed) { - return {"swi", conds[cc], " #0x", hex<6>(immed)}; -} - -string armWritePsr(uint4 cc, uint1 psr, uint4 mask, string rm) { - string f = mask&8? "f":""; - string s = mask&4? "s":""; - string x = mask&2? "x":""; - string c = mask&1? "c":""; - return {"msr", conds[cc], " ", psr? "spsr":"cpsr", "_", f,s,x,c, ", ", rm}; -} - -string armReadPsr(uint4 cc, uint1 psr, uint4 rd) { - return {"mrs", conds[cc], " ", regs[rd], ", ", psr? "spsr":"cpsr"}; -} - -string armClz(uint4 cc, uint4 rd, uint4 rm) { - return {"clz", conds[cc], " ", regs[rd], ", ", regs[rm]}; -} - -string armDspAdd(uint4 cc, uint2 op, uint4 rd, uint4 rn, uint4 rm) { - string alu = op&1? "sub":"add"; - string d = op&2? "d":""; - return {"q",d,alu, conds[cc], " ", regs[rd], ", ", regs[rn], ", ", regs[rm]}; -} - -string armDspMul(uint4 cc, uint2 op, uint2 xy, uint4 rd, uint4 rn, uint4 rm, uint4 rs) { - string x = xy&1? "t":"b"; - string y = xy&2? "t":"b"; - - if(op==3) return {"smul",x,y, conds[cc], " ", regs[rd], ", ", regs[rm], ", ", regs[rs]}; - if(op==0) return {"smla",x,y, conds[cc], " ", regs[rd], ", ", regs[rm], ", ", regs[rs], ", ", regs[rn]}; - if(op==2) return {"smlal",x,y,conds[cc], " ", regs[rn], ", ", regs[rd], ", ", regs[rm], ", ", regs[rs]}; - - if(op==1 && (xy&1)) return {"smulw",y, conds[cc], " ", regs[rd], ", ", regs[rm], ", ", regs[rs]}; - if(op==1) return {"smlaw",y, conds[cc], " ", regs[rd], ", ", regs[rm], ", ", regs[rs], ", ", regs[rn]}; -} - -string armMultiply(uint4 cc, uint4 op, uint4 rd, uint4 rn, uint4 rm, uint4 rs) { - string s = op & 1? "s":""; - op &= ~1; - - if(op== 0) return {"mul", conds[cc], s, " ", regs[rd], ", ", regs[rm], ", ", regs[rs]}; - if(op== 2) return {"mla", conds[cc], s, " ", regs[rd], ", ", regs[rm], ", ", regs[rs], ", ", regs[rn]}; - - if(op== 8) return {"umull", conds[cc], s, " ", regs[rn], ", ", regs[rd], ", ", regs[rm], ", ", regs[rs]}; - if(op==10) return {"umlal", conds[cc], s, " ", regs[rn], ", ", regs[rd], ", ", regs[rm], ", ", regs[rs]}; - if(op==12) return {"smull", conds[cc], s, " ", regs[rn], ", ", regs[rd], ", ", regs[rm], ", ", regs[rs]}; - if(op==14) return {"smlal", conds[cc], s, " ", regs[rn], ", ", regs[rd], ", ", regs[rm], ", ", regs[rs]}; -} - -string armData(uint4 cc, uint5 op, uint4 rd, uint4 rn, string rm) { - string alu = aluops[collect(op, "aaaa.")]; - string s = collect(op, "....s")? "s" : ""; - - if(alu == "cmp" || alu == "cmn" || alu == "tst" || alu == "teq") - return {alu, conds[cc], s, " ", regs[rn], ", ", rm}; - - if(alu == "mov" || alu == "mvn" || rd == rn) - return {alu, conds[cc], s, " ", regs[rd], ", ", rm}; - - return {alu, conds[cc], s, " ", regs[rd], ", ", regs[rn], ", ", rm}; -} - -string armMem(uint4 cc, uint5 op, uint4 rd, uint4 rn, string rm) { - uint2 index = collect(op, "p..w."); - string u = collect(op, ".u...")? "" : "-"; - string b = collect(op, "..b..")? "b" : ""; - uint1 l = collect(op, "....l"); - - return {cc==15? "pld" : l? "ldr":"str", conds[cc], b, index==1?"t":"", - " ", regs[rd], ", ", armAddr(index, rn, u, rm)}; -} - -string armMem_v4(uint4 cc, uint5 op1, uint2 op2, uint4 rd, uint4 rn, string rm) { - uint2 index = collect(op1, "p..w."); - string u = collect(op1, ".u...")? "" : "-"; - uint1 l = collect(op1, "....l"); - string sh = op2==2?"sb" : op2==3?"sh" : "h"; - - return {l?"ldr":"str", conds[cc], sh, " ", regs[rd], ", ", armAddr(index, rn, u, rm)}; -} - -string armMem_v5(uint4 cc, uint5 op1, uint2 op2, uint4 rd, uint4 rn, string rm) { - uint2 index = collect(op1, "p..w."); - string u = collect(op1, ".u...")? "" : "-"; - uint1 s = op2 & 1; - - return {s?"str":"ldr", conds[cc], "d ", regs[rd], ", ", armAddr(index, rn, u, rm)}; -} - -string armMemSwap(uint4 cc, uint1 op, uint4 rd, uint4 rn, uint4 rm) { - string b = op? "b":""; - return {"swp", conds[cc], b, " ", regs[rm],", ", regs[rd], ", [", regs[rn], "]"}; -} - -string armMemCop(uint4 cc, uint4 cpno, uint5 op, uint4 rd, uint4 rn, uint8 offset) { - uint2 index = collect(op, "p..w."); - string u = collect(op, ".u...")? "" : "-"; - string n = collect(op, "..n..")? "l" : ""; - uint1 l = collect(op, "....l"); - - return {l? "ldc":"stc", conds[cc], cc==15?"2":"", n, " p",cpno, ", c",regs[rd], ", ", - armAddr(index, rn, index?u:"#", {"0x",hex<2>(offset)})}; -} - -string armBlock(uint4 cc, uint5 op, uint4 rn, uint16 rlist) { - uint2 index = collect(op, "pu..."); - string s = collect(op, "..s..")? "^" : ""; - string w = collect(op, "...w.")? "!" : ""; - uint1 l = collect(op, "....l"); - - string regnames = ""; - for(unsigned b = 0; b < 16; b++) { - if(rlist & 1<(target) + 2*link*exch}; -} - -string armBranchEx(uint4 cc, uint2 sh, uint4 rm) { - return {sh & 1? "blx":"bx", conds[cc], " ", regs[rm]}; -} - -string armCop(uint4 cc, uint4 cpno, uint4 op1, uint4 rd, uint4 rn, uint4 rm, uint4 op2) { - bool cdp = ~op2 & 1; - bool l = op1 & 1; - if(!cdp) op1 >>= 1; - op2 >>= 1; - return {cdp?"cdp" : l? "mrc":"mcr", conds[cc], cc==15?"2":"", - " p",cpno, ",", op1>>1, ", ", cdp?"cr":"r",rd, ", ", "cr",rn, ", ", "cr",rm, ", ", op2}; -} - -string armCop_v5(uint4 cc, uint4 cpno, uint4 op1, uint4 rd, uint4 rn, uint4 rm, uint4 op2) { - bool l = op1 & 1; - return {l? "mrrc":"mcrr", conds[cc], cc==15?"2":"", - " p",cpno, ",", op2, ", ", regs[rd], ", ", regs[rn], ", ", "cr",rm}; -} - - - -static string thumbmemregops[] = { - "str", "strh", "strb", "ldrsb", "ldr", "ldrh", "ldrb", "ldrsh" -}; -static string thumbmemimmops[] = { - "str", "ldr", "strb", "ldrb", "strh", "ldrh" -}; - -string thumbUndefined(uint16 i) { - return {" #0x", hex<4>(i)}; -} - -string thumbBkpt(uint8 imm) { - return {"bkpt #0x", hex<2>(imm)}; -} - -string thumbSwi(uint8 imm) { - return {"swi #0x", hex<2>(imm)}; -} - -string thumbAddSub(uint2 op, uint3 rd, uint3 rn, uint3 rm) { - if(op == 2 && rm == 0) return {"mov ", regs[rd], ", ", regs[rn]}; - if(op & 2) return {op & 1?"sub":"add", " ", regs[rd], ", ", regs[rn], ", #", rm}; - else return {op & 1?"sub":"add", " ", regs[rd], ", ", regs[rn], ", ", regs[rm]}; -} - -string thumbShiftImm(uint2 op, uint3 rd, uint3 rm, uint5 imm) { - return {shiftops[op], " ", regs[rd], ", ", regs[rm], ", #", op==0 || imm? (unsigned)imm : 32}; -} - -string thumbDataImm(uint2 op, uint3 rd, uint8 imm) { - if(op == 0) return {"mov ", regs[rd], ", #0x", hex<2>(imm)}; - if(op == 1) return {"cmp ", regs[rd], ", #0x", hex<2>(imm)}; - if(op == 2) return {"add ", regs[rd], ", #0x", hex<2>(imm)}; - if(op == 3) return {"sub ", regs[rd], ", #0x", hex<2>(imm)}; -} - -string thumbDataLo(uint4 op, uint3 rd, uint3 rm) { - if(op == 2) return {"lsl ", regs[rd], ", ", regs[rm]}; - if(op == 3) return {"lsr ", regs[rd], ", ", regs[rm]}; - if(op == 4) return {"asr ", regs[rd], ", ", regs[rm]}; - if(op == 7) return {"ror ", regs[rd], ", ", regs[rm]}; - if(op == 9) return {"neg ", regs[rd], ", ", regs[rm]}; - if(op ==13) return {"mul ", regs[rd], ", ", regs[rm]}; - - return {aluops[op], " ", regs[rd], ", ", regs[rm]}; -} - -string thumbDataHi(uint2 op, uint4 rd, uint4 rm) { - if(op == 0) return {"add ", regs[rd], ", ", regs[rm]}; - if(op == 1) return {"cmp ", regs[rd], ", ", regs[rm]}; - if(op == 2) return {"mov ", regs[rd], ", ", regs[rm]}; - if(rd & 8) return {"blx ", regs[rm]}; - else return {"bx ", regs[rm]}; -} - -string thumbMemReg(uint3 op, uint3 rd, uint3 rn, uint3 rm) { - return {thumbmemregops[op], " ", regs[rd], ", [", regs[rn], ", ", regs[rm], "]"}; -} - -string thumbMemImm(uint5 op, uint3 rd, uint3 rn, uint5 offset) { - unsigned rm = offset; - if(op < 14) rm *= 4; - if(op >= 16) rm *= 2; - - return {thumbmemimmops[op-12], " ", regs[rd], ", [", regs[rn], ", #0x", hex<3>(rm), "]"}; -} - -string thumbAddSP(uint1 op, uint7 offset) { - return {op?"sub":"add", " sp, #0x", hex<3>(4*offset)}; -} - -string thumbRelative(uint5 op, uint3 rd, uint8 offset) { - if(op == 9) return {"ldr ", regs[rd], ", [pc, #0x", hex<3>(4*offset), "]"}; - if(op ==18) return {"str ", regs[rd], ", [sp, #0x", hex<3>(4*offset), "]"}; - if(op ==19) return {"ldr ", regs[rd], ", [sp, #0x", hex<3>(4*offset), "]"}; - if(op ==20) return {"add ", regs[rd], ", pc, ", "#0x", hex<3>(4*offset)}; - if(op ==21) return {"add ", regs[rd], ", sp, ", "#0x", hex<3>(4*offset)}; -} - -string thumbBlock(uint4 op, uint3 rn, uint8 rlist) { - bool l = op & 1; - string regnames = ""; - for(unsigned b = 0; b < 8; b++) { - if(rlist & 1<(target)}; -} - -string thumbBranch(uint32 target) { - return {"b 0x", hex<8>(target)}; -} - -string thumbBh(int11 offset_hi) { - return {"bh 0x", hex<3>(2*offset_hi)}; -} - -string thumbBl(uint1 tbit, uint32 target) { - return {tbit? "bl":"blx", " 0x", hex<8>(target)}; -} - -string arm(ARMCore* arm, uint32 i) { - uint8 op = i>>20; - uint4 cc = i>>28; - uint4 rd = i>>12, rn = i>>16; - uint4 rm = i, rs = i>>8; - uint2 sh = i>>5; - uint32 pc = arm->r[15] & ~3; - - if(match(i, "1111 0101u101/// ..../")) return armMem(15, op, rd, rn, armOffset12(i)); - if(match(i, "1111 0111u101/// ...0/")) return armMem(15, op, rd, rn, armShiftImm(rm, sh, i>>7)); - if(match(i, "1111 101l..../// ..../")) return armBranch(14, 0, 1, pc + 4*int24(i)); - if(match(i, "1111 1100000l/// ..../")) return armUndefined(i); - if(match(i, "1111 1100010l/// ..../")) return armCop_v5(15, i>>8, op, rd, rn, rm, i>>4); - if(match(i, "1111 110punwl/// ..../")) return armMemCop(15, i>>8, op, rd, rn, i); - if(match(i, "1111 1110..../// ..../")) return armCop(15, i>>8, op, rd, rn, rm, i>>4); - if(match(i, "1111 ......../// ..../")) return armUndefined(i); - - if(match(i, ".... 00110r10/// ..../")) return armWritePsr(cc, i>>22, rn, armImmed(i, rs)); - if(match(i, ".... 00010r10/// 0000/")) return armWritePsr(cc, i>>22, rn, armRm(rm)); - if(match(i, ".... 00010r00/// 0000/")) return armReadPsr (cc, i>>22, rd); - if(match(i, ".... 00010010/// 00l1/")) return armBranchEx(cc, sh, rm); - if(match(i, ".... 00010010/// 0111/")) return armBkpt (cc, i>>8, i); - if(match(i, ".... 00010110/// 0001/")) return armClz (cc, rd, rm); - if(match(i, ".... 00010ds0/// 0101/")) return armDspAdd (cc, i>>21, rd, rn, rm); - if(match(i, ".... 00010oo0/// 1yx0/")) return armDspMul (cc, i>>21, sh, rn, rd, rm, rs); - - if(match(i, ".... 0000luas/// 1001/")) return armMultiply(cc, op, rn, rd, rm, rs); - if(match(i, ".... 00010b00/// 1001/")) return armMemSwap (cc, i>>22, rd, rn, rm); - if(match(i, ".... 0000ui1l/// 1sh1/")) return armUndefined(i); - if(match(i, ".... 000pu0w0/// 11s1/")) return armMem_v5 (cc, op, sh, rd, rn, armRm(i)); - if(match(i, ".... 000pu0wl/// 1sh1/")) return armMem_v4 (cc, op, sh, rd, rn, armRm(i)); - if(match(i, ".... 000pu1w0/// 11s1/")) return armMem_v5 (cc, op, sh, rd, rn, armOffset8(i, i>>8)); - if(match(i, ".... 000pu1wl/// 1sh1/")) return armMem_v4 (cc, op, sh, rd, rn, armOffset8(i, i>>8)); - - if(match(i, ".... 000aaaas/// 0sh1/")) return armData (cc, op, rd, rn, armShiftReg(rm, sh, rs)); - if(match(i, ".... 000aaaas/// .sh0/")) return armData (cc, op, rd, rn, armShiftImm(rm, sh, i>>7)); - if(match(i, ".... 001aaaas/// ..../")) return armData (cc, op, rd, rn, armImmed(i, rs)); - if(match(i, ".... 010pubwl/// ..../")) return armMem (cc, op, rd, rn, armOffset12(i)); - if(match(i, ".... 011pubwl/// ...0/")) return armMem (cc, op, rd, rn, armShiftImm(rm, sh, i>>7)); - - if(match(i, ".... 100puswl/// ..../")) return armBlock(cc, op, rn, i); - if(match(i, ".... 101l..../// ..../")) return armBranch(cc, i>>24, 0, pc + 4*int24(i)); - if(match(i, ".... 1100000l/// ..../")) return armUndefined(i); - if(match(i, ".... 1100010l/// ..../")) return armCop_v5(cc, i>>8, op, rd, rn, rm, i>>4); - if(match(i, ".... 110punwl/// ..../")) return armMemCop(cc, i>>8, op, rd, rn, i); - if(match(i, ".... 1110..../// ..../")) return armCop(cc, i>>8, op, rd, rn, rm, i>>4); - if(match(i, ".... 1111..../// ..../")) return armSwi(cc, i); - - return armUndefined(i); -} - -string thumb(ARMCore* arm, uint16 i) { - uint32 pc = arm->r[15] & ~1; - - if(match(i, "00011ismmmnnnddd")) return thumbAddSub (i>>9, i, i>>3, i>>6); - if(match(i, "000ssiiiiimmmddd")) return thumbShiftImm(i>>11, i, i>>3, i>>6); - if(match(i, "001oodddiiiiiiii")) return thumbDataImm (i>>11, i>>8, i); - if(match(i, "010000oooommmddd")) return thumbDataLo (i>>6, i, i>>3); - if(match(i, "010001oodmmmmddd")) return thumbDataHi (i>>8, (i&7)+(i>>4&8), i>>3); - - if(match(i, "0101ooommmnnnddd")) return thumbMemReg (i>>9, i, i>>3, i>>6); - if(match(i, "011bliiiiinnnddd")) return thumbMemImm (i>>11, i, i>>3, i>>6); - if(match(i, "1000liiiiinnnddd")) return thumbMemImm (i>>11, i, i>>3, i>>6); - - if(match(i, "10111110........")) return thumbBkpt(i); - if(match(i, "10110000siiiiiii")) return thumbAddSP ( i>>7, i); - if(match(i, "01001dddrrrrrrrr")) return thumbRelative(i>>11, i>>8, i); - if(match(i, "1001odddrrrrrrrr")) return thumbRelative(i>>11, i>>8, i); - if(match(i, "1010odddrrrrrrrr")) return thumbRelative(i>>11, i>>8, i); - - if(match(i, "11011110rrrrrrrr")) return thumbUndefined(i); - if(match(i, "11011111rrrrrrrr")) return thumbSwi(i); - if(match(i, "1101ccccrrrrrrrr")) return thumbCond ( i>>8, pc + 2*int8(i)); - if(match(i, "11100rrrrrrrrrrr")) return thumbBranch (pc + 2*int11(i)); - if(match(i, "11110rrrrrrrrrrr")) return thumbBh (i); - if(match(i, "11101rrrrrrrrrr1")) return thumbUndefined(i); - if(match(i, "111t1rrrrrrrrrrr")) return thumbBl (i>>12, arm->r[14] + 2*uint11(i)); - if(match(i, "1o..lnnnrrrrrrrr")) return thumbBlock (i>>11, i>>8, i); - - return thumbUndefined(i); -} - -#undef collect -#undef match -} diff --git a/bsnes/nds/cpu/dma.cpp b/bsnes/nds/cpu/dma.cpp deleted file mode 100644 index f69363ec..00000000 --- a/bsnes/nds/cpu/dma.cpp +++ /dev/null @@ -1,131 +0,0 @@ - -bool CPUCore::dmaTrigger(unsigned channels, unsigned value) { - for(unsigned no = 0; no < 4; no++) { - if((channels & 1<dma[no]; - - uint32 size = dma.size? Word : Half; - uint32 srcmask = config.arm7 && no == 0? 0x07fffffe : 0x0ffffffe; - uint32 destmask = config.arm7 && no < 3? 0x07fffffe : 0x0ffffffe; - uint32 countmask = 0x1fffff; - - if(config.arm7) - countmask = no < 3? 0x3fff : 0xffff; - - int srcinc = (dma.srcStep == 1? -2 : dma.srcStep != 2? +2 : 0); - int destinc = (dma.destStep == 1? -2 : dma.destStep != 2? +2 : 0); - - if(size == Word) - srcinc <<= 1, destinc <<= 1; - - do { - uint32 data = read(dma.source, size, true); - write(dma.dest, size, true, data); - - dma.source = (dma.source + srcinc) & srcmask; - dma.dest = (dma.dest + destinc) & destmask; - } while(--dma.count & countmask); - - if(dma.destStep == 3) dma.dest = dma.init.dest; - if(dma.repeat == 1) dma.count = dma.init.count; - if(dma.repeat == 0) dma.enable = false; - - if(dma.irq) interrupt.flags |= irqDma << no; -} - - -uint32 CPUCore::regDmaControl(unsigned no) { - return dma[no].init.count<<0 | dma[no].destStep<<21 | dma[no].srcStep<<23 - | dma[no].repeat<<25 | dma[no].size<<26 | dma[no].trigger<<27 - | dma[no].irq<<30 | dma[no].enable<<31; -} - -uint32 CPUCore::regDmaSource(unsigned no) { - return dma[no].init.source; -} - -uint32 CPUCore::regDmaDest(unsigned no) { - return dma[no].init.dest; -} - -uint32 CPUCore::regDmaFill(unsigned no) { - return dma[no].fill; -} - -void CPUCore::regDmaControl(unsigned no, uint32 data, uint32 mask) { - auto &dma = this->dma[no]; - - uint32 countmask = 0x1fffff; - if(config.arm7) // still limited to 16K / 64K transfers - countmask = no < 3? 0x3fff : 0xffff; - - if(mask & countmask) { - dma.init.count ^= (dma.init.count ^ data) & countmask; - } - if(mask & 0xffe00000) { // ?? - bool previously = dma.enable; - - dma.destStep = data>>21; - dma.srcStep = data>>23; - dma.repeat = data>>25; - dma.size = data>>26; - dma.trigger = data>>27; - dma.irq = data>>30; - dma.enable = data>>31; - - if(config.arm7) - dma.trigger >>= 1; - - if(dma.enable) { - if(previously == false) { - // Latch new settings - dma.source = dma.init.source; - dma.dest = dma.init.dest; - dma.count = dma.init.count; - } - if(dma.trigger == 0) { - dmaTransfer(no); - } - else if(dma.trigger == 7) { - // Geometry fifo - DMA display list - // - just do it right here since we lack timing - dmaTransfer(no); - } - //else { - // print(config.arm7?"arm7":"arm9", - // ": dma trigger ",dma.trigger,": unimplemented\n"); - //} - } - } -} - -void CPUCore::regDmaSource(unsigned no, uint32 data, uint32 mask) { - mask &= 0x0ffffffe; - if(config.arm7 && no == 0) - mask &= 0x07fffffe; // DMA0 is internal only - - dma[no].init.source ^= (dma[no].init.source ^ data) & mask; -} - -void CPUCore::regDmaDest(unsigned no, uint32 data, uint32 mask) { - mask &= 0x0ffffffe; - if(config.arm7 && no != 3) - mask &= 0x07fffffe; // only DMA3 can write to slot 2 - - dma[no].init.dest ^= (dma[no].init.dest ^ data) & mask; -} - -void CPUCore::regDmaFill(unsigned no, uint32 data, uint32 mask) { - if(config.arm7) - return; // not present - - dma[no].fill ^= (dma[no].fill ^ data) & mask; -} diff --git a/bsnes/nds/cpu/math.cpp b/bsnes/nds/cpu/math.cpp deleted file mode 100644 index f7ec1bd4..00000000 --- a/bsnes/nds/cpu/math.cpp +++ /dev/null @@ -1,115 +0,0 @@ - -void ARM946ES::regDivideControl(uint32 data, uint32 mask) { - if(mask & 3) divMode = data; - startDivide(); -} - -void ARM946ES::regNumerator(unsigned index, uint32 data, uint32 mask) { - int64 update = data & mask; update <<= 32*index; - int64 umask = mask; umask <<= 32*index; - - numerator ^= (numerator ^ update) & umask; - startDivide(); -} - -void ARM946ES::regDenominator(unsigned index, uint32 data, uint32 mask) { - int64 update = data & mask; update <<= 32*index; - int64 umask = mask; umask <<= 32*index; - - denominator ^= (denominator ^ update) & umask; - startDivide(); -} - - - -void ARM946ES::regSquareRootControl(uint32 data, uint32 mask) { - if(mask & 1) rootMode = data; - startSquareRoot(); -} - -void ARM946ES::regSquare(unsigned index, uint32 data, uint32 mask) { - int64 update = data & mask; update <<= 32*index; - int64 umask = mask; umask <<= 32*index; - - square ^= (square ^ update) & umask; - startSquareRoot(); -} - - - -uint32 ARM946ES::regDivideControl() { - return divMode<<0 | divByZero<<13 | divBusy<<15; -} - -uint32 ARM946ES::regNumerator(unsigned index) { - return numerator >> 32*index; -} - -uint32 ARM946ES::regDenominator(unsigned index) { - return denominator >> 32*index; -} - -uint32 ARM946ES::regQuotient(unsigned index) { - return quotient >> 32*index; -} - -uint32 ARM946ES::regRemainder(unsigned index) { - return remainder >> 32*index; -} - - - -uint32 ARM946ES::regSquareRootControl() { - return rootMode<<0 | rootBusy<<15; -} - -uint32 ARM946ES::regSquare(unsigned index) { - return square >> 32*index; -} - -uint32 ARM946ES::regSquareRoot() { - return squareRoot; -} - - - -void ARM946ES::startDivide() { - divByZero = false; - - int64 n = numerator, d = denominator; - - if(divMode == div32) { n &= 0xffffffffll; n -= 2*(n & 1ll<<31); } - if(divMode != div64) { d &= 0xffffffffll; d -= 2*(d & 1ll<<31); } - - // Ugh, GBATEK does not say at all how remainder works with signed values. - // Will have to fix this later.. - if(d == 0) { - divByZero = true; - quotient = n >= 0? -1 : +1; - remainder = n; - } - else if(n == (-1ll<<63) && d == -1ll) { - quotient = -1ll<<63; - } - else { - quotient = n / d; - remainder = n % d; - } -} - - - -void ARM946ES::startSquareRoot() { - uint64 x = square, r = 0; - if(rootMode == sqrt32) - x = uint32(x); - - for(uint64 bit = 1ull << 62; bit != 0; bit >>= 2) { - r >>= 1; - if(x >= 2*r + bit) { - x -= 2*r + bit; - r += bit; - } - } - squareRoot = r; -} diff --git a/bsnes/nds/cpu/message.cpp b/bsnes/nds/cpu/message.cpp deleted file mode 100644 index 16f7c554..00000000 --- a/bsnes/nds/cpu/message.cpp +++ /dev/null @@ -1,98 +0,0 @@ - -void CPUCore::popMsg() { - msg.full = false; - if(++msg.readOffset == msg.writeOffset) - msg.empty = true; -} - -void CPUCore::pushMsg(uint32 data) { - msg.buffer[msg.writeOffset] = data; - msg.empty = false; - if(++msg.writeOffset == msg.readOffset) - msg.full = true; -} - -void CPUCore::clearMsg() { - msg.readOffset = 0; - msg.writeOffset = 0; - msg.empty = true; - msg.full = false; - for(unsigned n = 0; n < 16; n++) - msg.buffer[n] = 0; -} - -uint32 CPUCore::regMsgControl() { - return msg.enable<<15 | msg.error<<14 - | msg.irqOnRecv<<10 | other->msg.full<<9 | other->msg.empty<<8 - | msg.irqOnSent<<2 | this->msg.full<<1 | this->msg.empty<<0; -} - -void CPUCore::regMsgControl(uint32 data, uint32 mask) { - if(mask & 0x00ff) { - bool previously = msg.irqOnSent; - - msg.irqOnSent = data>>2; - if(data & 1<<3) clearMsg(); - - // Edge triggered - if(msg.empty && msg.irqOnSent && previously == false) { - interrupt.flags |= irqMsgSent; - } - } - if(mask & 0xff00) { - bool previously = msg.irqOnRecv; - - msg.irqOnRecv = data>>10; - msg.enable = data>>15; - if(data & 1<<14) msg.error = false; - - // Edge triggered - if(!other->msg.empty && msg.irqOnRecv && previously == false) - interrupt.flags |= irqMsgRecv; - } -} - -void CPUCore::regMsgSend(uint32 data) { - if(msg.enable) { - if(msg.full) { - msg.error = true; - return; - } - bool wasEmpty = msg.empty; - pushMsg(data); - - if(wasEmpty && other->msg.irqOnRecv) - other->interrupt.flags |= irqMsgRecv; - } -} - -uint32 CPUCore::regMsgRecv() { - uint32 data = other->msg.buffer[other->msg.readOffset]; - - if(other->msg.enable) { - if(other->msg.empty) { - msg.error = true; - return data; - } - other->popMsg(); - - if(other->msg.empty && other->msg.irqOnSent) - other->interrupt.flags |= irqMsgSent; - } - return data; -} - -uint32 CPUCore::regSync() { - return sync.enable<<14 | this->sync.output<<8 | other->sync.output<<0; -} - -void CPUCore::regSync(uint32 data, uint32 mask) { - if(mask & 0xff00) { - sync.enable = data>>14; - sync.output = data>>8; - if(data & 1<<13) { - if(other->sync.enable) - other->interrupt.flags |= irqSync; - } - } -} diff --git a/bsnes/nds/cpu/slot.cpp b/bsnes/nds/cpu/slot.cpp deleted file mode 100644 index ebd7c600..00000000 --- a/bsnes/nds/cpu/slot.cpp +++ /dev/null @@ -1,131 +0,0 @@ - -uint32 CPUCore::regSlot1Control() { - return slot1.spi.baud<<0 | slot1.spi.hold<<6 - | slot1.spi.busy<<7 | slot1.spi.enable<<13 - | slot1.transferIrq<<14 | slot1.enable<<15 - | slot1.spi.data<<16; -} - -uint32 CPUCore::regSlot1RomControl() { - return slot1.decryptLatency<<0 | slot1.xorData<<13 - | slot1.responseLatency<<16 | slot1.xorCmds<<22 - | slot1.dataReady<<23 | slot1.blockSize<<24 - | slot1.clock<<27 | slot1.secureMode<<28 - | 1<<29 | slot1.transferPending<<31; -} - -uint32 CPUCore::regSlot1RomCommand(unsigned index) { - auto cmd = slot1.command; - if(index == 0) cmd >>= 32; - - return (cmd>>24 & 0xff) << 0 - | (cmd>>16 & 0xff) << 8 - | (cmd>> 8 & 0xff) << 16 - | (cmd>> 0 & 0xff) << 24; -} - -uint32 CPUCore::regSlot1RomRecv() { - uint32 data = 0; - data += slot1.readRom() << 0; - data += slot1.readRom() << 8; - data += slot1.readRom() << 16; - data += slot1.readRom() << 24; - return data; -} - -void CPUCore::regSlot1Control(uint32 data, uint32 mask) { - if(mask & 0x000000ff) { - slot1.spi.baud = data>>0; - slot1.spi.hold = data>>6; - } - if(mask & 0x0000ff00) { - slot1.spi.enable = data>>13; - slot1.transferIrq = data>>14; - slot1.enable = data>>15; - - if(slot1.enable == false || slot1.spi.enable == false) { - if(slot1.card && slot1.card->spi) { - //print("slot1 spi: deselect\n"); - slot1.card->spi->select(false); - } - } - } - if(mask & 0x00ff0000) { - // SPI transfer - if(!slot1.spi.enable) return; - slot1.spi.data = slot1.spiTransfer(data>>16); - //print("slot1 spi: w ",hex<2>(data>>16)," r ",hex<2>(slot1.spi.data),"\n"); - } -} - -void CPUCore::regSlot1RomControl(uint32 data, uint32 mask) { - if(mask & 0x00001fff) { - slot1.decryptLatency ^= (slot1.decryptLatency ^ data) & mask; - } - if(mask & 0x0000e000) { - slot1.xorData = data>>13; - if(data & 1<<15) { - slot1.lfsr[0] = config.xorSeeds[0]; - slot1.lfsr[1] = config.xorSeeds[1]; - } - } - if(mask & 0x00ff0000) { - slot1.responseLatency = data>>16; - slot1.xorCmds = data>>22; - } - if(mask & 0xff000000) { - slot1.blockSize = data>>24; - slot1.clock = data>>27; - slot1.secureMode = data>>28; - if(data & 1<<31) - slot1.startRomTransfer(); - } -} - -void CPUCore::regSlot1RomCommand(unsigned index, uint32 data, uint32 mask) { - auto &cmd = slot1.command; - uint64 ldata = data; - - // Big endian commands, argh! - if(index == 0) { - if(mask & 0x000000ff) cmd ^= (cmd ^ ldata<<56) & 0xff00000000000000; - if(mask & 0x0000ff00) cmd ^= (cmd ^ ldata<<40) & 0x00ff000000000000; - if(mask & 0x00ff0000) cmd ^= (cmd ^ ldata<<24) & 0x0000ff0000000000; - if(mask & 0xff000000) cmd ^= (cmd ^ ldata<< 8) & 0x000000ff00000000; - } else { - if(mask & 0x000000ff) cmd ^= (cmd ^ ldata<<24) & 0x00000000ff000000; - if(mask & 0x0000ff00) cmd ^= (cmd ^ ldata<< 8) & 0x0000000000ff0000; - if(mask & 0x00ff0000) cmd ^= (cmd ^ ldata>> 8) & 0x000000000000ff00; - if(mask & 0xff000000) cmd ^= (cmd ^ ldata>>24) & 0x00000000000000ff; - } -} - -void CPUCore::regSlot1RomSeed(unsigned index, uint32 data, uint32 mask) { - if(index == 2) { - data &= 0x7f007f & mask; - if(mask & 0x00007f) config.xorSeeds[0] = (config.xorSeeds[0] & 0xffffffff) | uint64(data>>0 )<<32; - if(mask & 0x7f0000) config.xorSeeds[1] = (config.xorSeeds[1] & 0xffffffff) | uint64(data>>16)<<32; - } - else { - config.xorSeeds[index] ^= (config.xorSeeds[index] ^ data) & mask; - } -} - - - -uint32 CPUCore::regSlot2Control() { - return config.slot2ramTiming<<0 | config.slot2romTiming0<<2 - | config.slot2romTiming1<<4 | config.slot2phi<<5 - | !arm9.slot2access<<7 | !arm9.slot1access<<11 - | 1<<13 | 1<<14 | !arm9.ramPriority<<15; -} - -void CPUCore::regSlot2Control(uint32 data, uint32 mask) { - if(mask & 0xff) { - config.slot2ramTiming = data>>0; - config.slot2romTiming0 = data>>2; - config.slot2romTiming1 = data>>4; - config.slot2phi = data>>5; - } -} - diff --git a/bsnes/nds/cpu/thumb.cpp b/bsnes/nds/cpu/thumb.cpp deleted file mode 100644 index 50ec31ce..00000000 --- a/bsnes/nds/cpu/thumb.cpp +++ /dev/null @@ -1,150 +0,0 @@ - -void ARMCore::thumbShiftImm(uint2 opcode, uint3 ird, uint3 irm, uint5 rs) { - auto &rd = r[ird]; - r[15] += 2; - - SOut r = shiftImm(irm, opcode, rs); - bitf(true, rd = r, r); // lsl, lsr, asr -} - -void ARMCore::thumbAddSub(uint2 opcode, uint3 ird, uint3 irn, uint3 irm) { - auto& rd = r[ird], rn = r[irn], rm = opcode & 2? (uint32)irm : r[irm]; - r[15] += 2; - - if(opcode & 1) sumf(true, rd = rn-rm, rn, ~rm); // subs - else sumf(true, rd = rn+rm, rn, rm); // adds -} - -void ARMCore::thumbDataImm(uint2 opcode, uint3 ird, uint8 rm) { - auto &rd = r[ird], rn = rd; - r[15] += 2; - - if(opcode == 0) bitf(true, rd = rm, {rm, Cf}); // movs - if(opcode == 1) sumf(true, rn-rm, rn, ~rm); // cmps - if(opcode == 2) sumf(true, rd = rn+rm, rn, rm); // adds - if(opcode == 3) sumf(true, rd = rn-rm, rn, ~rm); // subs -} - -void ARMCore::thumbDataLo(uint4 opcode, uint3 ird, uint3 irm) { - auto &rd = r[ird], rm = r[irm]; - r[15] += 2; - - if(opcode == 2) { SOut r = lsl(rd, rm); bitf(true, rd = r, r); } // lsls - else if(opcode == 3) { SOut r = lsr(rd, rm); bitf(true, rd = r, r); } // lsrs - else if(opcode == 4) { SOut r = asr(rd, rm); bitf(true, rd = r, r); } // asrs - else if(opcode == 7) { SOut r = ror(rd, rm); bitf(true, rd = r, r); } // rors - else if(opcode == 9) sumf(true, rd = -rm, 0, ~rm); // negs - else if(opcode == 13) bitf(true, rd = rm * rd, {rm*rd, Cf}); // muls - else alu(2*opcode+1, rd, rd, {rm,Cf}); // others are same as ARM -} - -void ARMCore::thumbDataHi(uint2 opcode, uint4 ird, uint4 irm) { - auto &rd = r[ird], rn = rd, rm = r[irm]; - r[15] += 2; - - if(opcode == 0) rd = rn + rm; // add - if(opcode == 1) sumf(true, rn-rm, rn, ~rm); // cmps - if(opcode == 2) rd = rm; // mov - if(opcode == 3) { // bx, blx - if(ird & 8) r[14] = r[15] - 4 + 1; - return branch(rm & 1, rm); - } - if(ird == 15) branch(1, r[15]); -} - -void ARMCore::thumbMemImm(uint5 opcode, uint3 ird, uint3 irn, uint5 rm) { - auto &rd = r[ird], addr = r[irn]; - r[15] += 2; - - if(opcode == 13) rd = load(addr + 4*rm, Word); // ldr - if(opcode == 15) rd = load(addr + 1*rm, Byte); // ldrb - if(opcode == 17) rd = load(addr + 2*rm, Half); // ldrh - if(opcode == 12) store(addr + 4*rm, Word, rd); // str - if(opcode == 14) store(addr + 1*rm, Byte, rd); // strb - if(opcode == 16) store(addr + 2*rm, Half, rd); // strh -} - -void ARMCore::thumbMemReg(uint3 opcode, uint3 ird, uint3 irn, uint3 irm) { - bool ld = opcode & 1; - auto &rd = r[ird], addr = r[irn] + r[irm]; - r[15] += 2; - - if(opcode == 0) store(addr, Word, rd); // str - if(opcode == 1) store(addr, Half, rd); // strh - if(opcode == 2) store(addr, Byte, rd); // strb - if(opcode == 4) rd = load(addr, Word); // ldr - if(opcode == 5) rd = load(addr, Half); // ldrh - if(opcode == 6) rd = load(addr, Byte); // ldrb - if(opcode == 7) rd = (int16) load(addr, Half); // ldrsh - if(opcode == 3) rd = (int8) load(addr, Byte); // ldrsb -} - -void ARMCore::thumbRelative(uint5 opcode, uint3 ird, uint8 rm) { - auto &rd = r[ird], pc = r[15] & ~3; - r[15] += 2; - - if(opcode == 9) rd = load(pc + 4*rm, Word); // ldr [pc,#n] - if(opcode ==18) store(r[13] + 4*rm, Word, rd); // str [sp,#n] - if(opcode ==19) rd = load(r[13] + 4*rm, Word); // ldr [sp,#n] - if(opcode ==20) rd = pc + 4*rm; // adr rd,pc,.. - if(opcode ==21) rd = r[13] + 4*rm; // adr rd,sp,.. -} - -void ARMCore::thumbAddSP(uint1 opcode, uint7 rm) { - r[15] += 2; - if(opcode == 0) r[13] += 4*rm; // add sp,#n - if(opcode == 1) r[13] -= 4*rm; // sub sp,#n -} - -void ARMCore::thumbBlock(uint4 opcode, uint3 irn, uint8 rlist) { - auto &rn = opcode < 8? r[13] : r[irn]; - bool ld = opcode & 1; - bool up = true; - bool writeback = true; - uint32 regs = rlist; - - if(opcode < 8) { - up = ld; - if(irn & 1) regs |= (1 << 14+ld); - } - - uint32 addr = rn, base = rn, size = 4*bit::count(regs); - if(!up) addr -= size; - r[15] += 2; - - for(unsigned b = 0, s = 0; b < 16; b++) { - if(~regs & 1<timer[no]; - - if(timer.cascade == false) - updateTimer(no); - - return timer.count<<0 | timer.divider<<16 - | timer.cascade<<18 | timer.irq<<22 | timer.enable<<23; -} - -void CPUCore::regTimer(unsigned no, uint32 data, uint32 mask) { - auto &timer = this->timer[no]; - - if(timer.cascade == false) - updateTimer(no); - - event.queue.remove(timer.event); - - if(mask & 0x00ffff) { - timer.reload ^= (timer.reload ^ data) & mask; - } - if(mask & 0xff0000) { - if(!timer.enable && (data & 1<<23)) { - timer.count = timer.reload; - } - timer.divider = data>>16; - timer.cascade = data>>18; - timer.irq = data>>22; - timer.enable = data>>23; - } - - if(timer.cascade == false) - updateTimer(no); -} - -void CPUCore::updateTimer(unsigned no) { - auto &timer = this->timer[no]; - - if(timer.enable) { - uint16 old = timer.count; - uint32 ticks = 1; - - unsigned dbits[] = { 1, 7, 9, 11 }; // 33MHz, 512KHz, 128KHz, 32KHz - unsigned s = dbits[timer.divider]; - uint32 divider = 1 << s; - - if(timer.cascade) { - timer.count++; - } else { - ticks = (event.queue.time >> s) - (timer.lastUpdate >> s); - timer.count += ticks; - } - - if(ticks && timer.count <= old) { - if(timer.irq) interrupt.flags |= irqTimer << no; - - timer.count = timer.reload; - - if(no < 3 && this->timer[no+1].cascade) - updateTimer(no+1); - } - - if(timer.cascade == false) { - uint32 ticksLeft = 0x10000 - timer.count; - uint32 nextTick = divider;// - (event.queue.time & divider-1); - uint32 nextOverflow = nextTick + divider * (ticksLeft-1); - - // The above commented part breaks maxmod's interpolated audio - // - perhaps the internal counters have expanded? - if(event.queue.time & 1) - nextTick -= 1; // align to 33MHz clock however - - event.queue.add(nextOverflow, timer.event); - } - } - timer.lastUpdate = event.queue.time; -} diff --git a/bsnes/nds/gpu/commands.cpp b/bsnes/nds/gpu/commands.cpp deleted file mode 100644 index 530c47e9..00000000 --- a/bsnes/nds/gpu/commands.cpp +++ /dev/null @@ -1,527 +0,0 @@ - -bool GPU::gxMatrixMode() { - if(numArgs < 1) return false; - - matrixMode = args[0]; - return true; -} - -bool GPU::gxMatrixPush() { - if(matrixMode == mmTexture) { - return true; - } - if(matrixMode == mmProjection) { - projStack[0] = projMatrix; - if(projSP++ == 1) { stackOverflow = true; } - return true; - } - // mmModelView or mmLitView - lightStack[viewSP % 32] = lightMatrix; - viewStack[viewSP % 32] = viewMatrix; - - if(viewSP++ >= 31) { stackOverflow = true; } - return true; -} - -bool GPU::gxMatrixPop() { - if(numArgs < 1) return false; - - if(matrixMode == mmTexture) { - return true; - } - if(matrixMode == mmProjection) { - if(projSP-- == 0) { stackOverflow = true; } - projMatrix = projStack[0]; - return true; - } - // mmModelView or mmLitView - args[0] %= 64; - viewSP -= args[0]; - if(viewSP >= 31) { stackOverflow = true; } - - lightMatrix = lightStack[viewSP % 32]; - viewMatrix = viewStack[viewSP % 32]; - return true; -} - -bool GPU::gxMatrixStore() { - if(numArgs < 1) return false; - - if(matrixMode == mmTexture) { - return true; - } - if(matrixMode == mmProjection) { - projStack[0] = projMatrix; - return true; - } - // mmModelView or mmLitView - args[0] %= 32; - if(args[0] == 31) { stackOverflow = true; } - - lightStack[args[0]] = lightMatrix; - viewStack[args[0]] = viewMatrix; - return true; -} - -bool GPU::gxMatrixRestore() { - if(numArgs < 1) return false; - - if(matrixMode == mmTexture) { - return true; - } - if(matrixMode == mmProjection) { - projMatrix = projStack[0]; - clipMatrix = projMatrix; - transform(clipMatrix, viewMatrix); - return true; - } - // mmModelView or mmLitView - args[0] %= 32; - if(args[0] == 31) { stackOverflow = true; } - - lightMatrix = lightStack[args[0]]; - viewMatrix = viewStack[args[0]]; - clipMatrix = projMatrix; - transform(clipMatrix, viewMatrix); - return true; -} - -bool GPU::gxMatrixLoadIdentity() { - loadMatrix({ 0x1000, 0, 0, 0, - 0, 0x1000, 0, 0, - 0, 0, 0x1000, 0, - 0, 0, 0, 0x1000 }); - return true; -} - -// Storage is transposed to make each row contiguous, which is opposite -// of OpenGL. This allows easy multiplication with column vectors. - -bool GPU::gxMatrixLoad4x4() { - if(numArgs < 16) return false; - - loadMatrix({ args[ 0], args[ 4], args[ 8], args[12], - args[ 1], args[ 5], args[ 9], args[13], - args[ 2], args[ 6], args[10], args[14], - args[ 3], args[ 7], args[11], args[15] }); - return true; -} - -bool GPU::gxMatrixLoad4x3() { - if(numArgs < 12) return false; - - loadMatrix({ args[ 0], args[ 3], args[ 6], args[ 9], - args[ 1], args[ 4], args[ 7], args[10], - args[ 2], args[ 5], args[ 8], args[11], - 0, 0, 0, 0x1000 }); - return true; -} - -bool GPU::gxMatrixMult4x4() { - if(numArgs < 16) return false; - - multMatrix({ args[ 0], args[ 4], args[ 8], args[12], - args[ 1], args[ 5], args[ 9], args[13], - args[ 2], args[ 6], args[10], args[14], - args[ 3], args[ 7], args[11], args[15] }); - return true; -} - -bool GPU::gxMatrixMult4x3() { - if(numArgs < 12) return false; - - multMatrix({ args[ 0], args[ 3], args[ 6], args[ 9], - args[ 1], args[ 4], args[ 7], args[10], - args[ 2], args[ 5], args[ 8], args[11], - 0, 0, 0, 0x1000 }); - return true; -} - -bool GPU::gxMatrixRotate() { - if(numArgs < 9) return false; - - multMatrix({ args[0], args[3], args[6], 0, - args[1], args[4], args[7], 0, - args[2], args[5], args[8], 0, - 0, 0, 0, 0x1000 }); - return true; -} - -bool GPU::gxMatrixScale() { - if(numArgs < 3) return false; - - // Don't scale the lighting matrix - unsigned prevMode = matrixMode; - if(matrixMode == mmLitView) - matrixMode = mmModelView; - - multMatrix({ args[0], 0, 0, 0, - 0, args[1], 0, 0, - 0, 0, args[2], 0, - 0, 0, 0, 0x1000 }); - matrixMode = prevMode; - return true; -} - -bool GPU::gxMatrixTranslate() { - if(numArgs < 3) return false; - - multMatrix({ 0x1000, 0, 0, args[0], - 0, 0x1000, 0, args[1], - 0, 0, 0x1000, args[2], - 0, 0, 0, 0x1000 }); - return true; -} - - - -void GPU::unpackColor(int32* color, uint16 rgb) { - // Yes, it's really this crazy. PPU and GPU colors do NOT match! - // Super annoying when trying to hide things or make them seamless. - int r = 2*(rgb>> 0 & 31); r += (r>0); - int g = 2*(rgb>> 5 & 31); g += (g>0); - int b = 2*(rgb>>10 & 31); b += (b>0); - - color[0] = 0x1000*r; - color[1] = 0x1000*g; - color[2] = 0x1000*b; -} - -bool GPU::gxColor() { - if(numArgs < 1) return false; - - unpackColor(vertex.color, args[0]); - return true; -} - -bool GPU::gxNormal() { - if(numArgs < 1) return false; - - // Normalize to +/- 1 range - normal[0] = int10(args[0]>> 0) << 3; - normal[1] = int10(args[0]>>10) << 3; - normal[2] = int10(args[0]>>20) << 3; - normal[3] = 0; - - if(primitive.texTransform == PS::ttNormal) { - // Used for environment mapping. - textureMatrix(0,3) = vertex.texCoord[0]; - textureMatrix(1,3) = vertex.texCoord[1]; - - vertex.texCoord[0] = normal[0]; - vertex.texCoord[1] = normal[1]; - vertex.texCoord[2] = normal[2]; - vertex.texCoord[3] = 0x1000; - - transform(textureMatrix, vertex.texCoord); - } - - transform(lightMatrix, normal); - - vertex.color = emission; - - for(auto& light : lights) { - if(light.enable == false) - continue; - - int32 dl = max(0, -dot(light.eyeVector, normal)); - int32 sl = max(0, -dot(light.halfVector, normal)); - - sl = min(0xfff, sl*sl / 0x1000); - if(useShineTable) - sl = shininess[sl>>5] << 4; - - for(unsigned n = 0; n < 3; n++) { - vertex.color[n] += (int64) specular[n] * light.color[n] * sl / 0x8000000; - vertex.color[n] += (int64) diffuse[n] * light.color[n] * dl / 0x8000000; - vertex.color[n] += (int64) ambient[n] * light.color[n] * 0x200 / 0x8000000; // ?? - } - } - return true; -} - -bool GPU::gxTexCoord() { - if(numArgs < 1) return false; - - vertex.texCoord[0] = 0x1000 * int16(args[0]>> 0); - vertex.texCoord[1] = 0x1000 * int16(args[0]>>16); - vertex.texCoord[2] = 0x1000; - vertex.texCoord[3] = 0x1000; - - // Affine texture transformations - if(primitive.texTransform == PS::ttTexCoord) - transform(textureMatrix, vertex.texCoord); - - //if(primitive.texTransform == PS::ttNormal || primitive.texTransform == PS::ttVertex) { - // // Plug in U,V for environment/vertex mapping - // textureMatrix(0,3) = vertex.texCoord[0]; - // textureMatrix(1,3) = vertex.texCoord[1]; - //} - return true; -} - -bool GPU::gxVertex3i_16() { - if(numArgs < 2) return false; - - // 4.12, +/- 16 range - vertex.position[0] = int16(args[0]>> 0); - vertex.position[1] = int16(args[0]>>16); - vertex.position[2] = int16(args[1]>> 0); - submitVertex(); - return true; -} - -bool GPU::gxVertex3i_10() { - if(numArgs < 1) return false; - - // 4.6, +/- 16 range - vertex.position[0] = int10(args[0]>> 0) << 6; - vertex.position[1] = int10(args[0]>>10) << 6; - vertex.position[2] = int10(args[0]>>20) << 6; - submitVertex(); - return true; -} - -bool GPU::gxVertex2i_XY() { - if(numArgs < 1) return false; - - // Use same Z as before - vertex.position[0] = int16(args[0]>> 0); - vertex.position[1] = int16(args[0]>>16); - submitVertex(); - return true; -} - -bool GPU::gxVertex2i_XZ() { - if(numArgs < 1) return false; - - // Use same Y as before - vertex.position[0] = int16(args[0]>> 0); - vertex.position[2] = int16(args[0]>>16); - submitVertex(); - return true; -} - -bool GPU::gxVertex2i_YZ() { - if(numArgs < 1) return false; - - // Use same X as before - vertex.position[1] = int16(args[0]>> 0); - vertex.position[2] = int16(args[0]>>16); - submitVertex(); - return true; -} - -bool GPU::gxVertex3i_Rel() { - if(numArgs < 1) return false; - - // 0.10, previous vertex +/- 0.125 relative range - vertex.position[0] = int16(vertex.position[0] + int10(args[0]>> 0)); - vertex.position[1] = int16(vertex.position[1] + int10(args[0]>>10)); - vertex.position[2] = int16(vertex.position[2] + int10(args[0]>>20)); - submitVertex(); - return true; -} - - - -bool GPU::gxAttribute() { - if(numArgs < 1) return false; - - for(unsigned n = 0; n < 4; n++) - lights[n].enable = args[0] >> n; - - attributes = args[0]; - return true; -} - -bool GPU::gxTexImage() { - if(numArgs < 1) return false; - - texImage = args[0] & 0x3fffffff; - primitive.texTransform = args[0] >> 30; - - //if(primitive.type == PS::tris || primitive.type == PS::quads) - // primitive.texImage = texImage; - return true; -} - -bool GPU::gxTexPalette() { - if(numArgs < 1) return false; - - texPalette = args[0] & 0x1fff; - - //if(primitive.type == PS::tris || primitive.type == PS::quads) - // primitive.texPalette = texPalette; - return true; -} - - - -bool GPU::gxLightDiffuseAmbient() { - if(numArgs < 1) return false; - - unpackColor(diffuse, args[0] >> 0); - unpackColor(ambient, args[0] >> 16); - - // This is meant to allow display lists to be ignorant of - // the lighting state (namely whether it's in use or not). - if(args[0] & 1<<15) - unpackColor(vertex.color, args[0]); - return true; -} - -bool GPU::gxLightSpecularEmission() { - if(numArgs < 1) return false; - - unpackColor(specular, args[0] >> 0); - unpackColor(emission, args[0] >> 16); - - useShineTable = args[0] & 1<<15; - return true; -} - -bool GPU::gxLightDirection() { - if(numArgs < 1) return false; - - unsigned no = args[0] >> 30; - auto &light = lights[no]; - - light.direction[0] = int10(args[0] >> 0); - light.direction[1] = int10(args[0] >>10); - light.direction[2] = int10(args[0] >>20); - light.direction[3] = 0; - - light.eyeVector = light.direction; - transform(lightMatrix, light.eyeVector); - - light.halfVector[0] = (light.eyeVector[0] + 0)/2; - light.halfVector[1] = (light.eyeVector[1] + 0)/2; - light.halfVector[2] = (light.eyeVector[2] - 0x1000)/2; - light.halfVector[3] = 0; - return true; -} - -bool GPU::gxLightColor() { - if(numArgs < 1) return false; - - unsigned no = args[0] >> 30; - - unpackColor(lights[no].color, args[0]); - return true; -} - -bool GPU::gxLightShininess() { - if(numArgs < 32) return false; - - for(unsigned n = 0; n < 128; n += 4) { - shininess[n+0] = args[n/4] >> 0; - shininess[n+1] = args[n/4] >> 8; - shininess[n+2] = args[n/4] >> 16; - shininess[n+3] = args[n/4] >> 24; - } - return true; -} - - - -bool GPU::gxBeginPrimitive() { - if(numArgs < 1) return false; - - if(uploadList->numPrims < 2048 - && primitive.size >= (primitive.type==PS::quadStrip? 4 : 3)) - uploadList->numPrims++; // terminate the preceding strip - - primitive.type = args[0]; - primitive.size = 0; - primitive.winding = 0; - primitive.attributes = attributes; - primitive.texImage = texImage; - primitive.texPalette = texPalette; - return true; -} - -bool GPU::gxSwapBuffers() { - if(numArgs < 1) return false; - - sceneFinished = true; - swapArgument = args[0]; - return true; -} - -bool GPU::gxViewport() { - if(numArgs < 1) return false; - - viewport.x = (args[0]>> 0 & 0xff) + 0; - viewport.y = (args[0]>> 8 & 0xff) + 0; - viewport.w = (args[0]>>16 & 0xff) + 1 - viewport.x; - viewport.h = (args[0]>>24 & 0xff) + 1 - viewport.y; - return true; -} - - - -bool GPU::gxCullTest() { - if(numArgs < 3) return false; - - // Box range given as x, y, z, w, h, d - int16 a[6] = { - int16(args[0]>> 0), int16(args[0]>>16), int16(args[1]>> 0), - int16(args[1]>>16), int16(args[2]>> 0), int16(args[2]>>16), - }; - // -> l, b, n, r, t, f - a[3] += a[0]; a[4] += a[1]; a[5] += a[2]; - - // Generate all 8 corners and outcodes - int32 out[8]; - ClipSpaceVertex vertex[8] = { // X Y Z - {{ a[0], a[1], a[2], 0x1000 }}, // l,b,n - {{ a[0], a[1], a[5], 0x1000 }}, // l,b,f - {{ a[0], a[4], a[2], 0x1000 }}, // l,t,n - {{ a[0], a[4], a[5], 0x1000 }}, // l,t,f - {{ a[3], a[1], a[2], 0x1000 }}, // r,b,n - {{ a[3], a[1], a[5], 0x1000 }}, // r,b,f - {{ a[3], a[4], a[2], 0x1000 }}, // r,t,n - {{ a[3], a[4], a[5], 0x1000 }}, // r,t,f - }; - for(unsigned n = 0; n < 8; n++) { - transform(clipMatrix, vertex[n].position); - out[n] = outcode(vertex[n]); - } - - // Find out which sides of the box would be drawn - bool front = (out[0] & out[2] & out[4] & out[6]) == 0; - bool back = (out[1] & out[3] & out[5] & out[7]) == 0; - bool bottom = (out[0] & out[1] & out[4] & out[5]) == 0; - bool top = (out[2] & out[3] & out[6] & out[7]) == 0; - bool left = (out[0] & out[1] & out[2] & out[3]) == 0; - bool right = (out[4] & out[5] & out[6] & out[7]) == 0; - - // True if at least one face was accepted - boxResult = front || back || bottom || top || left || right; - return true; -} - -bool GPU::gxPositionTest() { - if(numArgs < 2) return false; - - vertex.position[0] = int16(args[0]>> 0); - vertex.position[1] = int16(args[0]>>16); - vertex.position[2] = int16(args[1]>> 0); - - vertexResult = vertex.position; - transform(clipMatrix, vertexResult); - return true; -} - -bool GPU::gxDirectionTest() { - if(numArgs < 1) return false; - - normalResult[0] = int10(args[0]>> 0) << 3; - normalResult[1] = int10(args[0]>>10) << 3; - normalResult[2] = int10(args[0]>>20) << 3; - normalResult[3] = 0; - - transform(lightMatrix, normalResult); - return true; -} diff --git a/bsnes/nds/gpu/commands.hpp b/bsnes/nds/gpu/commands.hpp deleted file mode 100644 index 032f0c12..00000000 --- a/bsnes/nds/gpu/commands.hpp +++ /dev/null @@ -1,41 +0,0 @@ - - bool gxMatrixMode(); - bool gxMatrixPush(); - bool gxMatrixPop(); - bool gxMatrixStore(); - bool gxMatrixRestore(); - bool gxMatrixLoadIdentity(); - bool gxMatrixLoad4x4(); - bool gxMatrixLoad4x3(); - bool gxMatrixMult4x4(); - bool gxMatrixMult4x3(); - bool gxMatrixRotate(); - bool gxMatrixScale(); - bool gxMatrixTranslate(); - - bool gxColor(); - bool gxNormal(); - bool gxTexCoord(); - bool gxVertex3i_16(); - bool gxVertex3i_10(); - bool gxVertex2i_XY(); - bool gxVertex2i_XZ(); - bool gxVertex2i_YZ(); - bool gxVertex3i_Rel(); - bool gxAttribute(); - bool gxTexImage(); - bool gxTexPalette(); - - bool gxLightDiffuseAmbient(); - bool gxLightSpecularEmission(); - bool gxLightDirection(); - bool gxLightColor(); - bool gxLightShininess(); - - bool gxBeginPrimitive(); - bool gxSwapBuffers(); - bool gxViewport(); - - bool gxCullTest(); - bool gxPositionTest(); - bool gxDirectionTest(); diff --git a/bsnes/nds/gpu/geometry.cpp b/bsnes/nds/gpu/geometry.cpp deleted file mode 100644 index 51a52f08..00000000 --- a/bsnes/nds/gpu/geometry.cpp +++ /dev/null @@ -1,316 +0,0 @@ - -void GPU::submitVertex() { - if(primitive.texTransform == PS::ttVertex) { - textureMatrix(0,3) = vertex.texCoord[0]; - textureMatrix(1,3) = vertex.texCoord[1]; - - vertex.texCoord[0] = vertex.position[0]; - vertex.texCoord[1] = vertex.position[1]; - vertex.texCoord[2] = vertex.position[2]; - vertex.texCoord[3] = 0x1000; - - transform(textureMatrix, vertex.texCoord); - } - - auto &v = primitive.v; - auto input = vertex; - - transform(clipMatrix, input.position); - - switch(primitive.type) { - case PS::tris: - v[primitive.size] = input; - - if(++primitive.size >= 3) - submitTri(v[0], v[1], v[2]); - break; - - case PS::triStrip: - v[min(2, primitive.size)] = input; - - if(++primitive.size >= 3) { - submitTriStrip(v[0], v[1], v[2]); - primitive.winding ^= 1; - v[0] = v[1]; - v[1] = v[2]; - } - break; - - case PS::quads: - v[primitive.size] = input; - - // Slightly different order than triangles and strips - if(++primitive.size >= 4) - submitQuad(v[0], v[1], v[2], v[3]); - break; - - case PS::quadStrip: - if(primitive.size % 2) v[min(3, primitive.size)] = input; - else v[min(2, primitive.size)] = input; - - if(++primitive.size >= 4) { - if(primitive.size % 2 == 0) { - submitQuadStrip(v[0], v[1], v[2], v[3]); - v[0] = v[2]; - v[1] = v[3]; - } - } - break; - } -} - - - -void GPU::submitTri(ClipSpaceVertex& v0, ClipSpaceVertex& v1, ClipSpaceVertex& v2) { - int32 out[] = { outcode(v0), outcode(v1), outcode(v2) }; - int32 face = facing(v0, v1, v2); - - if(primitive.winding == 1) - face = -face; // this can happen when clipping triangle strips - - bool front = primitive.attributes & PS::drawFront; - bool back = primitive.attributes & PS::drawBack; - - bool culled = face && !(front && face > 0 || back && face < 0); - bool clipped = out[0] | out[1] | out[2]; - bool reject = out[0] & out[1] & out[2] | culled; - - if(!reject) { - ClipSpaceVertex *vs[] = { &v0, &v1, &v2 }; - addPoly(vs, 3, clipped); - } - primitive.texImage = texImage; - primitive.texPalette = texPalette; - primitive.size = 0; -} - -void GPU::submitQuad(ClipSpaceVertex& v0, ClipSpaceVertex& v1, ClipSpaceVertex& v2, ClipSpaceVertex& v3) { - int32 out[] = { outcode(v0), outcode(v1), outcode(v2), outcode(v3) }; - int32 face = facing(v0, v1, v2); - - bool front = primitive.attributes & PS::drawFront; - bool back = primitive.attributes & PS::drawBack; - - bool culled = face && !(front && face > 0 || back && face < 0); - bool clipped = out[0] | out[1] | out[2] | out[3]; - bool reject = out[0] & out[1] & out[2] & out[3] | culled; - - if(!reject) { - ClipSpaceVertex *vs[] = { &v0, &v1, &v2, &v3 }; - addPoly(vs, 4, clipped); - } - primitive.texImage = texImage; - primitive.texPalette = texPalette; - primitive.size = 0; -} - - - -void GPU::submitTriStrip(ClipSpaceVertex& v0, ClipSpaceVertex& v1, ClipSpaceVertex& v2) { - int32 face = facing(v0, v1, v2); - - if(primitive.winding == 1) - face = -face; - - // Clipping is a pain here. The easiest way that comes to mind is to check - // whether a vertex was clipped. Then if so, split this polygon off and, - // after clipping, restart the primitive with the current winding order. - bool front = primitive.attributes & PS::drawFront; - bool back = primitive.attributes & PS::drawBack; - - bool culled = face != 0 && !(front && face > 0 || back && face < 0); - bool clipped = outcode(v0) | outcode(v1) | outcode(v2); - - if(culled || clipped) { - if(uploadList->numPrims < 2048 && primitive.size > 3) - uploadList->numPrims++; // Terminate the current strip (if any) - - submitTri(v0, v1, v2); // Submit as separate triangle - primitive.size = 2; // Next vertex restarts the strip - return; - } - if(primitive.size == 3) { - addPrim(Prim::triStrip); - addVertex(v0); - addVertex(v1); - } - addVertex(v2); -} - -void GPU::submitQuadStrip(ClipSpaceVertex& v0, ClipSpaceVertex& v1, ClipSpaceVertex& v2, ClipSpaceVertex& v3) { - int32 face = facing(v0, v1, v3); - bool front = primitive.attributes & PS::drawFront; - bool back = primitive.attributes & PS::drawBack; - - bool culled = face != 0 && !(front && face > 0 || back && face < 0); - bool clipped = outcode(v0) | outcode(v1) | outcode(v2) | outcode(v3); - - if(culled || clipped) { - if(uploadList->numPrims < 2048 && primitive.size > 4) - uploadList->numPrims++; // Terminate the current strip (if any) - - submitQuad(v0, v1, v3, v2); // Submit as separate quad - primitive.size = 2; // Next two vertices restart the strip - return; - } - if(primitive.size == 4) { - addPrim(Prim::quadStrip); - addVertex(v0); - addVertex(v1); - } - addVertex(v2); - addVertex(v3); -} - -bool GPU::addPoly(ClipSpaceVertex **v, unsigned numVerts, bool clip) { - struct Entry { - ClipSpaceVertex v; unsigned out; - Entry() {} - Entry(const ClipSpaceVertex& s) : v(s), out(outcode(s)) {} - operator ClipSpaceVertex() const { return v; } - }; - - vector list[2], *in = list+0, *out = list+1; - - for(unsigned i = 0; i < numVerts; i++) - out->append({ *(v[i]) }); - - if(clip) { - for(unsigned plane = 0; plane < 6; plane++) { - const int axis = plane/2, side = plane%2? +1 : -1; - - std::swap(in, out); - out->reset(); - - for(unsigned i = 0; i < in->size(); ) { - auto &a = (*in)[i++]; - auto &b = (*in)[i % in->size()]; - - if(1<append({ clipEdge(b, a, axis, side) }); - if(1<append({ clipEdge(a, b, axis, side) }); - else out->append({ b }); - } - } - } - if(!out->size()) - return true; - - if(!addPrim(Prim::poly)) - return false; - - for(unsigned i = 0; i < out->size(); i++) - addVertex((*out)[i]); - - uploadList->numPrims++; - return true; -} - -bool GPU::addVertex(const ClipSpaceVertex &v) { - if(uploadList->numPrims == 2048 || uploadList->numVerts == 6144) - return false; - - // XYZ are all in range +/-w in homogenous coordinates - uploadList->prims[uploadList->numPrims].numVerts++; - auto &out = uploadList->verts[uploadList->numVerts++]; - - // xyzw = 20.12 - // uv = 20.12 (in texels) - // rgb = 20.12 (0 - 63.0) - int32 w = v.position[3]; - - // Perspective transformation - divide everything by W. - // This flattens the perspective and allows linear pixel interpolation. - out.w = w? w : 1; // still needed to restore UVZ and RGB. - out.x = (int64) v.position[0] * 0x40000000/w; // x/w - out.y = (int64) v.position[1] * 0x40000000/w; // y/w - out.z = (int64) v.position[2] * 0x40000000/w; // z/w - out.u = (int64) v.texCoord[0] * 0x4000/w; // u/w - out.v = (int64) v.texCoord[1] * 0x4000/w; // v/w - out.r = (int64) v.color[0] * 0x4000/w; // r/w - out.g = (int64) v.color[1] * 0x4000/w; // g/w - out.b = (int64) v.color[2] * 0x4000/w; // b/w - - // Apply viewport scaling. X and Y get rounded off somehow. Vertices and - // interpolants jump around a lot, despite being perspective correct. :( - out.x = (out.x + 0x40000000ll) * viewport.w/2 + 0x400000*viewport.x >> 8; - out.y = (out.y + 0x40000000ll) * viewport.h/2 + 0x400000*viewport.y >> 8; - - // With perspective projections, W is a linear function of Z. Default then - // is to use the nonlinear Z/W, giving more precision close up. This setting - // gives linear depth values instead. - // - // Note: In orthographic/2D views, Z/W is linear anyway because W=1. In that - // case this option kills Z buffering (kinda bad, given the auto Y sort). - //if(uploadList->depthUseW) - // out.z = max(-0x8000, min(0x7fff, w)); // ? - return true; -} - -bool GPU::addPrim(unsigned shape) { - if(uploadList->numPrims == 2048) - return false; - - auto &out = uploadList->prims[uploadList->numPrims]; - - //primitive.texImage = texImage; - //primitive.texPalette = texPalette; - - out.numVerts = 0; - out.firstVert = uploadList->numVerts; - out.id = primitive.attributes >> 24 & 63; - out.alpha = primitive.attributes >> 16 & 31; - out.drawMode = shape; - out.drawMode += Prim::fog * uint1(primitive.attributes >> 15); - out.drawMode += Prim::zequal * uint1(primitive.attributes >> 14); - out.drawMode += Prim::zwrite * uint1(primitive.attributes >> 11); - out.drawMode += Prim::shadeMask & uint2(primitive.attributes >> 4); - out.drawMode += Prim::colorKey * uint1(primitive.texImage >> 29); - - out.texFormat = primitive.texImage >> 26 & 7; - //out.texSize[1] = primitive.texImage >> 23 & 7; - //out.texSize[0] = primitive.texImage >> 20 & 7; - //out.texBorder[1] = primitive.texImage >> 17 & 5; - //out.texBorder[0] = primitive.texImage >> 16 & 5; - out.texImage = primitive.texImage; - out.texPalette = primitive.texPalette; - if(out.texFormat != Prim::I2) - out.texPalette *= 2; - - return true; -} - - -// Matrices, OpenGL style: -// -// clip projection view.. model.. vertex -// |Cx| |0 4 8 c| |0 4 8 c| |0 4 8 c| |Vx| -// |Cy| = |1 5 9 d| * |1 5 9 d| * |1 5 9 d| * |Vy| -// |Cz| |2 6 a e| |2 6 a e| |2 6 a e| |Vz| -// |Cw| |3 7 b f| |3 7 b f| |3 7 b f| |Vw| -// -// transform() multiplies new matrix on the LEFT, ie. m = t*m. - -void GPU::loadMatrix(const Matrix& m) { - if(matrixMode == mmTexture) textureMatrix = m; - else { - if(matrixMode == mmLitView) lightMatrix = m; - if(matrixMode == mmProjection) projMatrix = m; - else /*mmModelView,mmLitView*/ viewMatrix = m; - - clipMatrix = projMatrix; - transform(clipMatrix, viewMatrix); - } -} - -void GPU::multMatrix(const Matrix& m) { - if(matrixMode == mmTexture) transform(textureMatrix, m); - else { - if(matrixMode == mmLitView) transform(lightMatrix, m); - if(matrixMode == mmProjection) transform(projMatrix, m); - else /*mmModelView,mmLitView*/ transform(viewMatrix, m); - - clipMatrix = projMatrix; - transform(clipMatrix, viewMatrix); - } -} diff --git a/bsnes/nds/gpu/geometry.hpp b/bsnes/nds/gpu/geometry.hpp deleted file mode 100644 index fb48cc84..00000000 --- a/bsnes/nds/gpu/geometry.hpp +++ /dev/null @@ -1,83 +0,0 @@ - - uint32 regGeomStatus(); - uint32 regGeomLoad(); - uint32 regGeomPosition(unsigned index); - uint32 regGeomNormal(unsigned index); - uint32 regClipMatrix(unsigned index); - uint32 regLightMatrix(unsigned index); - - void regGeomMaxPointDepth(uint32 data, uint32 mask); - void regGeomStatus(uint32 data, uint32 mask); - - - void loadMatrix(const Matrix& m); - void multMatrix(const Matrix& m); - - void unpackColor(int32* color, uint16 rgb); - - void submitVertex(); - void submitTriStrip(ClipSpaceVertex& v0, ClipSpaceVertex& v1, ClipSpaceVertex& v2); - void submitQuadStrip(ClipSpaceVertex& v0, ClipSpaceVertex& v1, ClipSpaceVertex& v2, ClipSpaceVertex& v3); - void submitTri(ClipSpaceVertex& v0, ClipSpaceVertex& v1, ClipSpaceVertex& v2); - void submitQuad(ClipSpaceVertex& v0, ClipSpaceVertex& v1, ClipSpaceVertex& v2, ClipSpaceVertex& v3); - - bool addPoly(ClipSpaceVertex **v, unsigned numVerts, bool clip); - bool addVertex(const ClipSpaceVertex &v); - bool addPrim(unsigned shape); - - struct Light { - uint1 enable; - Vector color; - Vector direction; - - Vector eyeVector; - Vector halfVector; - }; - - // Matrix state - uint2 matrixMode; enum { mmProjection, mmModelView, mmLitView, mmTexture }; - bool stackOverflow; - uint1 projSP; - uint6 viewSP; - Matrix clipMatrix; - Matrix textureMatrix; - Matrix projMatrix, projStack[1]; - Matrix viewMatrix, viewStack[32]; - Matrix lightMatrix, lightStack[32]; - - Vector vertexResult; - Vector normalResult; - bool boxResult; - - // Lighting and material state - Light lights[4]; - Vector normal; - Vector diffuse; - Vector ambient; - Vector specular; - Vector emission; - uint8 shininess[128]; - bool useShineTable; - - // Primitive state - struct PS { - unsigned size; - uint1 winding; - uint2 type; enum { tris, quads, triStrip, quadStrip }; - uint32 attributes; enum { drawFront = 0x80, drawBack = 0x40 }; - - uint32 texImage; - uint16 texPalette; - uint2 texTransform; enum { ttNone, ttTexCoord, ttNormal, ttVertex }; - - ClipSpaceVertex v[4]; - } primitive; - - uint32 attributes; - uint32 texImage; - uint16 texPalette; - ClipSpaceVertex vertex; - - struct { - unsigned x, y, w, h; - } viewport; diff --git a/bsnes/nds/gpu/gpu.cpp b/bsnes/nds/gpu/gpu.cpp deleted file mode 100644 index 6911f6c2..00000000 --- a/bsnes/nds/gpu/gpu.cpp +++ /dev/null @@ -1,497 +0,0 @@ -#include - -namespace NintendoDS { - -GPU gpu; - - -GPU::GPU() { } - -void GPU::power() { - powered = true; - swapArgument = 0; - uploadList = &sceneList[0]; - renderList = &sceneList[1]; - renderedLines = 0; - stencilMode = false; - sceneFinished = false; - commandBufIrq = false; - packedCommands = 0; - numArgs = 0; - - for(unsigned n = 0; n < 2; n++) { - sceneList[n].numVerts = 0; - sceneList[n].numPrims = 0; - sceneList[n].firstAlpha = 0; - sceneList[n].alphaSort = 1; - sceneList[n].depthUseW = 0; - - memset(sceneList[n].verts, 0, sizeof sceneList[n].verts); - memset(sceneList[n].prims, 0, sizeof sceneList[n].prims); - } - - // Geometry state - Matrix identity = { - 0x1000, 0,0,0, - 0, 0x1000, 0,0, - 0,0, 0x1000, 0, - 0,0,0, 0x1000, - }; - clipMatrix = identity; projSP = viewSP = stackOverflow = 0; - textureMatrix = identity; matrixMode = mmProjection; - projMatrix = identity; for(auto &m : projStack) m = identity; - viewMatrix = identity; for(auto &m : viewStack) m = identity; - lightMatrix = identity; for(auto &m : lightStack) m = identity; - - for(auto &l : lights) { - l.enable = false; - l.color = Vector{0,0,0,0}; - l.direction = Vector{0,0,0,0}; - l.eyeVector = Vector{0,0,0,0}; - l.halfVector = Vector{0,0,0,0}; - } - diffuse = Vector{0,0,0,0}; - ambient = Vector{0,0,0,0}; - specular = Vector{0,0,0,0}; - emission = Vector{0,0,0,0}; - useShineTable = false; - for(auto &e : shininess) e = 0; - - normal = Vector{0,0,0,0}; - vertex.position = Vector{0,0,0,0x1000}; - vertex.texCoord = Vector{0,0,0,0x1000}; - vertex.color = Vector{0x3f000,0x3f000,0x3f000,0}; - - primitive.size = 0; - primitive.winding = 0; - primitive.type = PS::tris; - primitive.attributes = attributes = 0; - primitive.texImage = texImage = 0; - primitive.texPalette = texPalette = 0; - primitive.texTransform = PS::ttNone; - - // Render state - renderControl.texturing = false; - renderControl.toonShading = RC::darken; - renderControl.edgeMode = RC::solid; - renderControl.fogMode = 0; - renderControl.fogLevel = 0; - renderControl.alphaTest = false; - renderControl.alphaBlend = false; - renderControl.backImage = false; - - backColor[0] = 0; fogColor[0] = 0; - backColor[1] = 0; fogColor[1] = 0; - backColor[2] = 0; fogColor[2] = 0; - backAlpha = 0; fogAlpha = 0; - backId = 0; fogZ = 0; - backX = 0; - backY = 0; minAlpha = 0; - backZ = 0x7fff; - - for(auto &e : fogTable) e = 0; - for(auto &e : edgeTable) e = Vector{0,0,0,0}; - for(auto &e : toonTable[0]) e = Vector{0,0,0,0}; - for(auto &e : toonTable[1]) e = Vector{0,0,0,0}; - - for(unsigned n = 0; n < 2; n++) { - drawList[n].first = 0; - drawList[n].last = 0; - drawList[n].nextPrim = 0; - drawList[n].lastPrim = 0; - } -} - -void GPU::scanline() { - uint8 renderTime = (video.line + 50) % 263; - - if(renderTime < 241 && renderedLines < 192+1) { - // Rendering starts in advance. Draw time varies; however, up to 48 extra - // scanlines can be cached, providing a buffer for complicated scenes. - // - // That isn't emulated at the moment. Scanline rendering is still needed, - // however, to get stencilling and other edge cases right. - renderScanline(); - renderedLines++; - } - - if(renderTime == 242) { - // Finished rendering - process the new scene list. - // Games are free to load textures during this time. - swapBuffers(); - renderedLines = -1; - - drawList[0].nextPrim = 0; - drawList[0].lastPrim = renderList->firstAlpha; - drawList[0].first = 0; - drawList[0].last = 0; - - drawList[1].nextPrim = renderList->firstAlpha; - drawList[1].lastPrim = renderList->numPrims; - drawList[1].first = 0; - drawList[1].last = 0; - - for(auto &line : pixels) for(auto &p : line) { - p.a.a = p.b.a = 0; - p.a.id = p.b.id = 0xff; - p.az = p.bz = 0x7fffffff; - } - } - - if(commandBufIrq) - arm9.interrupt.flags |= CPUCore::irqGeomBuf; -} - -void GPU::swapBuffers() { - if(sceneFinished) { - std::swap(uploadList, renderList); - - // These settings apply to the NEW list, not the old one. - uploadList->alphaSort = !(swapArgument >> 0); - uploadList->depthUseW = swapArgument >> 1; - uploadList->numVerts = 0; - uploadList->numPrims = 0; - - // Release the ARM9 if it was blocking on a command.. - sceneFinished = false; - //texCache.reset(); - - // Terminate the current strip, if any. - if(renderList->numPrims < 2048 && primitive.type >= 2 - && primitive.size >= (primitive.type==PS::quadStrip? 4 : 3)) - renderList->numPrims++; - - while(renderList->numPrims) { - auto &p = renderList->prims[renderList->numPrims-1]; - - // Ensure the program submitted enough vertices.. - // Amusingly, this case not only crashes us, but the real GPU as well. - // Should issue a diagnostic here. - // - // This check also catches the case where vertex RAM fills up, - // leaving the last primitive unfinished. - if(p.numVerts < 3 || p.numVerts < 4 && (p.drawMode & Prim::quadStrip)) { - renderList->numPrims--; - } else { - break; - } - } - primitive.size = 0; - - // Sort the new list - auto count = renderList->numPrims; - auto &prims = renderList->prims; - auto &verts = renderList->verts; - - renderList->firstAlpha = 0; - - for(unsigned n = 0; n < count; n++) { - renderList->order[n] = n; - - // Is this per primitive or per polygon? - prims[n].minY = 255; - prims[n].maxY = 0; - - // Clip range is x/w, y/w := +/- 0x40000000 - for(unsigned k = 0; k < prims[n].numVerts; k++) { - int32 y = 192 - verts[prims[n].firstVert + k].y/0x400000; - - prims[n].minY = min(prims[n].minY, y); - prims[n].maxY = max(prims[n].maxY, y); - } - - // Special case for wireframe... only edge pixels are drawn. - if(prims[n].alpha == 0) { - prims[n].alpha = 31; - prims[n].wire = 1; - } - // Alpha is not the only thing that can send a primitive to the - // translucent pile. Using textures with the alpha channel does it too. - prims[n].blend = prims[n].alpha < 31 - || prims[n].texFormat == Prim::A3_I5 - || prims[n].texFormat == Prim::A5_I3; - - if(prims[n].blend == 0) - renderList->firstAlpha++; - } - - std::sort(renderList->order, renderList->order+count, [&](uint16 i0, uint16 i1) -> bool { - auto &p0 = prims[i0], &p1 = prims[i1]; - - if(p0.blend != p1.blend) { - return p0.blend < p1.blend; // separate solid + blend passes - } - if(p0.blend == false || renderList->alphaSort) { - // Sort polygons towards the top of the screen first. They prolly - // do this to save time and avoid searching the entire list. - if(p0.minY != p1.minY) return p0.minY < p1.minY; - if(p0.maxY != p1.maxY) return p0.maxY < p1.maxY; - } - return i0 < i1; // retain order in case of blending or ties - }); - } -} - - - -uint32 GPU::regRenderOptions() { - return renderControl.texturing<<0 | renderControl.toonShading<<1 - | renderControl.alphaTest<<2 | renderControl.alphaBlend<<3 - | renderControl.edgeMode<<4 | renderControl.fogMode<<6 - | renderControl.fogLevel<<8 | renderControl.backImage<<14; -} - -uint32 GPU::regRenderLoad() { - return 48-2; -} - -void GPU::regRenderOptions(uint32 data, uint32 mask) { - if(mask & 0x00ff) { - renderControl.texturing = data >> 0; - renderControl.toonShading = data >> 1; - renderControl.alphaTest = data >> 2; - renderControl.alphaBlend = data >> 3; - renderControl.edgeMode = data >> 4; - renderControl.fogMode = data >> 6; - } - if(mask & 0x7f00) { - renderControl.fogLevel = data >> 8; - renderControl.backImage = data >> 14; - } -} - -void GPU::regRenderMinAlpha(uint32 data, uint32 mask) { - minAlpha ^= (minAlpha ^ data) & mask; -} - -void GPU::regRenderClearColor(uint32 data, uint32 mask) { - if(mask & 0x00007fff) { - backColor[0] = data>> 0 & 31; - backColor[1] = data>> 5 & 31; - backColor[2] = data>>10 & 31; - backFog = data>>15 & 1; - - for(unsigned n = 0; n < 3; n++) - backColor[n] = 2*backColor[n] + (backColor[n] > 0); - } - if(mask & 0x001f0000) backAlpha = data>>16 & 31; - if(mask & 0x3f000000) backId = data>>24 & 63; -} - -void GPU::regRenderClearCoord(uint32 data, uint32 mask) { - if(mask & 0x00007fff) backZ = data>>0; - if(mask & 0x00ff0000) backX = data>>16; - if(mask & 0xff000000) backY = data>>24; -} - -void GPU::regRenderFogColor(uint32 data, uint32 mask) { - if(mask & 0x00007fff) { - fogColor[0] = data>> 0 & 31; - fogColor[1] = data>> 5 & 31; - fogColor[2] = data>>10 & 31; - for(unsigned n = 0; n < 3; n++) - fogColor[n] = 2*fogColor[n] + (fogColor[n] > 0); - } - if(mask & 0x001f0000) { - fogAlpha = data>>16 & 31; - } -} - -void GPU::regRenderFogCoord(uint32 data, uint32 mask) { - if(mask & 0x00007fff) fogZ = data; -} - -void GPU::regRenderFogTable(unsigned index, uint32 data, uint32 mask) { - if(mask & 0x000000ff) fogTable[4*index+0] = data >> 0 & 0x7f; - if(mask & 0x0000ff00) fogTable[4*index+1] = data >> 8 & 0x7f; - if(mask & 0x00ff0000) fogTable[4*index+2] = data >> 16 & 0x7f; - if(mask & 0xff000000) fogTable[4*index+3] = data >> 24 & 0x7f; - - fogTable[32] = fogTable[31]; // extra element for lerping -} - -void GPU::regRenderEdgeTable(unsigned index, uint32 data, uint32 mask) { - //uint6 r0 = 2*uint5(data>> 0), r1 = 2*uint5(data>>16); - //uint6 g0 = 2*uint5(data>> 5), g1 = 2*uint5(data>>21); - //uint6 b0 = 2*uint5(data>>10), b1 = 2*uint5(data>>26); - // - //if(r0) r0++; if(r1) r1++; - //if(g0) g0++; if(g1) g1++; - //if(b0) b0++; if(b1) b1++; - // - //auto *edge = &edgeTable[2*index]; - // - //if(mask & 0x0000ffff) edge[0] = b0<<12 | g0<<6 | r0<<0; - //if(mask & 0xffff0000) edge[1] = b1<<12 | g1<<6 | r1<<0; - if(mask & 0x0000ffff) unpackColor(edgeTable[2*index+0], data>>0); - if(mask & 0xffff0000) unpackColor(edgeTable[2*index+1], data>>16); -} - -void GPU::regRenderToonTable(unsigned index, uint32 data, uint32 mask) { - auto &d0 = toonTable[0][2*index+0]; - auto &d1 = toonTable[0][2*index+1]; - auto &l0 = toonTable[1][2*index+0]; - auto &l1 = toonTable[1][2*index+1]; - - if(mask & 0x0000ffff) unpackColor(d0, data>>0); - if(mask & 0xffff0000) unpackColor(d1, data>>16); - - // Generate entries for lighten mode - l0 = d0; l1 = d1; - l0[0] += 0x1000; l1[0] += 0x1000; - l0[1] += 0x1000; l1[1] += 0x1000; - l0[2] += 0x1000; l1[2] += 0x1000; -} - - - -void GPU::regGeomMaxPointDepth(uint32 data, uint32 mask) { - -} - -void GPU::regGeomStatus(uint32 data, uint32 mask) { - data &= mask; - if(data & 1<<15) { - stackOverflow = false; - projSP = 0; - viewSP = 0; - } - - if(mask & 0xff000000) { - commandBufIrq = data>>30; - if(commandBufIrq) - arm9.interrupt.flags |= CPUCore::irqGeomBuf; - } -} - -uint32 GPU::regGeomStatus() { - return boxResult<<1 | (viewSP % 32)<<8 | projSP<<13 | stackOverflow<<15 - | 1<<25 | 1<<26 | commandBufIrq<<30; -} - -uint32 GPU::regGeomLoad() { - return uploadList->numPrims<<0 | uploadList->numVerts<<16; -} - -uint32 GPU::regGeomPosition(unsigned index) { - return vertexResult[index]; -} - -uint32 GPU::regGeomNormal(unsigned index) { - return uint16(int12(normalResult[index/2 + 0]))<<0 - | uint16(int12(normalResult[index/2 + 1]))<<16; -} - -uint32 GPU::regClipMatrix(unsigned index) { - uint2 col = index / 4; - uint2 row = index % 4; - - return clipMatrix[4*row + col]; -} - -uint32 GPU::regLightMatrix(unsigned index) { - uint2 col = index / 3; - uint2 row = index % 3; - - return lightMatrix[4*row + col]; -} - - - -void GPU::sendGeomBuffered(uint32 data) { - // On real hardware commands are buffered, and filling up this buffer - // forces an indefinite waitstate until the buffer drains. A swapBuffers - // command sits around 'til vblank, thereby throttling the game at 60fps. - - // Since we don't emulate that yet, this is the closest thing. - while(sceneFinished) { - arm9.step(16); - if(arm7.clock < -255) - co_switch(arm7.thread); - } - // Command bytes are packed 4 to a word.. - if(packedCommands) args[numArgs++] = data; - else packedCommands = data; - - // Take the first one and try to run it. - // It succeeds when enough arguments are provided. - // - // It's important to run ALL possible commands here, since some of them - // don't consume any arguments and the next invocation would erroneously - // pass data to the wrong command. - while(packedCommands && geomCommand(packedCommands)) { - numArgs = 0; - packedCommands >>= 8; - } - if(commandBufIrq) - arm9.interrupt.flags |= CPUCore::irqGeomBuf; -} - -void GPU::sendGeomImmediate(uint8 command, uint32 data) { - while(sceneFinished) { - arm9.step(16); - if(arm7.clock < -255) - co_switch(arm7.thread); - } - args[numArgs++] = data; - if(geomCommand(command)) { - numArgs = 0; - } - if(commandBufIrq) - arm9.interrupt.flags |= CPUCore::irqGeomBuf; -} - -bool GPU::geomCommand(uint8 command) { - switch(command) { - case 0x10: return gxMatrixMode(); - case 0x11: return gxMatrixPush(); - case 0x12: return gxMatrixPop(); - case 0x13: return gxMatrixStore(); - case 0x14: return gxMatrixRestore(); - case 0x15: return gxMatrixLoadIdentity(); - case 0x16: return gxMatrixLoad4x4(); - case 0x17: return gxMatrixLoad4x3(); - case 0x18: return gxMatrixMult4x4(); - case 0x19: return gxMatrixMult4x3(); - case 0x1a: return gxMatrixRotate(); - case 0x1b: return gxMatrixScale(); - case 0x1c: return gxMatrixTranslate(); - - case 0x20: return gxColor(); - case 0x21: return gxNormal(); - case 0x22: return gxTexCoord(); - case 0x23: return gxVertex3i_16(); - case 0x24: return gxVertex3i_10(); - case 0x25: return gxVertex2i_XY(); - case 0x26: return gxVertex2i_XZ(); - case 0x27: return gxVertex2i_YZ(); - case 0x28: return gxVertex3i_Rel(); - case 0x29: return gxAttribute(); - case 0x2a: return gxTexImage(); - case 0x2b: return gxTexPalette(); - - case 0x30: return gxLightDiffuseAmbient(); - case 0x31: return gxLightSpecularEmission(); - case 0x32: return gxLightDirection(); - case 0x33: return gxLightColor(); - case 0x34: return gxLightShininess(); - - case 0x40: return gxBeginPrimitive(); - case 0x50: return gxSwapBuffers(); - case 0x60: return gxViewport(); - - case 0x70: return gxCullTest(); - case 0x71: return gxPositionTest(); - case 0x72: return gxDirectionTest(); - } - return true; -} - - -#include "math.cpp" -#include "commands.cpp" -#include "geometry.cpp" -#include "render.cpp" -#include "textures.cpp" - -} diff --git a/bsnes/nds/gpu/gpu.hpp b/bsnes/nds/gpu/gpu.hpp deleted file mode 100644 index cdaa59f4..00000000 --- a/bsnes/nds/gpu/gpu.hpp +++ /dev/null @@ -1,77 +0,0 @@ - -struct GPU { - GPU(); - - void power(); - void scanline(); - void swapBuffers(); - - void sendGeomBuffered(uint32 data); - void sendGeomImmediate(uint8 command, uint32 data); - bool geomCommand(uint8 command); - - // Once the geometry submitted by the program gets through transform, - // lighting, culling, and clipping, we've built a SceneList with: - struct Vertex { - // A single point within a primitive. - int64 x, y, z; // normalized device coordinates (xyz/w => -1..+1) - int32 u, v; // texture coordinates (u/w, v/w) - int32 r, g, b; // color (r/w, g/w, b/w) - int32 w; // - }; - struct Prim { - // A strip of triangles or quads - or a single, clipped n-gon. - // AFAIK, none of these attributes can change between primitives. - uint16 firstVert, numVerts; - uint8 minY, maxY; - uint1 blend, wire; - uint8 drawMode; enum { shadeMask=0x03, normal=0, decal=1, toon=2, stencil=3, - poly=0, triStrip=0x04, quadStrip=0x08, - colorKey=0x10, zequal=0x20, zwrite=0x40, fog=0x80 }; - uint8 id, alpha; - uint8 texFormat; enum { untextured, A3_I5, I2,I4,I8, packed, A5_I3, A1_RGB15 }; - uint8 texBorder[2]; enum { clamp=0, repeat=1, clamp_=4, mirror=5 }; - uint8 texSize[2]; // 8 << texSize - - uint16 texPalette; - uint32 texImage; - }; - - struct SceneList { - unsigned numVerts; - unsigned numPrims; - unsigned firstAlpha; - - Vertex verts[6144]; - Prim prims[2048]; - uint16 order[2048]; // by solid first, top Y, bottom Y, then index - - uint1 alphaSort; // Sort transparent geometry by Y coordinate? - uint1 depthUseW; // Use Z or W for depth buffering? - }; - - uint1 powered; - uint2 swapArgument; - SceneList sceneList[2]; - SceneList *uploadList; - SceneList *renderList; - - bool sceneFinished; - uint2 commandBufIrq; - int32 renderedLines; - uint32 packedCommands; - uint32 args[32], numArgs; - - uint32 output[256*192]; // ARGB5666 - - struct Matrix; - struct Vector; - struct ClipSpaceVertex; - - #include "math.hpp" - #include "commands.hpp" - #include "geometry.hpp" - #include "render.hpp" -}; - -extern GPU gpu; diff --git a/bsnes/nds/gpu/math.cpp b/bsnes/nds/gpu/math.cpp deleted file mode 100644 index c44d9629..00000000 --- a/bsnes/nds/gpu/math.cpp +++ /dev/null @@ -1,143 +0,0 @@ - -// Flips a 4x4 matrix along the diagonal: -// |a b c d| |a e i m| -// |e f g h| -> |b f j n| -// |i j k l| |c g k o| -// |m n o p| |d h l p| -void GPU::Matrix::transpose() { - auto &m = *this; - std::swap(m(0,1), m(1,0)); - std::swap(m(0,2), m(2,0)); - std::swap(m(0,3), m(3,0)); - std::swap(m(1,2), m(2,1)); - std::swap(m(1,3), m(3,1)); - std::swap(m(2,3), m(3,2)); -} - -// Product of two matrices: M := M * T. -void GPU::transform(Matrix& m, Matrix t) { - t.transpose(); - for(unsigned i = 0; i < 4; i++) - transform(t, m(i)); -} - -// Product of 4x4 matrix and 4D vector: v := T * v. -void GPU::transform(const Matrix& t, int32* v) { - int32 vector[] = { v[0], v[1], v[2], v[3] }; - for(unsigned i = 0; i < 4; i++) - v[i] = dot(t(i), vector); -} - -// Dot product of two 4D vectors: s := a . b. -int32 GPU::dot(const int32* a, const int32* b) { - return ( (int64) a[0] * b[0] - + (int64) a[1] * b[1] - + (int64) a[2] * b[2] - + (int64) a[3] * b[3] ) - / 0x1000; -} - -// Given a 4D homogenous coordinate, returns a mask telling whether -// it's out of bounds. One bit per side of the clipping volume. -unsigned GPU::outcode(const ClipSpaceVertex &v) { - const int32 &x = v.position[0], &y = v.position[1]; - const int32 &z = v.position[2], &w = v.position[3]; - - unsigned code = 0; - if(x < -w) code += 1; if(x > +w) code += 2; // left, right - if(y < -w) code += 4; if(y > +w) code += 8; // bottom, top - if(z < -w) code += 16; if(z > +w) code += 32; // near, far - return code; -} - -// Looks at three triangle vertices and returns a signed value: -// negative (back face), zero (edge on), or positive (front face). -// -// AKA sign of Z from the cross product (v1-v0) x (v2-v1) in screen coordinates: -// Z = (v1-v0).x (v2-v1).y - (v1-v0).y (v2-v1).x -int GPU::facing(const ClipSpaceVertex &v0, const ClipSpaceVertex &v1, const ClipSpaceVertex &v2) { - // These are in homogenous space, so.. that's more like: - // Z = a + b - c, where - // a = (v0.x v1.y - v0.y v1.x) / (v0.w v1.w) - // b = (v1.x v2.y - v1.y v2.x) / (v1.w v2.w) - // c = (v0.x v2.y - v0.y v2.x) / (v0.w v2.w) - // - // Since only the sign matters, - // S = (a+b-c <=> 0) = (a+b <=> c) - // - // and knowing w is positive within the clipping volume, - // p = v0.w v1.w v2.w - // a' = a*p, b' = b*p, c' = c*p - // - // that makes the divisions disappear. - // x y y x w - int64 a = ((int64) v0.position[0]*v1.position[1] - (int64) v0.position[1]*v1.position[0]) / 0x1000 * v2.position[3]; - int64 b = ((int64) v1.position[0]*v2.position[1] - (int64) v1.position[1]*v2.position[0]) / 0x1000 * v0.position[3]; - int64 c = ((int64) v0.position[0]*v2.position[1] - (int64) v0.position[1]*v2.position[0]) / 0x1000 * v1.position[3]; - - int64 r = a + b - c; - return r<0? -1 : r>0? +1 : 0; -} - -// a is inside the clipping plane -// b is outside, and will be clipped to the -// intersection between AB and the clip plane. -// axis controls which of X,Y,Z is tested. -// side affects the sign of the W comparand. -GPU::ClipSpaceVertex GPU::clipEdge(const ClipSpaceVertex &a, const ClipSpaceVertex &b, unsigned axis, int side) { - // Normally, to find the intersection we would attempt to find the fraction - // of the edge that remains unclipped: - // t = (1 - ax) / (bx - ax) - // - // The problem is that we haven't divided by W. We end up with this mess: - // t = (1 - ax/aw) / (bx/bw - ax/aw) - // - // Not very helpful. Besides which we still need W for perspective-correct - // texturing. - // - // In homogenous space, the clipping volume is defined by: - // -w < {x,y,z} < +w - // - // So we expect the clipped vertex c to have: - // cx = +/-cw ; cx,cy,cz depending on the plane - // - // And for each {x,y,z,w}: - // cx = ax + t*(bx - ax) - // - // Expanding both sides of the first equation: - // ax + t*(bx - ax) = aw + t*(bw - aw) - // t*(bx - ax) - t*(bw - aw) = aw - ax - // t = (aw - ax) / ((bx - ax) - (bw - aw)) - // - // We end up with these two equations: - // t = (+aw - ax) / ((+aw - ax) - (+bw - bx)) ; cx=+cw - // t = (-aw - ax) / ((-aw - ax) - (-bw - bx)) ; cx=-cw - // - // or more simply: - // t = (ax - +aw) / ((ax - +aw) - (bx - +bw)) ; cx=+cw - // t = (ax - -aw) / ((ax - -aw) - (bx - -bw)) ; cx=-cw - // - // t = (ax +/- aw) / ((ax +/- aw) - (bx +/- bw)) - // - // So clipping requires one division per edge that crosses a clipping plane. - // Quite pleasant, actually. - ClipSpaceVertex c; - int32 ax_aw = a.position[axis] - side*a.position[3]; - int32 bx_bw = b.position[axis] - side*b.position[3]; - - if(ax_aw - bx_bw) { - int64 t = 0x40000000ll * ax_aw / (ax_aw - bx_bw); - - // t should be between 0 and 1. Rather than being a linear function of X/Y/Z - // it also includes W. But at this point it's just an interpolation. - for(unsigned n = 0; n < 4; n++) { - c.position[n] = a.position[n] + int64(b.position[n] - a.position[n]) * t/0x40000000; - c.texCoord[n] = a.texCoord[n] + int64(b.texCoord[n] - a.texCoord[n]) * t/0x40000000; - c.color[n] = a.color[n] + int64(b.color[n] - a.color[n] ) * t/0x40000000; - } - // Ensure vertex is exactly on the clipping plane, - // so we don't try and clip it again. - c.position[axis] = side*c.position[3]; - } - return c; -} diff --git a/bsnes/nds/gpu/math.hpp b/bsnes/nds/gpu/math.hpp deleted file mode 100644 index 74298f7e..00000000 --- a/bsnes/nds/gpu/math.hpp +++ /dev/null @@ -1,53 +0,0 @@ - - struct Vector { - int32 v[4]; - - Vector() { } - - Vector(const std::initializer_list& elems) { - unsigned n = 0; - for(auto i : elems) { - if(n == 4) break; - v[n++] = i; - } - } - inline int32& operator[](unsigned i) { return v[i]; } - inline const int32& operator[](unsigned i) const { return v[i]; } - inline operator int32*() { return v; } - }; - - struct Matrix { - int32 m[4*4]; - - Matrix() { } - - Matrix(const std::initializer_list& elems) { - unsigned n = 0; - for(auto i: elems) - if(n < 4*4) m[n++] = i; - } - - inline int32& operator[](unsigned i) { return m[i]; } - inline int32& operator()(unsigned i, unsigned j) { return m[4*i + j]; } - inline int32* operator()(unsigned i) { return &m[4*i]; } - - inline const int32& operator[](unsigned i) const { return m[i]; } - inline const int32& operator()(unsigned i, unsigned j) const { return m[4*i + j]; } - inline const int32* operator()(unsigned i) const { return &m[4*i]; } - - void transpose(); - }; - - struct ClipSpaceVertex { - Vector position; - Vector texCoord; - Vector color; - }; - - static void transform(Matrix& m, Matrix t); - static void transform(const Matrix& t, int32* v); - - static int32 dot(const int32* a, const int32* b); - static int facing(const ClipSpaceVertex &v0, const ClipSpaceVertex &v1, const ClipSpaceVertex &v2); - static unsigned outcode(const ClipSpaceVertex &v); - static ClipSpaceVertex clipEdge(const ClipSpaceVertex &b, const ClipSpaceVertex &a, unsigned axis, int side); diff --git a/bsnes/nds/gpu/render.cpp b/bsnes/nds/gpu/render.cpp deleted file mode 100644 index 8439329e..00000000 --- a/bsnes/nds/gpu/render.cpp +++ /dev/null @@ -1,578 +0,0 @@ - -void GPU::updateDrawList(int y, DrawList& list, bool sorted) { - // Blah, why are polys with numVerts==0 making it in? - - // Remove polygons that have finished rendering - while(list.first < list.last && (!list.polys[list.first].numVerts - || 192-list.polys[list.first].v[list.polys[list.first].numVerts-1]->y/0x400000 < y)) - list.first++; - - // Add primitives matching Y as their first line - unsigned pi = list.nextPrim; - while(pi < list.lastPrim) { - auto *prim = &renderList->prims[renderList->order[pi]]; - if(sorted && y < prim->minY-1) - break; - - if(!sorted || y == prim->minY-1) { - auto *v = &renderList->verts[prim->firstVert]; - - if(prim->drawMode & Prim::triStrip) { - for(unsigned n = 2; n < prim->numVerts; n += 1, v += 1) - setupPoly(list.polys[list.last++], prim, v, 3); - } - else if(prim->drawMode & Prim::quadStrip) { - for(unsigned n = 2; n < prim->numVerts; n += 2, v += 2) - setupPoly(list.polys[list.last++], prim, v, 4); - } - else { - setupPoly(list.polys[list.last++], prim, v, prim->numVerts); - } - - if(list.nextPrim == pi) - list.nextPrim++; - } - pi++; - } -} - -void GPU::setupPoly(ActivePoly& poly, Prim* prim, Vertex *vs, unsigned numVerts) { - for(unsigned n = 0; n < numVerts; n++) - poly.v[n] = &vs[n]; - - // Sort vertices by Y, then X if on same line - std::sort(poly.v, poly.v+numVerts, [](Vertex *a, Vertex *b) - { return a->y != b->y? a->y > b->y : a->x < b->x; }); - - poly.numVerts = numVerts; - if(!numVerts) return; - - poly.p = prim; - poly.lv = poly.next_lv = 0; // start at top vertex - poly.rv = poly.next_rv = 0; - poly.side[0] = 0; // top and bottom are - poly.side[numVerts-1] = 0; // considered to be on both sides. - - // Find out which side each vertex is on. This is based on the observation - // that with a convex polygon, edges always curve inwards, towards the other - // side. So we switch sides every time the curve changes direction. - for(int n = 1; n < numVerts-1; n++) { - int64 dx0 = poly.v[n]->x - poly.v[n-1]->x; - int64 dx1 = poly.v[n+1]->x - poly.v[n]->x; - int64 dy0 = -(poly.v[n]->y - poly.v[n-1]->y); - int64 dy1 = -(poly.v[n+1]->y - poly.v[n]->y); - - poly.side[n] = poly.side[n-1]; // special case for straight or co-linear edges - - if(!dy0) dy0 = 1; - if(!dy1) dy1 = 1; - - // compare dx1/dy1 <=> dx0/dy0 - // - both sides have been multiplied by dy0*dy1 to avoid division by 0 - if(dx1*dy0 > dx0*dy1) poly.side[n] = -1; // curves to the right, so must be on the left - if(dx1*dy0 < dx0*dy1) poly.side[n] = +1; // curves to the left, so must be on the right - } - setupNextEdge(poly, poly.lv, poly.next_lv, -1, poly.lnext, poly.dl_dv); - setupNextEdge(poly, poly.rv, poly.next_rv, +1, poly.rnext, poly.dr_dv); - - poly.prev_lx = poly.lnext.x; - poly.prev_rx = poly.rnext.x; -} - -void GPU::setupNextEdge(ActivePoly& poly, unsigned& vi, unsigned& next, - int side, Interpolants& edge, Interpolants& gradient) -{ - vi = next++; - while(poly.side[next]*side < 0) - next++; - - Interpolants endpoint; - assignEdge(edge, poly.v[vi]); edge.x &= ~0x3fffff; - assignEdge(endpoint, poly.v[next]); endpoint.x &= ~0x3fffff; - - int32 y0 = 192 - poly.v[vi]->y/0x400000; - int32 y1 = 192 - poly.v[next]->y/0x400000; - int32 numLines = y1 - y0; - if(numLines) { - for(unsigned j = 0; j < Interpolants::count; j++) - gradient[j] = (endpoint[j] - edge[j]) / numLines; - } -} - -void GPU::assignEdge(Interpolants& edge, Vertex* v) { - edge.r = v->r; edge.u = v->u; - edge.g = v->g; edge.v = v->v; - edge.b = v->b; edge.z = v->z; - - edge.inv_w = 0x80000000000/max(1,v->w); - edge.x = v->x; -} - - - -void GPU::renderScanline() { - int y = renderedLines; - auto *line = 1 + pixels[y-0 & 3]; - auto *line1 = 1 + pixels[y-1 & 3]; - auto *line2 = 1 + pixels[y-2 & 3]; - - updateDrawList(y, drawList[0], true); - updateDrawList(y, drawList[1], renderList->alphaSort); - - unsigned backOffs = 0x40000 + 512*(backY+y & 0xff); - uint16 *backImageColor = &system.vmap.tex[backOffs+0x00000 >> 14][backOffs+0x00000]; - uint16 *backImageDepth = &system.vmap.tex[backOffs+0x20000 >> 14][backOffs+0x20000]; - - for(int x = -1; x <= 256; x++) { - auto &px = line[x]; - uint16 color = backImageColor[backX+x & 0xff]; - uint16 depth = backImageDepth[backX+x & 0xff]; - - // Stencil is preserved, even between frames! - // Transitioning to stencilMode=1 is what clears it. - px.flags &= Pixel::stencil; - px.flags &= ~Pixel::blends; - - if(renderControl.backImage) { - px.a.r = color<<1 & 62; px.a.r += px.a.r > 0; - px.a.g = color>>4 & 62; px.a.g += px.a.g > 0; - px.a.b = color>>9 & 62; px.a.b += px.a.b > 0; - px.a.a = color>>15? 31 : 0; - px.a.id = backId; - px.az = depth<<16 & 0x7fff0000; - - if(depth & 1<<15) px.flags |= Pixel::fog; - } - else { - px.a.r = backColor[0]; - px.a.g = backColor[1]; - px.a.b = backColor[2]; - px.a.a = backAlpha; - px.a.id = backId; - px.az = backZ<<16; - - if(backFog) px.flags |= Pixel::fog; - } - - px.b.a = 0; - px.b.id = 0xff; - px.bz = 0x7fffffff; - px.sz = 0x7fffffff; - } - - renderDrawList(y, drawList[0], false); - renderDrawList(y, drawList[1], true); - if(y < 1) return; - - y--; // edge filter requires 1 line latency - - int32 fogZ = this->fogZ << 16; - uint32 *__restrict dest = &output[256*y]; - - for(int x = 0; x < 256; x++) { - // Any remaining fragments are combined here... or maybe this should - // be done between solid/alpha passes? I'm not sure if you can get a - // transparent pixel between a solid and a smooth edge, and still have - // it look right. - auto &px = line1[x]; - auto &above = px.a; - auto &below = px.b; - uint8 r = above.r; - uint8 g = above.g; - uint8 b = above.b; - uint8 a = above.a; - uint8 id = above.id; - int64 z = px.az; - - if(px.flags & Pixel::edge) { - auto &up = line2[x]; - auto &left = line1[x-1], &right = line1[x+1]; - auto &down = line[x]; - - // Toon edge filter - need to verify logic here, might be &&, etc. - if( z < up.az && id != up.a.id || z < down.az && id != down.a.id - || z < left.az && id != left.a.id || z < right.az && id != right.a.id - ) { - Vector outline = edgeTable[id/8]; - - if(renderControl.edgeMode & RC::toon) { - // Replace RGB with values from the table. - // Is there an option to disable this for some polygons? - r = outline[0] / 0x1000; - g = outline[1] / 0x1000; - b = outline[2] / 0x1000; - - // In this case, alpha is also overwritten. Edges that don't - // pass the filter remain antialiased, as in "smooth" mode. - if(renderControl.edgeMode == RC::blended) - a = 16; // fixed value - or is there a register? - } - } - } - - if(below.a /*not empty*/) { - if(below.id == id && a < 31 && (px.flags & Pixel::blends)) { - // Don't blend equal object IDs - r = below.r; - g = below.g; - b = below.b; - a = below.a; - } - else if(renderControl.alphaBlend || !(px.flags & Pixel::blends)) { - // Z blends, too! You can see this if you set fogAlpha=0 - // with edge smoothing on. - z = px.bz + (z - px.bz) * (a+1) / 32u; - - // They cheaped out here. To get correct Photoshop-style alpha - // (non pre-multiplied) requires dividing by A. It's nasty. - r = below.r + (r - below.r) * (a+1) / 32u; - g = below.g + (g - below.g) * (a+1) / 32u; - b = below.b + (b - below.b) * (a+1) / 32u; - a = max(a, below.a); - } - } - - // Polygons can be fogged toward a constant RGBA, or optionally just - // their alpha channel. Unlike most systems, this is a per-pixel effect - // based on the Z buffer. - if(px.flags & Pixel::fog) { - // Z := 0..0x7fffffff - int32 dist = z-fogZ >> 16-renderControl.fogLevel; - dist = max(0, min(0x7fff, dist)); - - int32 ifog = fogTable[dist/0x400u]; - ifog += (fogTable[dist/0x400u + 1] - ifog) * (dist & 0x3ff)/0x400u; - - if(renderControl.fogMode == RC::color) { - r += (fogColor[0] - r) * (ifog+1)/0x80u; - g += (fogColor[1] - g) * (ifog+1)/0x80u; - b += (fogColor[2] - b) * (ifog+1)/0x80u; - } - a += (fogAlpha - a) * (ifog+1)/0x80u; - } - *dest++ = a<<18 | b<<12 | g<<6 | r<<0; - } -} - -void GPU::renderDrawList(int y, DrawList& list, bool blend) { - auto *line = 1 + pixels[y & 3]; - - unsigned alphaTest = minAlpha * renderControl.alphaTest; - - for(unsigned n = list.first; n < list.last; n++) { - auto &poly = list.polys[n]; - if(!poly.numVerts) continue; - - int y0 = 192-poly.v[0]->y/0x400000; - int y1 = 192-poly.v[poly.numVerts-1]->y/0x400000; - - if(y < y0-1 || y >= y1) continue; - - while(y == 192-poly.v[poly.next_lv]->y/0x400000-1 && poly.next_lv < poly.numVerts-1) - setupNextEdge(poly, poly.lv, poly.next_lv, -1, poly.lnext, poly.dl_dv); - - while(y == 192-poly.v[poly.next_rv]->y/0x400000-1 && poly.next_rv < poly.numVerts-1) - setupNextEdge(poly, poly.rv, poly.next_rv, +1, poly.rnext, poly.dr_dv); - - // X range for previous, current, and next line - // We need this to determine "edge" cases (sorry) -> - int px0 = poly.prev_lx / 0x400000; // Top: x in x0..prev_x0 - int px1 = poly.prev_rx / 0x400000; // or prev_x1..x1 - int x0 = poly.left.x / 0x400000; // Bottom: x in x0..next_x0 - int x1 = poly.right.x / 0x400000; // or next_x1..x1 - int nx0 = poly.lnext.x / 0x400000; // Left: x+0 == x0 - int nx1 = poly.rnext.x / 0x400000; // Right: x+1 == x1 - - // Theory: - // A pixel is marked "edge" on one of the above conditions. Translucent - // (alpha < 31) polygons do not modify the edge flags. Smooth edges have - // their alpha set to the fraction of pixel covered. - - // Test for dropout - DS doesn't have explicit line or point primitives; - // to draw them, you simply use geometry thinner than 1px. The rasterizer - // ALMOST never leaves holes.. even in extremely narrow triangles. Very - // occasionally, degenerate triangles will have gaps. - if(x0 > px1) x0 = px1; - if(x1 < px0) x1 = px0; - if(x1 <= x0) x1 = x0; - - if(y >= y0) { - Texture *tex = nullptr; - if(renderControl.texturing) - tex = getTexture(poly.p->texImage, poly.p->texPalette); - - Interpolants i = poly.left; // RGB, UVZW at current pixel - Interpolants delta; // Gradient from left to right edges - - if(x1 > x0) - for(unsigned j = 0; j < Interpolants::count; j++) - delta[j] = (poly.left[j] - poly.right[j]) / (x0-x1); - - uint8 id = poly.p->id; - int drawMode = poly.p->drawMode; - int shadeMode = drawMode & Prim::shadeMask; - - if(!renderControl.fogMode) - drawMode &= ~Prim::fog; - - if((drawMode & Prim::shadeMask) == Prim::stencil) { - if(id) { - stencilMode = false; // Draw to screen, using stencil bits as mask. - } - else if(stencilMode == false) { - stencilMode = true; // Draw to stencil buffer. - - // Toggling into stencil mode with ID=0 was observed to clear the - // stencil buffer. This IS affected by polygon sorting so it will - // not happen on every line, or even every frame, unless so arranged! - // - // The buffer holds data for only 2 lines, and if not cleared, then - // old data is used. So shadow volumes must be closed to work. - for(unsigned x = 0; x < 256; x++) - line[x].flags &= ~Pixel::stencil; - } - } - - if(i.inv_w < 0x2000) i.inv_w = 0x2000; - - // Hrm. Too many variables here, this should be split up. Perhaps: - // pass 1: calculate edge coverage (a==31 only) - // pass 2: if z <= bz, calculate [argbf]z (modulate, decal, toon, stencil) - // pass 3: do atest, ztest (less, equal), merge with line buffer (a==31, a<31)? - - for(unsigned x = x0; x <= x1; x++) { - int32 w = 0x80000000000ll / max(2ll, i.inv_w); - int32 z = i.z + 0x40000000; // z/w - - // Should find some way to justify this - <<7 was Selected for - // suitable fog in Mario Kart's Chocolate Mountain course.. - if(renderList->depthUseW) - z = w<<7; - - // Unproject the interpolated values - int32 u = ((int64) i.u * w)/0x40000000; - int32 v = ((int64) i.v * w)/0x40000000; - - Vector color = { - min(63, (int64) i.r * w/0x4000000), - min(63, (int64) i.g * w/0x4000000), - min(63, (int64) i.b * w/0x4000000), - poly.p->alpha - }; - - i.u += delta.u; i.r += delta.r; - i.v += delta.v; i.g += delta.g; - i.z += delta.z; i.b += delta.b; - i.inv_w += delta.inv_w; - - bool edge = false; - - if(blend == false) { - edge = x0 <= x && (x <= px0 || x <= nx0) - || (px1 <= x || nx1 <= x) && x <= x1 - || x == x0 || x == x1; - - if(renderControl.edgeMode & RC::smooth) { - if(x == x0) color[3] = 31-(poly.left.x>>17 & 31); - if(x == x1) color[3] = (poly.right.x>>17 & 31); - } - } - - Vector texColor = { 63, 63, 63, 31 }; - if(tex) { - u = max(0, min(tex->width-1, u & tex->umask)); - v = max(0, min(tex->height-1, v & tex->vmask)); - - uint32 abgr = tex->image[tex->width*v + u]; - texColor[0] = 2*(abgr>> 0 & 31) + 1; - texColor[1] = 2*(abgr>> 5 & 31) + 1; - texColor[2] = 2*(abgr>>10 & 31) + 1; - texColor[3] = (abgr>>15); - } - - auto &px = line[x]; - auto &above = px.a; - auto &below = px.b; - bool ztest_a = drawMode & Prim::zequal? z == px.az : z < px.az; - bool ztest_b = drawMode & Prim::zequal? z == px.bz : z < px.bz; - - if(shadeMode == Prim::stencil) { - if(stencilMode) { - // Draw to stencil buffer, not the screen - // Does texturing work here? Alpha, maybe? - if(ztest_a == false) { - px.flags |= Pixel::stencil; - px.sz = px.az; - } - continue; - } - // Mask polygons using the stencil buffer - if(px.flags & Pixel::stencil) { - // Succeeded - force Z onto the fragment being shadowed - z = px.sz; - if(id == above.id) { - // FF IV surrounds characters in shadow volumes, and uses the ID - // to prevent self-shadowing. So technically this fragment is on - // top, yet the DS somehow draws it underneath the model. If not - // done this way, edge smoothing would clash with the shadow. - ztest_a = false; - ztest_b = true; - z = px.bz; - } - } else { - // Failed stencil test - continue; - } - } - - if(shadeMode == Prim::toon) { - // Look up shade based on the red channel - int a = color[3]; - color = toonTable[renderControl.toonShading][color[0]/2 & 31]; - color[0] /= 0x1000u; - color[1] /= 0x1000u; - color[2] /= 0x1000u; - color[3] = a; - } - - if(shadeMode == Prim::decal) { - color[0] += (texColor[0] - color[0]) * (texColor[3]+1) / 32u; - color[1] += (texColor[1] - color[1]) * (texColor[3]+1) / 32u; - color[2] += (texColor[2] - color[2]) * (texColor[3]+1) / 32u; - } else { - color[0] = color[0] * texColor[0] / 64u; - color[1] = color[1] * texColor[1] / 64u; - color[2] = color[2] * texColor[2] / 64u; - color[3] = (1 + color[3]) * texColor[3] / 32u; - } - - if(color[3] <= renderControl.alphaTest) - continue; - - if(blend) { - if(ztest_a) { - if(above.id == id) continue; - - if(!renderControl.alphaBlend) { - // Mario Kart uses this on the car selection screen. The alpha - // and coverage are still retained and used for PPU blending. - above.r = color[0]; - above.g = color[1]; - above.b = color[2]; - above.a = max(color[3], px.a.a); - above.id = id; - - if(!(drawMode & Prim::fog)) px.flags &= ~Pixel::fog; - if(drawMode & Prim::zwrite) px.az = z; - continue; - } - - if(below.a /*not empty*/) { - if(below.id != above.id || color[3] == 31 || !(px.flags & Pixel::blends)) { - // Merge the top pixel down to make room - px.bz += int64(px.az - px.bz) * (above.a + 1)/32u; - - below.r += (above.r - below.r) * (above.a + 1)/32u; - below.g += (above.g - below.g) * (above.a + 1)/32u; - below.b += (above.b - below.b) * (above.a + 1)/32u; - below.a = max(above.a, below.a); - below.id = above.id; - } - } else { - // Bottom empty or top solid, simply push down - below = above; - px.bz = px.az; - } - // Then write the top one - above.r = color[0]; - above.g = color[1]; - above.b = color[2]; - above.a = color[3]; - above.id = id; - - // AND with previous fog bit - if(!(drawMode & Prim::fog)) px.flags &= ~Pixel::fog; - if(drawMode & Prim::zwrite) px.az = z; - - px.flags |= Pixel::blends; - } - else if(ztest_b) { - if(below.a /*not empty*/) { - if(below.id == id && color[3] < 31) continue; - - if(!renderControl.alphaBlend) { - if(drawMode & Prim::zwrite) - px.bz = z; - - below.r = color[0]; - below.g = color[1]; - below.b = color[2]; - } - else { - // Blend into bottom pixel - if(drawMode & Prim::zwrite) - px.bz += int64(z - px.bz) * (color[3] + 1)/32u; - - below.r += (color[0] - below.r) * (color[3] + 1)/32u; - below.g += (color[1] - below.g) * (color[3] + 1)/32u; - below.b += (color[2] - below.b) * (color[3] + 1)/32u; - } - below.a = max(color[3], below.a); - below.id = id; - } else { - // Bottom empty, simply replace - if(drawMode & Prim::zwrite) - px.bz = z; - - below.r = color[0]; - below.g = color[1]; - below.b = color[2]; - below.a = color[3]; - below.id = id; - } - } - continue; - } - - if(ztest_a) { - if(drawMode & Prim::fog) px.flags |= Pixel::fog; - else px.flags &= ~Pixel::fog; - - // Push the top pixel down. Anything beneath is lost. - // Check first to avoid breaking backAlpha == 0. - if(above.a /*not empty*/) { - px.bz = px.az; - below = above; - below.a = 31; - } - above.r = color[0]; - above.g = color[1]; - above.b = color[2]; - above.a = color[3]; - above.id = id; - px.az = z; - - if(edge) px.flags |= Pixel::edge; - else px.flags &= ~Pixel::edge; - } - else if(ztest_b) { - below.r = color[0]; - below.g = color[1]; - below.b = color[2]; - below.a = 31; - below.id = id; - px.bz = z; - } - } - poly.prev_lx = poly.left.x; - poly.prev_rx = poly.right.x; - } - poly.left = poly.lnext; - poly.right = poly.rnext; - - for(unsigned j = 0; j < Interpolants::count; j++) { - poly.lnext[j] += poly.dl_dv[j]; - poly.rnext[j] += poly.dr_dv[j]; - } - } -} diff --git a/bsnes/nds/gpu/render.hpp b/bsnes/nds/gpu/render.hpp deleted file mode 100644 index 77e56562..00000000 --- a/bsnes/nds/gpu/render.hpp +++ /dev/null @@ -1,163 +0,0 @@ - - struct ActivePoly; - union Interpolants; - struct DrawList; - - void updateDrawList(int y, DrawList& list, bool sorted); - void setupPoly(ActivePoly& poly, Prim* prim, Vertex *vs, unsigned numVerts); - void setupNextEdge(ActivePoly& poly, unsigned& vi, unsigned& next, int side, Interpolants& edge, Interpolants& gradient); - void assignEdge(Interpolants& edge, Vertex* v); - - void renderScanline(); - void renderDrawList(int y, DrawList& list, bool blend); - - uint32 regRenderOptions(); - uint32 regRenderLoad(); - - void regRenderOptions(uint32 data, uint32 mask); - void regRenderMinAlpha(uint32 data, uint32 mask); - void regRenderClearColor(uint32 data, uint32 mask); - void regRenderClearCoord(uint32 data, uint32 mask); - void regRenderFogColor(uint32 data, uint32 mask); - void regRenderFogCoord(uint32 data, uint32 mask); - void regRenderFogTable(unsigned index, uint32 data, uint32 mask); - void regRenderEdgeTable(unsigned index, uint32 data, uint32 mask); - void regRenderToonTable(unsigned index, uint32 data, uint32 mask); - - struct Texture { - // Lookup data - 44 significant bits - uint64 key; // paladdr<<32 | format<<16 | texaddr<<0 - uint32 imageBase, indexBase, colorBase; - - // Mirrored textures: clamp at 2*size, wrap at 2*size, cache all 4 mirrors - // Repeating textures: clamp dt 1*size, wrap at 1*size - // Clamped textures: clamp at 1*size, wrap at UINT_MAX - int32 width, height; - int32 umask, vmask; - uint32 *image; - - // Address ranges for dirty checks - uint32 texelRange[2]; // pixel data - uint32 indexRange[2]; // for compressed format - uint32 colorRange[2]; // for paletted formats - - ~Texture() { delete[] image; } - Texture(uint64 key, int width, int height) : key(key), - width(width), height(height), umask(~0), vmask(~0), image(nullptr) {} - }; - - struct TexCache { - void reset(); - void flushDirty(unsigned bank); - bool checkDirty(Texture *texture, uint32 *range, VRAMMapping *map, uint32 mask); - - void add(Texture *t); - Texture *get(uint64 key); - - enum { tableSize = 1<<10 }; - vector table[tableSize]; - int size; - } texCache; - - Texture *getTexture(uint32 texImage, uint16 texPalette); - void mirrorTexture(Texture *tex, int width, int height); - void convertPacked(Texture *tex, int width, int height); - void convertI2(Texture *tex, int width, int height, bool colorKey); - void convertI3(Texture *tex, int width, int height); - void convertI4(Texture *tex, int width, int height, bool colorKey); - void convertI5(Texture *tex, int width, int height); - void convertI8(Texture *tex, int width, int height, bool colorKey); - void convertARGB(Texture *tex, int width, int height); - - - union Interpolants { - int64& operator[](unsigned i) { return val[i]; } - - int64 val[8]; enum { count=8 }; - struct { - int64 r, g, b, u, v, z, inv_w, x; - }; - }; - - struct ActivePoly { - Prim *p; - uint8 numVerts; - int8 side[8]; // is vertex on left or right? - Vertex *v[8]; - Interpolants left, right; // current values at l, r - Interpolants lnext, rnext; - Interpolants dl_dv, dr_dv; // gradient down each side - unsigned lv, rv; // index of current vertex - unsigned next_lv, next_rv; // index of next vertex - int32 prev_lx, prev_rx; // x span on previous line - }; - - struct Pixel { - // Z for depth sorting. We need two layers (!) to make edge smoothing - // independent of draw order. It also saves the trouble of blending every - // pixel drawn - the worst case is a single pass at the end. - int32 az, bz; // at least 24 bits? 15 bit had too much Z fighting :/ - int32 sz; // shadow buffer z - struct { - uint8 r, g, b; // 6 bits - uint8 a; // 5 bits - - // Object ID is a kludge Nintendo came up with to deal with edge fill. - // They chose to make all polygon edges overlap, so their antialiasing - // looks right. However, this means translucent edge pixels would be - // drawn twice. The object ID is used to suppress that. - uint8 id; - } a, b; - - // Some miscellaneous bits, only one layer here. - // There have been comments to the effect that multiple stencil bits are - // needed, but I don't think that's true - shadow volumes are drawn one - // at a time with the stencil cleared in-between, and the object ID - // prevents shadows blending more than once per pixel per light. - uint8 flags; enum { - fog = 1<<7, // apply post pass Z-based fogging - edge = 1<<6, // apply post pass toon edge filter - stencil = 1<<5, // pixels can be drawn here in stencil mode - blends = 1<<4, // if true, treat a as alpha; else as coverage - }; - }; - - struct RC { - uint1 texturing; - uint1 toonShading; enum { darken, lighten }; - uint2 edgeMode; enum { solid, smooth, toon, blended }; - uint2 fogMode; enum { color=2, alpha=3 }; - uint4 fogLevel; - uint1 alphaTest; - uint1 alphaBlend; - uint1 backImage; - } renderControl; - - struct DrawList { - unsigned first, last; - unsigned nextPrim, lastPrim; - ActivePoly polys[6144]; - } drawList[2]; // 2 passes - solid and translucent - - uint5 minAlpha; - - uint6 backColor[3]; - uint5 backAlpha; - uint6 backId; - uint8 backX, backY; - uint15 backZ; - uint1 backFog; - - int8 fogTable[32+1]; - uint6 fogColor[3]; - uint5 fogAlpha; - int16 fogZ; - - bool stencilMode; - - Vector toonTable[2][32]; - Vector edgeTable[8]; - - // Need two buffers here for edge transparency - // Need three for toon edges, argh. Will redo later. - Pixel pixels[4][256+2]; diff --git a/bsnes/nds/gpu/textures.cpp b/bsnes/nds/gpu/textures.cpp deleted file mode 100644 index c3bbbfea..00000000 --- a/bsnes/nds/gpu/textures.cpp +++ /dev/null @@ -1,304 +0,0 @@ - -void GPU::TexCache::reset() { - for(auto &bucket : table) { - for(auto &texture : bucket) - delete texture; - - bucket.reset(); - } - size = 0; -} - -bool GPU::TexCache::checkDirty(Texture *texture, uint32 *range, VRAMMapping* map, uint32 mask) { - uint32 addr = range[0] & ~255 & mask; - uint32 end = range[1] + 255 & ~255 & mask; - - for(; addr != end; addr = addr+256 & mask) - if(map[addr>>14].dirty(addr)) return true; - - return false; -} - -void GPU::TexCache::flushDirty(unsigned bank) { - // Called whenever VRAM is (re-)assigned as texture memory - // (ie. the game finished uploading and has locked it). - bool palMem = bank >= 4; - - for(auto &bucket : table) { - for(auto &texture : bucket) { - if(!(!palMem && checkDirty(texture, texture->texelRange, system.vmap.tex, 0x7ffff) - || !palMem && checkDirty(texture, texture->indexRange, system.vmap.tex, 0x7ffff) - || palMem && checkDirty(texture, texture->colorRange, system.vmap.texpal, 0x1ffff) )) - continue; - - delete texture; - texture = nullptr; - } - // Flush all the nullptrs at once to avoid O(n^2) removal. - unsigned count = 0; - for(unsigned n = 0; n < bucket.size(); n++) { - if(bucket[n]) bucket[count++] = bucket[n]; - } - bucket.resize(count); - } -} - - -void GPU::TexCache::add(Texture *t) { - uint10 hash = t->key ^ t->key>>10 ^ t->key>>20 ^ t->key>>30; - table[hash].append(t); - size++; -} - -GPU::Texture* GPU::TexCache::get(uint64 key) { - uint10 hash = key ^ key>>10 ^ key>>20 ^ key>>30; - - for(auto texture : table[hash]) { - if(texture->key == key) - return texture; - } - return nullptr; -} - - - -GPU::Texture *GPU::getTexture(uint32 texImage, uint16 texPalette) { - //texCache.reset(); - - uint64 key = (uint64) texImage ^ (uint64)texPalette<<30; - Texture *tex = texCache.get(key); - - if(!tex) { - int format = texImage>>26 & 7; - if(!format) return nullptr; - - bool colorKey = texImage & 1<<29; - unsigned uaxis = texImage>>16 & 5; - unsigned vaxis = texImage>>17 & 5; - unsigned imgwidth = 8 << (texImage>>20 & 7); - unsigned imgheight = 8 << (texImage>>23 & 7); - - tex = new Texture(key, imgwidth, imgheight); - - tex->colorBase = 8*(texPalette & 0x3fff); - tex->imageBase = 8*(texImage & 0xffff); - tex->indexBase = 0x20000 + (tex->imageBase/2 & 0xffff); - if(tex->imageBase >= 0x40000) - tex->indexBase += 0x10000; - - // Mirroring implies repeat as well. - if(uaxis == Prim::mirror) tex->width *= 2; - if(vaxis == Prim::mirror) tex->height *= 2; - if(uaxis & Prim::repeat) tex->umask = tex->width-1; - if(vaxis & Prim::repeat) tex->vmask = tex->height-1; - - tex->image = new uint32[tex->width * tex->height]; - tex->colorRange[0] = tex->colorRange[1] = tex->colorBase; - tex->texelRange[0] = tex->texelRange[1] = tex->imageBase; - tex->indexRange[0] = tex->indexRange[1] = tex->indexBase; - - switch(format) { - case Prim::packed: convertPacked(tex, imgwidth, imgheight); break; - case Prim::I2: convertI2(tex, imgwidth, imgheight, colorKey); break; - case Prim::A5_I3: convertI3(tex, imgwidth, imgheight); break; - case Prim::I4: convertI4(tex, imgwidth, imgheight, colorKey); break; - case Prim::A3_I5: convertI5(tex, imgwidth, imgheight); break; - case Prim::I8: convertI8(tex, imgwidth, imgheight, colorKey); break; - case Prim::A1_RGB15: convertARGB(tex, imgwidth, imgheight); break; - } - mirrorTexture(tex, imgwidth, imgheight); - texCache.add(tex); - } - return tex; -} - -void GPU::mirrorTexture(Texture *tex, int width, int height) { - for(int y = 0; y < height; y++) { - uint32 *row = &tex->image[tex->width*y]; - uint32 *mirror = &tex->image[tex->width*(tex->height-1 - y)]; - - if(tex->width > width) { - for(int x = 0; x < width; x++) - row[tex->width-1 - x] = row[x]; - } - if(tex->height > height) { - memcpy(mirror, row, tex->width*sizeof(*row)); - } - } -} - -void GPU::convertPacked(Texture *tex, int width, int height) { - uint32 taddr = tex->imageBase; - uint32 caddr = tex->indexBase; - - tex->texelRange[1] += (width/4)*(height/4)*4; - tex->indexRange[1] += (width/4)*(height/4)*2; - tex->colorRange[0] += 0x10000; - - for(unsigned v = 0; v < height; v += 4) { - uint32 *dest = &tex->image[tex->width*v]; - - for(unsigned u = 0; u < width; u += 4) { - // Retrieve 4x4 block = 16 pixels x 2bpp = 32 bits - auto &page = system.vmap.tex[taddr>>14 & 31]; - uint32 block = page[taddr] | page[taddr+2]<<16; - - // Retrieve color selection and mode bits - uint16 colorsel = system.vmap.tex[caddr>>14 & 31][caddr]; - uint32 paddr = tex->colorBase + (4*colorsel & 0xfffc); - uint32 fields = 31<<20 | 31<<10 | 31<<0; - uint32 gap = 15; // space apart to allow averaging - - // This could potentially span most of the palette space, but that would - // complicate the game's texture allocation, so rather unlikely. - tex->colorRange[0] = min(tex->colorRange[0], paddr+0); - tex->colorRange[1] = max(tex->colorRange[1], paddr+8); - - uint32 alpha[4] = { 31, 31, 31, 31 }; - - uint32 colors[4] = { - uint15(system.vmap.texpal[paddr+0 >> 14 & 31][paddr+0]) * (1<> 14 & 31][paddr+2]) * (1<> 14 & 31][paddr+4]) * (1<> 14 & 31][paddr+6]) * (1<> 14) { - case 3: // 2 colors (4-way mix) - colors[2] = (5*colors[0] + 3*colors[1])/8 & fields; - colors[3] = (3*colors[0] + 5*colors[1])/8 & fields; - case 2: // 4 colors (separate) - break; - - case 1: // 2 colors (3-way mix) + transparent - colors[2] = (4*colors[0] + 4*colors[1])/8 & fields; - case 0: // 3 colors (separate) + transarent - alpha[3] = 0; - break; - } - - for(int i = 0; i < 4; i++) { - colors[i] |= colors[i] >> gap; - colors[i] = alpha[i]<<15 | colors[i] & 0x7fff; - } - for(int sv = 0; sv < 4; sv++, dest += tex->width) { - for(int su = 0; su < 4; su++, block >>= 2) - dest[su] = colors[block & 3]; - } - dest += 4 - 4*tex->width; - taddr += 4; - caddr += 2; - } - } -} - -void GPU::convertI2(Texture *tex, int width, int height, bool colorKey) { - tex->texelRange[1] += width*height/4; - tex->colorRange[1] += 8; - - for(unsigned v = 0; v < height; v++) { - uint32 *dest = &tex->image[tex->width*v]; - uint32 taddr = tex->imageBase + width/4*v; - - for(unsigned u = 0; u < width; u++, taddr += !(u%4)) { - uint2 index = system.vmap.tex[taddr>>14 & 31][taddr] >> 2*(u&7); - uint32 paddr = tex->colorBase + 2*index; - uint16 bgr = system.vmap.texpal[paddr>>14 & 31][paddr]; - uint5 a = 31*(colorKey == false || index > 0); - - *dest++ = a<<15 | bgr; - } - } -} - -void GPU::convertI3(Texture *tex, int width, int height) { - tex->texelRange[1] += width*height/1; - tex->colorRange[1] += 16; - - for(unsigned v = 0; v < height; v++) { - uint32 *dest = &tex->image[tex->width*v]; - uint32 taddr = tex->imageBase + width*v; - - for(unsigned u = 0; u < width; u++, taddr++) { - uint8 index = system.vmap.tex[taddr>>14 & 31][taddr] >> 8*(u&1); - uint32 paddr = tex->colorBase + 2*(index & 0x07); - uint16 bgr = system.vmap.texpal[paddr>>14 & 31][paddr]; - uint5 a = index>>3; - - *dest++ = a<<15 | bgr; - } - } -} - -void GPU::convertI4(Texture *tex, int width, int height, bool colorKey) { - tex->texelRange[1] += width*height/2; - tex->colorRange[1] += 32; - - for(unsigned v = 0; v < height; v++) { - uint32 *dest = &tex->image[tex->width*v]; - uint32 taddr = tex->imageBase + width/2*v; - - for(unsigned u = 0; u < width; u++, taddr += !(u%2)) { - uint4 index = system.vmap.tex[taddr>>14 & 31][taddr] >> 4*(u&3); - uint32 paddr = tex->colorBase + 2*index; - uint16 bgr = system.vmap.texpal[paddr>>14 & 31][paddr]; - uint5 a = 31*(colorKey == false || index > 0); - - *dest++ = a<<15 | bgr; - } - } -} - -void GPU::convertI5(Texture *tex, int width, int height) { - tex->texelRange[1] += width*height/1; - tex->colorRange[1] += 64; - - for(unsigned v = 0; v < height; v++) { - uint32 *dest = &tex->image[tex->width*v]; - uint32 taddr = tex->imageBase + width*v; - - for(unsigned u = 0; u < width; u++, taddr++) { - uint8 index = system.vmap.tex[taddr>>14 & 31][taddr] >> 8*(u&1); - uint32 paddr = tex->colorBase + 2*(index & 0x1f); - uint16 bgr = system.vmap.texpal[paddr>>14 & 31][paddr]; - uint5 a = (index>>5) * 9/2; - - *dest++ = a<<15 | bgr; - } - } -} - -void GPU::convertI8(Texture *tex, int width, int height, bool colorKey) { - tex->texelRange[1] += width*height/1; - tex->colorRange[1] += 512; - - for(unsigned v = 0; v < height; v++) { - uint32 *dest = &tex->image[tex->width*v]; - uint32 taddr = tex->imageBase + width*v; - - for(unsigned u = 0; u < width; u++, taddr++) { - uint8 index = system.vmap.tex[taddr>>14 & 31][taddr] >> 8*(u&1); - uint32 paddr = tex->colorBase + 2*index; - uint16 bgr = system.vmap.texpal[paddr>>14 & 31][paddr]; - uint5 a = 31*(colorKey == false || index > 0); - - *dest++ = a<<15 | bgr; - } - } -} - -void GPU::convertARGB(Texture *tex, int width, int height) { - tex->texelRange[1] += width*height*2; - - for(unsigned v = 0; v < height; v++) { - uint32 *dest = &tex->image[tex->width*v]; - uint32 taddr = tex->imageBase + 2*width*v; - - for(unsigned u = 0; u < width; u++, taddr += 2) { - uint16 abgr = system.vmap.tex[taddr>>14 & 31][taddr]; - uint5 a = 31*(abgr >> 15); - - *dest++ = a<<15 | abgr; - } - } -} \ No newline at end of file diff --git a/bsnes/nds/interface/interface.cpp b/bsnes/nds/interface/interface.cpp deleted file mode 100644 index 42cf40ce..00000000 --- a/bsnes/nds/interface/interface.cpp +++ /dev/null @@ -1,410 +0,0 @@ -#include -#include - -namespace NintendoDS { - -Interface *interface = nullptr; - -double Interface::videoFrequency() { - return 2.*33513982 / (2*6 * 263*355); -} - -double Interface::audioFrequency() { - return 2.*33513982 / (2 * 1024); -} - -bool Interface::loaded() { - return true; -} - -unsigned Interface::group(unsigned id) { - if(id == ARM7BIOS || id == ARM9BIOS) return 0; - if(id == Firmware || id == Clock) return 0; - - if(id == Slot1ROM || id == Slot1EEPROM) return 1; - if(id == Slot1FRAM || id == Slot1Flash) return 1; - - if(id == Slot2ROM || id == Slot2RAM) return 2; - if(id == Slot2SRAM || id == Slot2EEPROM) return 2; - if(id == Slot2FRAM || id == Slot2Flash) return 2; - - return 0; -} - -void Interface::load(unsigned id, const string& manifest) { - //print(manifest,"\n"); - string syspath = interface->path(System); - - if(id == NintendoDS) { - gameManifest = manifest; - systemManifest.readfile({syspath, "manifest.xml"}); - XML::Document sysdoc(systemManifest); - - if(!sysdoc["system"].exists()) { - interface->notify("manifest.xml not found"); - } - else { - auto &sys = sysdoc["system"]; - - string arm7BiosFile = sys["arm7"]["bios"]["data"].data; - string arm9BiosFile = sys["arm9"]["bios"]["data"].data; - string firmwareFile = sys["flash"]["data"].data; - string clockXmlFile = sys["rtc"]["data"].data; - - if(!file::exists({syspath, arm7BiosFile})) interface->notify("arm7 bios not found"); - if(!file::exists({syspath, arm9BiosFile})) interface->notify("arm9 bios not found"); - if(!file::exists({syspath, firmwareFile})) interface->notify("firmware not found"); - - interface->loadRequest(ARM7BIOS, arm7BiosFile); - interface->loadRequest(ARM9BIOS, arm9BiosFile); - interface->loadRequest(Firmware, firmwareFile); - interface->loadRequest(Clock, clockXmlFile); - } - - if(gameManifest == "") { - // Default to 1GB ROM with no save. Since GameCard does bounds-check, - // we only allocate enough to hold the stream passed in. - gameManifest = - "" - "" - "" - "" - ""; - } - - // - XML::Document document(gameManifest); - - //if(document.error != "") { - // print(document.error,"\n"); - // return; - //} - - auto &eslot1 = document["cartridge"]["slot1"]; - - // - if(eslot1.exists()) { - // - if(eslot1["rom"].exists()) { - string file = string(eslot1["rom"]["name"].data); - uint32 size = numeral(eslot1["rom"]["size"].data); - uint32 chipId = numeral(eslot1["rom"]["id"].data); - - print("Loading slot-1 ROM (", file, ").. "); - slot1.load(new GameCard(chipId)); - interface->loadRequest(Slot1ROM, file); - print("\n"); - } - // - if(eslot1["save"].exists()) { - string file = string(eslot1["save"]["name"].data); - string type = string(eslot1["save"]["type"].data); - uint32 size = numeral(eslot1["save"]["size"].data); - uint32 psize = numeral(eslot1["save"]["page"].data); // EEPROM only - uint32 chipId = numeral(eslot1["save"]["id"].data); // Flash only - - unsigned id = 0; - if(auto card = slot1.card) { - if(type == "EEPROM") id = Slot1EEPROM, card->spi = new EEPROM(size, psize); - if(type == "Flash") id = Slot1Flash, card->spi = new Flash(size, chipId); - if(type == "FRAM") id = Slot1FRAM, card->spi = new FRAM(size); - } - if(id) { - print("Loading slot-1 ",eslot1["save"]["type"].data," (", file, ").. "); - interface->loadRequest(id, file); - print("\n"); - } - } - // - if(eslot1["irport"].exists()) { - // Required by Pokemon HG/SS and B/W. These cards have an infrared port - // built-in. Since there's only one /CS, access to flash memory passes - // through the infrared bridge via an override command. - slot1.card->spi = new IRPort(slot1.card->spi); - } - } - } - - // Provide blank images if needed (we'd crash otherwise). - if(system.firmware.size == 0) { - system.firmware.size = 0x40000; - system.firmware.data = new uint8[system.firmware.size]; - memset(system.firmware.data, 0xff, system.firmware.size); - } - if(arm7.bios.size == 0) { - arm7.bios.size = 4; - arm7.bios.data = new uint32[arm7.bios.size/4]; - memset(arm7.bios.data, 0xef, arm7.bios.size); - } - if(arm9.bios.size == 0) { - arm9.bios.size = 4; - arm9.bios.data = new uint32[arm9.bios.size/4]; - memset(arm9.bios.data, 0xef, arm9.bios.size); - } -} - -void Interface::load(unsigned id, const stream& memory, const string& markup) { - if(id == ARM7BIOS) return system.loadArm7Bios(memory); - if(id == ARM9BIOS) return system.loadArm9Bios(memory); - if(id == Firmware) return system.loadFirmware(memory); - if(id == Clock) return system.loadRTC(memory); - - XML::Document document(gameManifest); - - auto &eslot1 = document["cartridge"]["slot1"]; - - if(eslot1.exists()) { - if(eslot1["rom"].exists() && id == Slot1ROM) { - string hash = string(eslot1["rom"]["sha256"].data); - uint32 size = numeral(eslot1["rom"]["size"].data); - - if(auto card = slot1.card) { - delete card->rom.data; - card->rom.size = min(memory.size(), size); - card->rom.data = new uint8[card->rom.size]; - card->size = bit::round(size); - - memory.read(card->rom.data, card->rom.size); - - if(hash && hash != card->sha256) print("SHA256 mismatch."); - else print("OK."); - } - } - if(eslot1["save"].exists() && slot1.card && (id==Slot1EEPROM || id==Slot1Flash || id==Slot1FRAM)) { - uint32 size = numeral(eslot1["save"]["size"].data); - - if(auto save = slot1.card->spi) { - if(auto irport = dynamic_cast(save)) - save = irport->slave; - - if(auto media = dynamic_cast(save)) { - memory.read(media->data, min(media->size, memory.size())); - print("OK."); - } - } - } - } -} - - - -void Interface::save() { - XML::Document sysdoc(systemManifest); - - if(sysdoc["system"].exists()) { - auto &sys = sysdoc["system"]; - - interface->saveRequest(Firmware, sys["flash"]["data"].data); - interface->saveRequest(Clock, sys["rtc"]["data"].data); - } - - XML::Document document(gameManifest); - auto &eslot1 = document["cartridge"]["slot1"]; - - if(eslot1.exists() && eslot1["save"].exists()) { - string file = eslot1["save"]["name"].data; - string type = eslot1["save"]["type"].data; - - print("Saving slot-1 ",type,".. "); - - if(type == "EEPROM") interface->saveRequest(Slot1EEPROM, file); - if(type == "Flash") interface->saveRequest(Slot1Flash, file); - if(type == "FRAM") interface->saveRequest(Slot1FRAM, file); - - print("\n"); - } -} - -void Interface::save(unsigned id, const stream& memory) { - if(id == Firmware) return system.saveFirmware(memory); - if(id == Clock) return system.saveRTC(memory); - - if(slot1.card && (id == Slot1EEPROM || id == Slot1Flash || id == Slot1FRAM)) { - if(auto save = slot1.card->spi) { - if(auto irport = dynamic_cast(save)) - save = irport->slave; - - if(auto media = dynamic_cast(save)) { - memory.write(media->data, media->size); - print("OK."); - } - } - } -} - - - -void Interface::unload() { - struct timeval tv; - gettimeofday(&tv, nullptr); - system.clock.freeze(tv.tv_sec, tv.tv_usec); - system.running = false; - - save(); - delete slot1.unload(); -} - -void Interface::power() { - system.power(); -} - -void Interface::run() { - if(!system.running) { - struct timeval tv; - gettimeofday(&tv, nullptr); - system.clock.thaw(tv.tv_sec, tv.tv_usec); - system.running = true; - } - system.run(); -} - -serializer Interface::serialize() { - return {}; -} - -bool Interface::unserialize(serializer &s) { - return false; -} - -void Interface::paletteUpdate() { - for(unsigned color = 0; color < 01000000; color++) { - uint16 r = uint6(color>> 0) * 010101/4; - uint16 g = uint6(color>> 6) * 010101/4; - uint16 b = uint6(color>>12) * 010101/4; - - palette[color] = interface->videoColor(color, r,g,b); - } -} - -void Interface::videoRefresh(const uint32_t *data, unsigned pitch, unsigned width, unsigned height) { - static uint32_t pixels[256*384]; - - for(unsigned y = 0; y < 384; y++) { - const uint32 *src = &data[y*pitch/4]; - uint32 *dest = &pixels[y*256]; - - for(unsigned x = 0; x < 256; x++) - dest[x] = palette[src[x] & 0777777]; - } - return bind->videoRefresh(pixels, 256*4, 256, 384); -} - - -Interface::Interface() { - interface = this; - - information.name = "Nintendo DS"; - information.width = 256; - information.height = 384; - information.aspectRatio = 1.0; - information.overscan = false; - information.resettable = false; - information.capability.states = false; - information.capability.cheats = false; - - media.append({NintendoDS, "Nintendo DS", "nds"}); - //media.append({NintendoDS, "Nintendo DS", "nds", "Menu"}); - - // Input devices and ports - - emptySlot = Device{ID::Device::Empty, 1<port) - for(auto &device : this->device) - if(device.portmask & 1< device; - - // System inputs - Device sensors; - Device buttons; - Device touchpad; - - Device emptySlot; - - // Slot 1 - Device gameCard; - - // Slot 2 peripherals - Device gamePak; // for linking Pokémon D/P/HG/SS and R/S/E - Device expansionPak; // Opera browser, homebrew - Device rumblePak; // Metroid Pinball, others - Device guitarGrip; // Guitar Hero: On Tour - Device piano; // Easy Piano - Device paddle; // Arkanoid - - unsigned palette[01000000]; -}; - -extern Interface *interface; - -#ifndef NDS_HPP -} -#endif diff --git a/bsnes/nds/memory/eeprom.cpp b/bsnes/nds/memory/eeprom.cpp deleted file mode 100644 index cdb873f0..00000000 --- a/bsnes/nds/memory/eeprom.cpp +++ /dev/null @@ -1,96 +0,0 @@ - -EEPROM::~EEPROM() { } - -EEPROM::EEPROM(uint32 esize, uint32 psize) { - data = new uint8[size = esize]; - pageSize = psize; - memset(data, 0xff, size); -} - -EEPROM::EEPROM(const stream& memory, uint32 esize, uint32 psize) { - data = new uint8[size = esize]; - pageSize = psize; - memset(data, 0xff, size); - memory.read(data, min(memory.size(), size)); -} - -void EEPROM::power() { - if(!pageSize) { - if(size <= 0x200) pageSize = 0x10; - else if(size <= 0x2000) pageSize = 0x20; - else pageSize = 0x80; - } - command = 0; - writeEnable = false; -} - -void EEPROM::select(bool state) { - if(state) return; - - if(command && writeEnable) { - // Finish some previously submitted commands - if(command == 0x02 || command == 0x0a) { - //print("finishing write to ",hex<6>(page),"\n"); - address = page; - - // Write page - for(unsigned n = 0; n < count; n++) { - if(!(address & pageSize-1)) address = page; - this->data[address++] = buffer[n]; - } - writeEnable = false; - } - } - // Reset and wait for a new command - command = 0; -} - -uint8 EEPROM::transfer(uint8 data) { - if(command == 0) { - command = data; - address = count = 0; - addrCount = 0; - - //print("eeprom: cmd ",hex<2>(command),"\n"); - if(command == 0x02 || command == 0x0a) addrCount = 1 + (size > 512); - if(command == 0x03 || command == 0x0b) addrCount = 1 + (size > 512); - - if(command == 0x0a && size == 512) address = 1; // read/write 2nd page - if(command == 0x0b && size == 512) address = 1; // (512-byte only) - - if(command == 0x04) writeEnable = false; - if(command == 0x06) writeEnable = true; - return 0xff; - } - - if(addrCount) { // Input address - addrCount--; - address = address<<8 | data; - page = address; - return 0xff; - } - - if(command == 0x01) { - return 0xff; // Write status - } - - if(command == 0x05) { // Read status - return (size > 512? 0x00 : 0xf0) | writeEnable<<1; // | writing<<0; - } - - if(command == 0x03 || command == 0x0b) { // Read data - //if(address == page) print("eeprom: read ",hex<6>(address),"\n"); - if(address == size) address = 0; - return this->data[address++]; - } - - if(command == 0x02 || command == 0x0a) { // Write data - //if(address == page) print("eeprom: write ",hex<6>(address),"\n"); - if(count < pageSize) { - if(!(address & pageSize-1)) address = page; - buffer[count++] = data; - return this->data[address++]; - } - } - return 0xff; -} diff --git a/bsnes/nds/memory/eeprom.hpp b/bsnes/nds/memory/eeprom.hpp deleted file mode 100644 index 248390a1..00000000 --- a/bsnes/nds/memory/eeprom.hpp +++ /dev/null @@ -1,17 +0,0 @@ - -struct EEPROM : SPIDevice, StaticMemory { - ~EEPROM(); - EEPROM(uint32 esize, uint32 psize); - EEPROM(const stream& memory, uint32 esize, uint32 psize); - - void power(); - void select(bool state); - uint8 transfer(uint8 data); - - uint8 command; - uint16 address, page, pageSize; - unsigned addrCount; - unsigned count; - uint8 buffer[256]; - bool writeEnable; -}; diff --git a/bsnes/nds/memory/flash.cpp b/bsnes/nds/memory/flash.cpp deleted file mode 100644 index 15bcb572..00000000 --- a/bsnes/nds/memory/flash.cpp +++ /dev/null @@ -1,137 +0,0 @@ - -Flash::~Flash() { } - -Flash::Flash(uint32 esize, uint32 id) { - data = new uint8[size = esize]; - memset(data, 0xff, size); - this->id = id; -} - -Flash::Flash(const stream& memory, uint32 esize, uint32 id) { - data = new uint8[size = esize]; - memset(data, 0xff, size); - memory.read(data, min(memory.size(), size)); - this->id = id; -} - -void Flash::power() { - powered = true; - command = 0; - writeEnable = false; -} - -void Flash::select(bool state) { - if(state) return; - - //print("flash: deselect - cmd=",hex<2>(command)," wen=",writeEnable,"\n"); - if(command && writeEnable) { - // Finish some previously submitted commands - if(command == 0x0a) { - // Read any remaining page into the buffer, - // so it's not lost during the erase cycle. - while(count < 256) { - buffer[count++] = data[address++]; - if(!(address & 0xff)) address -= 0x100; - } - } - - if(command == 0x0a || command == 0xdb || command == 0xd8) { - // Modify page / erase page / erase 64Kbyte sector - unsigned block = command == 0xd8? 0x10000 : 0x100; - - address = page & ~(block-1); - - // Erasing sets data bits to 1. - for(unsigned n = 0; n < block; n++) - data[address++] = 0xff; - - writeEnable = false; - } - - if(command == 0x0a || command == 0x02) { - // Modify page / write page - address = page; - //print("finishing write to ",hex<6>(page),"\n"); - - for(unsigned n = 0; n < 256; n++) { - // Writing can only clear bits. - data[address++] &= buffer[n]; - if(!(address & 0xff)) address -= 0x100; - } - writeEnable = false; - } - } - // Reset and wait for a new command - command = 0; -} - -uint8 Flash::transfer(uint8 data) { - if(command == 0) { - command = data; - count = 0; - address = 0; - addrCount = 0; - - //print("flash: cmd ",hex<2>(command),"\n"); - - if(command == 0xab) powered = true; // Wake up - - if(powered) { - if(command == 0x9f) count = 3; // Read ID - if(command == 0xb9) powered = false; // Power down - if(command == 0x06) writeEnable = true; // Write enable - if(command == 0x04) writeEnable = false; // Write disable - - if(command == 0xdb || command == 0xd8) addrCount = 3; // Erase page / sector - if(command == 0x02 || command == 0x0a) addrCount = 3; // Write data - if(command == 0x03 || command == 0x0b) addrCount = 3; // Read data - } - return 0; - } - if(!powered) - return 0; - - if(addrCount) { - // Input address - addrCount--; - address = address<<8 | data; - page = address; - if(command == 0x0b) count = 1; // Dummy byte between address and data - return 0; - } - - if(command == 0x9f) { - // Read ID - //print("flash: read id\n"); - if(count) count--; - return id >> 8*count; - } - - if(command == 0x05) { - // Read status - //print("flash: read status\n"); - return writeEnable<<1; // | writing<<0; - } - - if(command == 0x03 || command == 0x0b) { - // Read data - //if(address == page) print("flash: read ",hex<6>(address),"\n"); - if(count) { count--; return 0; } - if(address >= size) address = 0; - return this->data[address++]; - } - - if(command == 0x02 || command == 0x0a) { - // Write page / modify page - //if(address == page) print("flash: write ",hex<6>(address),"\n"); - if(count < 0x100) { - if(address >= size) address = 0; - buffer[count++] = data; - uint8 r = this->data[address++]; - if(!(address & 0xff)) address -= 0x100; - return r; - } - return 0; - } - return 0; -} diff --git a/bsnes/nds/memory/flash.hpp b/bsnes/nds/memory/flash.hpp deleted file mode 100644 index 32656344..00000000 --- a/bsnes/nds/memory/flash.hpp +++ /dev/null @@ -1,20 +0,0 @@ - -struct Flash : SPIDevice, StaticMemory { - ~Flash(); - Flash() {} - Flash(uint32 esize, uint32 id); - Flash(const stream& memory, uint32 esize, uint32 id); - - void power(); - void select(bool state); - uint8 transfer(uint8 data); - - uint24 id; - uint8 command; - uint24 address, page; - unsigned addrCount; - unsigned count; - uint8 buffer[256]; - bool powered; - bool writeEnable; -}; diff --git a/bsnes/nds/memory/fram.cpp b/bsnes/nds/memory/fram.cpp deleted file mode 100644 index 1e955bd6..00000000 --- a/bsnes/nds/memory/fram.cpp +++ /dev/null @@ -1,64 +0,0 @@ - -FRAM::~FRAM() { } - -FRAM::FRAM(uint32 esize) { - data = new uint8[size = esize]; - memset(data, 0xff, size); -} - -FRAM::FRAM(const stream& memory, uint32 esize) { - data = new uint8[size = esize]; - memset(data, 0xff, size); - memory.read(data, min(memory.size(), size)); -} - -void FRAM::power() { - command = 0; - writeEnable = false; -} - -void FRAM::select(bool state) { - if(state) return; - - // Reset and wait for a new command - if(command == 0x02) writeEnable = false; - command = 0; -} - -uint8 FRAM::transfer(uint8 data) { - if(command == 0) { - command = data; - address = addrCount = 0; - - if(command == 0x02) addrCount = 2; - if(command == 0x03) addrCount = 2; - if(command == 0x04) writeEnable = false; - if(command == 0x06) writeEnable = true; - return 0xff; - } - - if(addrCount) { // Input address - addrCount--; - address = address<<8 | data; - return 0xff; - } - - if(command == 0x01) { - return 0xff; // Write status - } - - if(command == 0x05) { // Read status - return writeEnable<<1; // | writing<<0; - } - - if(command == 0x03) { // Read data - if(address == size) address = 0; - return this->data[address++]; - } - - if(command == 0x02) { // Write data - if(address == size) address = 0; - return this->data[address++] = data; - } - return 0xff; -} diff --git a/bsnes/nds/memory/fram.hpp b/bsnes/nds/memory/fram.hpp deleted file mode 100644 index 753f2a29..00000000 --- a/bsnes/nds/memory/fram.hpp +++ /dev/null @@ -1,16 +0,0 @@ - -struct FRAM : SPIDevice, StaticMemory { - ~FRAM(); - FRAM(uint32 esize); - FRAM(const stream& memory, uint32 esize); - - void power(); - void select(bool state); - uint8 transfer(uint8 data); - - uint8 command; - uint16 address, page, pageSize; - unsigned addrCount; - uint8 buffer[256]; - bool writeEnable; -}; diff --git a/bsnes/nds/memory/memory.cpp b/bsnes/nds/memory/memory.cpp deleted file mode 100644 index e4e10d44..00000000 --- a/bsnes/nds/memory/memory.cpp +++ /dev/null @@ -1,127 +0,0 @@ -#include - -namespace NintendoDS { - -Memory::~Memory() {} - -struct UnmappedMemory : Memory { - uint32 read(uint32 addr, uint32 size) { return 0u; } - void write(uint32 addr, uint32 size, uint32 word) {} -}; - -static UnmappedMemory unmappedMemory; - - -StaticMemory::StaticMemory() { data = nullptr; size = 0u; } -StaticMemory::~StaticMemory() { if(data) delete[] data; } -uint8& StaticMemory::operator[](uint32 addr) { return data[addr]; } - -uint32 StaticMemory::read(uint32 addr, uint32 size) { - if(size == Byte) return (*this)[addr]; - if(size == Half) return addr &= ~1, (*this)[addr] | (*this)[addr+1]<<8; - if(size == Word) return addr &= ~3, (*this)[addr] | (*this)[addr+1]<<8 | (*this)[addr+2]<<16 | (*this)[addr+3]<<24; -} - -void StaticMemory::write(uint32 addr, uint32 size, uint32 word) { - if(size == Half) addr &= ~1; - if(size == Word) addr &= ~3; - - (*this)[addr] = word; - if(size >= Half) { - (*this)[addr+1] = word>>8; - } - if(size >= Word) { - (*this)[addr+2] = word>>16; - (*this)[addr+3] = word>>24; - } -} - - -ByteMemory::ByteMemory() { data = nullptr; size = 0u; } -ByteMemory::~ByteMemory() { if(data) delete[] data; } -uint8& ByteMemory::operator[](uint32 addr) { return data[addr]; } - -uint32 ByteMemory::read(uint32 addr, uint32 size) { - return (*this)[addr] * 0x01010101; -} - -void ByteMemory::write(uint32 addr, uint32 size, uint32 word) { - (*this)[addr] = word; -} - - -HalfMemory::HalfMemory() { data = nullptr; size = 0u; } -HalfMemory::~HalfMemory() { if(data) delete[] data; } - -uint16& HalfMemory::operator[](uint32 addr) { return data[addr>>1]; } - -uint32 HalfMemory::read(uint32 addr, uint32 size) { - if(size == Word) return addr &= ~3, (*this)[addr] + ((*this)[addr+2] << 16); - if(size != Word) return (*this)[addr] * 0x00010001; -} - -void HalfMemory::write(uint32 addr, uint32 size, uint32 word) { - if(size == Word) addr &= ~3; - - (*this)[addr] = word; - if(size == Word) - (*this)[addr+2] = word>>16; -} - - -WordMemory::WordMemory() { data = nullptr; size = 0u; } -WordMemory::~WordMemory() { if(data) delete[] data; } - -uint32& WordMemory::operator[](uint32 addr) { return data[addr>>2]; } - -uint32 WordMemory::read(uint32 addr, uint32 size) { - return (*this)[addr]; -} - -void WordMemory::write(uint32 addr, uint32 size, uint32 word) { - if(size == Word) (*this)[addr] = word; - if(size != Word) (*this)[addr] ^= ((*this)[addr] ^ word) & 0xffff << 8*(addr & 2); -} - - -SDRAM::SDRAM() { data = nullptr; size = 0u; } -SDRAM::~SDRAM() { if(data) delete[] data; } - -uint16& SDRAM::operator[](uint32 addr) { return data[addr>>1]; } - -uint32 SDRAM::read(uint32 addr, uint32 size) { - if(size == Word) return addr &= ~3, (*this)[addr] + ((*this)[addr+2] << 16); - if(size != Word) return (*this)[addr] * 0x00010001; -} - -void SDRAM::write(uint32 addr, uint32 size, uint32 word) { - if(size == Word) { - addr &= ~3; - (*this)[addr+0] = word; - (*this)[addr+2] = word>>16; - } - if(size == Half) (*this)[addr] = word; - if(size == Byte) (*this)[addr] ^= ((*this)[addr] ^ word) & 0xff << 8*(addr & 1); -} - - -SRAM::SRAM() { data = nullptr; size = 0u; } -SRAM::~SRAM() { if(data) delete[] data; } - -uint32& SRAM::operator[](uint32 addr) { return data[addr>>2]; } - -uint32 SRAM::read(uint32 addr, uint32 size) { - return (*this)[addr]; -} - -void SRAM::write(uint32 addr, uint32 size, uint32 word) { - if(size == Word) (*this)[addr] = word; - if(size == Half) (*this)[addr] ^= ((*this)[addr] ^ word) & 0xffff << 8*(addr & 2); - if(size == Byte) (*this)[addr] ^= ((*this)[addr] ^ word) & 0xff << 8*(addr & 3); -} - -#include "eeprom.cpp" -#include "fram.cpp" -#include "flash.cpp" - -} diff --git a/bsnes/nds/memory/memory.hpp b/bsnes/nds/memory/memory.hpp deleted file mode 100644 index b1f2ed7f..00000000 --- a/bsnes/nds/memory/memory.hpp +++ /dev/null @@ -1,76 +0,0 @@ -struct Memory { - virtual ~Memory(); - virtual uint32 read(uint32 addr, uint32 size) = 0; - virtual void write(uint32 addr, uint32 size, uint32 word) = 0; -}; - -struct StaticMemory : Memory { - uint8_t *data; - unsigned size; - - uint8& operator[](uint32 addr); - uint32 read(uint32 addr, uint32 size); - void write(uint32 addr, uint32 size, uint32 word); - StaticMemory(); - ~StaticMemory(); -}; - -// Slot 2 SRAM - 8-bit; bytes only -struct ByteMemory : Memory { - uint8_t *data; - unsigned size; - - uint8& operator[](uint32 addr); - uint32 read(uint32 addr, uint32 size); - void write(uint32 addr, uint32 size, uint32 word); - ByteMemory(); - ~ByteMemory(); -}; - -// VRAM, Palettes - 16-bit; halves and words -struct HalfMemory : Memory { - uint16_t *data; - unsigned size; - - uint16& operator[](uint32 addr); - uint32 read(uint32 addr, uint32 size); - void write(uint32 addr, uint32 size, uint32 word); - HalfMemory(); - ~HalfMemory(); -}; - -// OAM, BIOS - 32-bit; halves and words -struct WordMemory : Memory { - uint32_t *data; - unsigned size; - - uint32& operator[](uint32 addr); - uint32 read(uint32 addr, uint32 size); - void write(uint32 addr, uint32 size, uint32 word); - WordMemory(); - ~WordMemory(); -}; - -// EWRAM - 16-bit; all sizes -struct SDRAM : Memory { - uint16_t *data; - unsigned size; - - uint16& operator[](uint32 addr); - uint32 read(uint32 addr, uint32 size); - void write(uint32 addr, uint32 size, uint32 word); - SDRAM(); - ~SDRAM(); -}; - -// TCM, IWRAM - 32-bit; all sizes -struct SRAM : Memory { - uint32_t *data; - unsigned size; - - uint32& operator[](uint32 addr); - uint32 read(uint32 addr, uint32 size); - void write(uint32 addr, uint32 size, uint32 word); - SRAM(); - ~SRAM(); -}; diff --git a/bsnes/nds/nds.hpp b/bsnes/nds/nds.hpp deleted file mode 100644 index 72f7d9ae..00000000 --- a/bsnes/nds/nds.hpp +++ /dev/null @@ -1,29 +0,0 @@ -#ifndef NDS_HPP -#define NDS_HPP - -// dasShiny - Nintendo DS emulator -// Copyright (c) 2012 Cydrak -// License: GPLv3 - -#include -#include - -namespace NintendoDS { - enum : unsigned { - Byte = 8, Half = 16, Word = 32 - }; - - #include - #include - #include - #include - #include - #include - #include - #include - #include - #include - #include -} - -#endif diff --git a/bsnes/nds/ppu/bg.cpp b/bsnes/nds/ppu/bg.cpp deleted file mode 100644 index 401d0e35..00000000 --- a/bsnes/nds/ppu/bg.cpp +++ /dev/null @@ -1,251 +0,0 @@ - -void PPU::renderBgs(unsigned y) { - unsigned bpp[4] = {}; - unsigned mapw[4], maph[4]; // tiled dimensions - unsigned affw[4], affh[4]; // Affine dimensions - unsigned bitw[4], bith[4]; // Bitmap dimensions - - for(unsigned n = 0; n < 4; n++) { - // Tiled dimensions - mapw[n] = bg[n].size & 1? 64 : 32; - maph[n] = bg[n].size & 2? 64 : 32; - - // Affine settings - affw[n] = 16 << bg[n].size; - affh[n] = 16 << bg[n].size; - bitw[n] = 128 << (bg[n].size - (bg[n].size >= 3)); // 128,256,512,512 - bith[n] = 128 << (bg[n].size - (bg[n].size >= 2)); // 128,256,256,512 - bpp[n] = 8 << (bg[n].tiles & 1); - } - - if(video.line == 0) { - bg[2].linex = bg[2].originx; - bg[2].liney = bg[2].originy; - bg[3].linex = bg[3].originx; - bg[3].liney = bg[3].originy; - } - - if(bgMode == 6) { - // Large 512 x 1024 x 8bpp bitmap - uses all 512K BG - // Supposedly 3D is still available on BG0, though - // you'd have no VRAM leftover for textures... - bitw[2] = 512 << (bg[2].size & 1); - bith[2] = 1024 >> (bg[2].size & 1); - - renderBitmapBg(2, 8, bitw[2], bith[2], y); - } - else { - // BG0 is either tiled or 3D render output - // BG1 is always tiled - if(bg0FromGPU == 0) renderTiledBg (0, mapw[0], maph[0], y); - renderTiledBg (1, mapw[1], maph[1], y); - - // BG2-3 are a selectable mix of: - // - Tiled: 16-bit screen blocks with tile attributes - // - GBA: 8-bit affine maps, only tile number - // - NDS: 16-bit affine maps with tile attributes; - // these also work as 8/16-bpp bitmaps - // - if(bgMode == 0) { // 2 x tiled - renderTiledBg (2, mapw[2], maph[2], y); - renderTiledBg (3, mapw[3], maph[3], y); - } - if(bgMode == 1) { // Tiled + GBA - renderTiledBg (2, mapw[2], maph[2], y); - renderAffineBg(3, 8, affw[3], affh[3], y); - } - if(bgMode == 2) { // 2 x GBA - renderAffineBg(2, 8, affw[2], affh[2], y); - renderAffineBg(3, 8, affw[3], affh[3], y); - } - if(bgMode == 3) { // Tiled + NDS - renderTiledBg (2, mapw[2], maph[2], y); - if(bg[3].depth == 0) renderAffineBg(3, 16, affw[3], affh[3], y); - if(bg[3].depth == 1) renderBitmapBg(3, bpp[3], bitw[3], bith[3], y); - } - if(bgMode == 4) { // GBA + NDS - renderAffineBg(2, 8, affw[2], affh[2], y); - if(bg[3].depth == 0) renderAffineBg(3, 16, affw[3], affh[3], y); - if(bg[3].depth == 1) renderBitmapBg(3, bpp[3], bitw[3], bith[3], y); - } - if(bgMode == 5) { // 2 x NDS - if(bg[2].depth == 0) renderAffineBg(2, 16, affw[2], affh[2], y); - if(bg[3].depth == 0) renderAffineBg(3, 16, affw[3], affh[3], y); - if(bg[2].depth == 1) renderBitmapBg(2, bpp[2], bitw[2], bith[2], y); - if(bg[3].depth == 1) renderBitmapBg(3, bpp[3], bitw[3], bith[3], y); - } - } - - bg[2].linex += bg[2].transform.dx_dv; - bg[2].liney += bg[2].transform.dy_dv; - bg[3].linex += bg[3].transform.dx_dv; - bg[3].liney += bg[3].transform.dy_dv; -} - -void PPU::renderTiledBg(unsigned no, unsigned mapw, unsigned maph, unsigned y) { - auto &bg = this->bg[no]; - if(bg.enable == false) - return; - - uint32 flags = pxPriority*bg.priority + pxLayer*(2u+no); - unsigned line = bg.voffs + y; - unsigned finex = bg.hoffs % 8; - auto above = &this->above[8 - finex]; - auto below = &this->below[8 - finex]; - - if(blendAbove & 1< 32 && (mapy & 32)) maddr += 32*mapw; - if(mapw > 32 && (mapx & 32)) maddr += 32*32; - - bool ext = bg.depth && bgLargePal; - unsigned depth = bg.depth? 0x100 : 0x10; - unsigned imask = depth-1; - - unsigned extpalbase = 0x1000*no; - if(bg.affineWrap) // special case for BG0/BG1 - this bit - extpalbase |= 0x2000; // makes them share BG2/BG3's palettes - - for(unsigned x = 0; x < 256+8; ) { - uint16 attr = system.vmap.bg(which, 2*maddr>>14)[2*maddr]; - int pal = (attr>>12)*depth + extpalbase; - uint1 vflip = attr>>11; - uint1 hflip = attr>>10; - uint10 tile = attr; - - int row = line%8; - if(vflip) row ^= 7; - - uint32 taddr = 0x10000*bgTileBase + 0x4000*bg.tiles + ((32*tile + 4*row) << bg.depth); - auto tref = &system.vmap.bg(which, taddr>>14)[taddr]; - - uint64 slice = 0; - for(int n = 3; n >= 0; --n) - slice = slice<<16 | tref[n]; - - int dir = +1; - if(hflip) dir = -1, x += 7; - - for(unsigned n = 0; n < 8; n++, x += dir) { - if(window[x + 8 - finex] & 1<> 13][pal+index << 1]; - bgr = (bgr<<3 & 0760000) | (bgr<<2 & 0007600) | (bgr<<1 & 0000076); - } - if(flags < above[x]) below[x] = above[x], above[x] = flags + bgr; - else if(flags < below[x]) below[x] = flags + bgr; - } - } - slice >>= (4 << bg.depth); - } - - if(hflip) x += 9; - - if((++maddr & 31) == 0) { - maddr -= 32; - if(mapw > 32) // wrap to next screen - maddr += mapx & 32? -32*32 : +32*32; - } - } -} - -void PPU::renderAffineBg(unsigned no, unsigned mapDepth, unsigned mapW, unsigned mapH, unsigned y) { - auto &bg = this->bg[no]; - if(bg.enable == false) - return; - - bool ext = mapDepth==16 && bgLargePal; - uint32 flags = pxPriority*bg.priority + pxLayer*(2+no); - int32 fx = bg.linex; - int32 fy = bg.liney; - - if(blendAbove & 1<> 8; - unsigned my = fy >> 8; - - if(bg.affineWrap) - mx &= 8*mapW-1, my &= 8*mapH-1; - - if(mx < 8*mapW && my < 8*mapH) { - uint32 addr = 0x10000*bgMapBase + 2*32*32*bg.map + ((mapW*(my/8) + (mx/8)) << (mapDepth == 16)); - uint16 attr = system.vmap.bg(which, addr>>14)[addr]; - - if(mapDepth == 8) { - // no special handling - pal, vflip, hflip will all be 0 - attr = attr >> 8*(mx/8 & 1) & 0xff; - } - int pal = (attr>>12)*0x100 + no*0x1000; - uint1 vflip = attr>>11; - uint1 hflip = attr>>10; - uint10 tile = attr; - - int row = my%8 ^ 7*vflip; - int col = mx%8 ^ 7*hflip; - - uint32 taddr = 0x10000*bgTileBase + 0x4000*bg.tiles + 64*tile + 8*row + col; - uint8 index = system.vmap.bg(which, taddr>>14)[taddr] >> 8*(col & 1); - - if(index) { - uint32 bgr = bgPal[pal+index & 0xff]; - if(ext) { - bgr = system.vmap.bgpal[which][pal>>13][pal+index << 1]; - bgr = (bgr<<3 & 0760000) | (bgr<<2 & 0007600) | (bgr<<1 & 0000076); - } - if(flags < above[x]) below[x] = above[x], above[x] = flags + bgr; - else if(flags < below[x]) below[x] = flags + bgr; - } - } - } - fx += bg.transform.dx_dh; - fy += bg.transform.dy_dh; - } -} - -void PPU::renderBitmapBg(unsigned no, unsigned mapDepth, unsigned mapW, unsigned mapH, unsigned y) { - auto &bg = this->bg[no]; - if(bg.enable == false) - return; - - uint32 flags = pxPriority*bg.priority + pxLayer*(2+no); - int32 fx = bg.linex; - int32 fy = bg.liney; - - if(blendAbove & 1<>8, my = fy>>8; - - if(bg.affineWrap) - mx &= mapW-1, my &= mapH-1; - - if(mx < mapW && my < mapH) { - uint32 addr = 0x4000*bg.map + ((mapW*my + mx) << (mapDepth == 16)); - uint16 data = system.vmap.bg(which, addr>>14)[addr] >> 8*(addr & 1); - uint32 bgr; - - if(mapDepth== 8) bgr = bgPal[data &= 0xff]; - if(mapDepth==16) bgr = (data<<3&62<<12)|(data<<2&62<<6)|(data<<1&62), data &= 0x8000; - - if(data) { - if(flags < above[x]) below[x] = above[x], above[x] = flags + bgr; - else if(flags < below[x]) below[x] = flags + bgr; - } - } - } - fx += bg.transform.dx_dh; - fy += bg.transform.dy_dh; - } -} diff --git a/bsnes/nds/ppu/obj.cpp b/bsnes/nds/ppu/obj.cpp deleted file mode 100644 index f1bce309..00000000 --- a/bsnes/nds/ppu/obj.cpp +++ /dev/null @@ -1,159 +0,0 @@ - -void PPU::renderObjs(unsigned y) { - if(objEnable == false) - return; - - for(unsigned n = 0; n < 128; n++) { - objinfo& obj = this->obj[n]; - - if(obj.renderMode == objinfo::hidden) continue; - - uint8 width = 1 << obj.size; - uint8 height = 1 << obj.size; - uint8 row = y - obj.y; - - bool wide = obj.shape == objinfo::wide; - bool tall = obj.shape == objinfo::tall; - bool affine = obj.renderMode & objinfo::affine; - bool size = obj.renderMode == objinfo::affineDouble; - - if(obj.size <= 1) width <<= wide, height <<= tall; - if(obj.size >= 1) width >>= tall, height >>= wide; - if(wide && tall) width = 1, height = 1; - - if(row >= 8*(height << size)) continue; - if(obj.x <= -8*(width << size)) continue; - - if(obj.kind == objinfo::bitmap) renderBitmapObj(obj, width, height, row); - else renderTiledObj(obj, width, height, row); - } -} - -void PPU::renderTiledObj(objinfo& obj, unsigned objw, unsigned objh, unsigned y) { - unsigned step = objTileMode? 0+objTileStep : 0; - unsigned srow = objTileMode? objw << obj.depth : 32; - unsigned tile = obj.index << step; - - uint32 zmask = pxPriority*3u + pxLayer*7u; - uint32 flags = pxPriority*obj.priority + pxLayer*1u; - bool affine = obj.renderMode & objinfo::affine; - bool size = obj.renderMode == objinfo::affineDouble; - bool hflip = obj.transform & 8; - bool vflip = obj.transform & 16; - bool ext = obj.depth && objLargePal; - bool win = obj.kind == objinfo::window; - unsigned pal = obj.depth? 256*obj.palette : 16*obj.palette; - unsigned mask = obj.depth? 0xff : 0x0f; - - if(blendAbove & 1<<4) flags |= pxBlendAbove; - if(blendBelow & 1<<4) flags |= pxBlendBelow; - - if(obj.kind == objinfo::blend) flags |= pxBlendForce; - - affineparam tf = { 0x100, 0, 0, 0x100 }; - - int32 cx = 8*objw/2, ox = 0 - (cx << size), dw = 8*objw << size; - int32 cy = 8*objh/2, oy = y - (cy << size), dh = 8*objh << size; - - if(affine) { - tf = objTransform[obj.transform]; - } else { - if(hflip) ox++, tf.dx_dh *= -1; - if(vflip) oy++, tf.dy_dv *= -1; - } - - int32 fx = ox*tf.dx_dh + oy*tf.dx_dv; - int32 fy = ox*tf.dy_dh + oy*tf.dy_dv; - - int x = obj.x + 8; - for(unsigned t = 0; t < dw && x < 256+8; x++, t++) { - uint32 mx = (fx >> 8) + cx; - uint32 my = (fy >> 8) + cy; - - if(mx < 8*objw && my < 8*objh) { - unsigned taddr = tile; - - taddr += (my/8)*srow; - taddr += (mx/8) << obj.depth; taddr <<= 3; - taddr += (my%8) << obj.depth; taddr <<= 2; - taddr += (mx%8) >>!obj.depth; - - uint16 data = system.vmap.obj(which, taddr>>14)[taddr]; - - if(obj.depth) data = data >> 8*(mx%2) & mask; - else data = data >> 4*(mx%4) & mask; - - if(x >= 0 && data) { - if(win) { - window[x] = min(window[x], 0x20+winArea[2]); - } - else { - uint32 bgr = objPal[pal+data & 0xff]; - if(ext) { - bgr = system.vmap.objpal[which][pal>>13][pal+data << 1]; - bgr = (bgr<<3 & 0760000) | (bgr<<2 & 0007600) | (bgr<<1 & 0000076); - } - if(flags < (objLayer[x] & zmask)) objLayer[x] = flags + bgr; - } - } - } - fx += tf.dx_dh; - fy += tf.dy_dh; - } -} - -void PPU::renderBitmapObj(objinfo& obj, unsigned objw, unsigned objh, unsigned y) { - unsigned srow = objBitmapMode>1? 16*objw : 256<1) tile <<= 7+objBitmapStep; - else tile = 8*srow*(obj.index>>5 & 31) + 16*(obj.index & 31); - - uint32 zmask = pxPriority*3u + pxLayer*7u; - uint32 flags = pxPriority*obj.priority + pxLayer*1u + pxAlpha*2u*(obj.palette+1); - bool affine = obj.renderMode & objinfo::affine; - bool size = obj.renderMode == objinfo::affineDouble; - bool hflip = obj.transform & 8; - bool vflip = obj.transform & 16; - unsigned alpha = obj.palette; - - if(blendAbove & 1<<4) flags |= pxBlendAbove; - if(blendBelow & 1<<4) flags |= pxBlendBelow; - - flags |= pxBlendForce + (2*alpha+1)*pxAlpha; - - affineparam tf = { 0x100, 0, 0, 0x100 }; - - int32 cx = 8*objw/2, ox = 0 - (cx << size), dw = 8*objw << size; - int32 cy = 8*objh/2, oy = y - (cy << size), dh = 8*objh << size; - - if(affine) { - tf = objTransform[obj.transform]; - } else { - if(hflip) ox++, tf.dx_dh *= -1; - if(vflip) oy++, tf.dy_dv *= -1; - } - - int32 fx = ox*tf.dx_dh + oy*tf.dx_dv; - int32 fy = ox*tf.dy_dh + oy*tf.dy_dv; - - int x = obj.x + 8; - for(unsigned t = 0; t < dw && x < 256+8; x++, t++) { - uint32 mx = (fx >> 8) + cx; - uint32 my = (fy >> 8) + cy; - - if(mx < 8*objw && my < 8*objh) { - unsigned taddr = tile + srow*my + 2*mx; - - uint16 data = system.vmap.obj(which, taddr>>14)[taddr]; - - if(x >= 0 && (data & 0x8000)) { - uint5 b = data>>10, g = data>>5, r = data>>0; - - if(flags < (objLayer[x] & zmask)) objLayer[x] = flags | b<<13 | g<<7 | r<<1; - } - } - fx += tf.dx_dh; - fy += tf.dy_dh; - } -} diff --git a/bsnes/nds/ppu/ppu.cpp b/bsnes/nds/ppu/ppu.cpp deleted file mode 100644 index c5197b5d..00000000 --- a/bsnes/nds/ppu/ppu.cpp +++ /dev/null @@ -1,414 +0,0 @@ -#include - -namespace NintendoDS { - -PPU ppu[2]; - - - -PPU::PPU() { -} - -void PPU::power() { - forceBlank = false; - - bgLargePal = false; - bg0FromGPU = false; - bgMode = 0; - bgTileBase = 0; - bgMapBase = 0; - - for(unsigned n = 0; n < 4; n++) { - bg[n].enable = false; - bg[n].mosaic = false; - bg[n].affineWrap = false; - bg[n].depth = 0; - bg[n].priority = 0; - bg[n].size = 0; - bg[n].map = 0; - bg[n].tiles = 0; - bg[n].palette = 0; - bg[n].hoffs = 0; - bg[n].voffs = 0; - bg[n].originx = 0; - bg[n].originy = 0; - bg[n].linex = 0; - bg[n].liney = 0; - bg[n].transform.dx_dh = 0; - bg[n].transform.dy_dh = 0; - bg[n].transform.dx_dv = 0; - bg[n].transform.dy_dv = 0; - } - objEnable = false; - objInHBlank = false; - objLargePal = false; - objTileMode = 0; - objTileStep = 0; - objBitmapMode = 0; - objBitmapStep = 0; - - for(unsigned n = 0; n < 128; n++) { - obj[n].kind = objinfo::none; - obj[n].renderMode = objinfo::normal; - obj[n].mosaic = false; - obj[n].depth = 0; - obj[n].size = 0; - obj[n].shape = objinfo::square; - obj[n].transform = 0; - obj[n].x = 0; - obj[n].y = 0; - obj[n].index = 0; - obj[n].priority = 0; - obj[n].palette = 0; - } - for(unsigned n = 0; n < 32; n++) { - objTransform[n].dx_dh = 0; - objTransform[n].dy_dh = 0; - objTransform[n].dx_dv = 0; - objTransform[n].dy_dv = 0; - } - - blendMode = 0; - blendAbove = 0; - blendBelow = 0; - blendAf = 0; - blendBf = 0; - blendYf = 0; - - for(unsigned n = 0; n < 2; n++) { - winX[n][0] = 0; winX[n][1] = 0xff; - winY[n][0] = 0; winY[n][1] = 0xff; - } - winArea[0] = 0; winEnable[0] = false; - winArea[1] = 0; winEnable[1] = false; - winArea[2] = 0; winEnable[2] = false; - winArea[3] = 0; -} - - -void PPU::scanline() { - if(video.line < 192) { - // Set up backdrop - for(unsigned x = 0; x < 256+16; x++) { - above[x] = pxPriority*3u + pxLayer*6u + bgPal[0]; - below[x] = pxPriority*3u + pxLayer*7u; - objLayer[x] = pxPriority*3u + pxLayer*7u; - - if(blendAbove & 1<<5) above[x] |= pxBlendAbove; // can shade backdrop - if(blendBelow & 1<<5) above[x] |= pxBlendBelow; // can blend over backdrop - } - - // Set up window buffer - bool useWindowing = winEnable[0] || winEnable[1] || winEnable[2]; - - if(useWindowing) memset(window, 0xc0+winArea[3], 256+16); // initialize with winout - else memset(window, 0x3f, 256+16); // draw everything - - for(int w = 1; w >= 0; w--) - if(winEnable[w] && winY[w][0] <= video.line && video.line <= winY[w][1] && winX[w][1] > winX[w][0]) - memset(&window[winX[w][0] + 8], 0x40+winArea[w], winX[w][1] - winX[w][0]); - - // Draw layers - if(objEnable) - renderObjs(video.line); - - renderBgs(video.line); - - - // Feed in 3D layer, if requested - if(bg[0].enable && bg0FromGPU && which == 0) { - auto *gpuOut = &gpu.output[256*video.line]; - - uint32 depth = pxPriority*bg[0].priority + pxLayer*2; - uint32 flags = pxBlendForce; - - if(blendAbove & 1<<0) flags |= pxBlendAbove; - if(blendBelow & 1<<0) flags |= pxBlendBelow; - - for(unsigned x = 0; x < 256; x++) { - if(!(window[x+8] & 1<<0)) continue; - if(gpuOut[x] < 1*pxAlpha) continue; - - if(depth < above[8+x]) { - below[8+x] = above[8+x]; - above[8+x] = depth | flags | gpuOut[x]; - } - else if(depth < below[8+x]) { - below[8+x] = depth | flags | gpuOut[x]; - } - } - } - - // Add OBJs, if enabled - if(objEnable) { - for(unsigned x = 0; x < 256; x++) { - if(!(window[x+8] & 1<<4)) continue; - - auto &objPx = objLayer[x+8]; - auto &abovePx = above[x+8]; - auto &belowPx = below[x+8]; - - if(objPx < abovePx) belowPx = abovePx, abovePx = objPx; - else if(objPx < belowPx) belowPx = objPx; - } - } - - unsigned yf = min(32, 2*blendYf); - - uint64 round = 02000200020; - uint64 shade = round; - if(blendMode == lighten) - shade += 07700770077ull*yf; - - for(unsigned x = 0; x < 256; x++) { - auto &abovePx = above[x+8]; - auto &belowPx = below[x+8]; - - unsigned af = min(32, 2*blendAf); - unsigned bf = min(32, 2*blendBf); - - bool canShade = (abovePx & pxBlendAbove); - bool canBlend = (abovePx & (pxBlendAbove|pxBlendForce)) && (belowPx & pxBlendBelow); - bool forceAlpha = (abovePx & pxBlendForce ) && (belowPx & pxBlendBelow); - unsigned mode = forceAlpha? alphaBlend : blendMode; - - if(!(mode && (window[x+8] & 1<<5))) { - output[x] = abovePx; - continue; - } - - uint64 a = (abovePx & 0777777)*01000001ull & 07700770077ull; - uint64 b = (belowPx & 0777777)*01000001ull & 07700770077ull; - - if(forceAlpha && (abovePx & 31*pxAlpha)) - af = (abovePx>>18 & 31) + 1, bf = 32-af; - - if(canBlend && mode == alphaBlend) a = (a*af + b*bf + round)/32; - else if(canShade && mode > alphaBlend) a = (a*(32 - yf) + shade)/32; - - if(uint32 oflow = a & 010001000100) - a |= oflow - (oflow>>6); - - a &= 07700770077; - output[x] = (a | a>>18) & 0777777; - } - } -} - - -#include "bg.cpp" -#include "obj.cpp" - - -uint32 PPU::readPalette(uint32 addr) { - addr &= ~3; - uint32* p = addr < 0x200? &bgPal[addr>>1 & 0xfe] : &objPal[addr>>1 & 0xfe]; - - uint5 b0 = p[0]>>13, g0 = p[0]>>7, r0 = p[0]>>1; - uint5 b1 = p[1]>>13, g1 = p[1]>>7, r1 = p[1]>>1; - - return b0<<10 | g0<<5 | r0<<0 | b1<<26 | g1<<21 | r1<<16; -} - -void PPU::writePalette(uint32 addr, uint32 size, uint32 data) { - uint32 mask = 0xffffffff; - - if(size == Byte) size = Half; - if(size == Half) addr &= ~1, mask = 0xffff << 8*(addr & 3); - if(size == Word) addr &= ~3; - - uint32* p = addr < 0x200? &bgPal[addr>>1 & 0xfe] : &objPal[addr>>1 & 0xfe]; - - uint5 b0 = data>>10, g0 = data>> 5, r0 = data>> 0; - uint5 b1 = data>>26, g1 = data>>21, r1 = data>>16; - - if(mask & 0x0000ffff) p[0] = b0<<13 | g0<<7 | r0<<1; - if(mask & 0xffff0000) p[1] = b1<<13 | g1<<7 | r1<<1; -} - -uint32 PPU::readOam(uint32 addr) { - addr &= ~3; - - objinfo& obj = this->obj[addr/8]; - affineparam& tf = this->objTransform[addr/32]; - - switch(addr & 4) { - case 0: - return obj.y<<0 | obj.renderMode<<8 | obj.kind<10 - | obj.mosaic<<12 | obj.depth<<13 | obj.size<<14 - | obj.x<<16 | obj.transform<<25 | obj.shape<<30; - - case 4: - return obj.index<<0 | obj.priority<<10 | obj.palette<<12 - | tf.m[addr>>3 & 3]; - } -} - -void PPU::writeOam(uint32 addr, uint32 size, uint32 data) { - if(size == Byte) return; - - if(size == Word) { - addr &= ~3; - writeOam(addr+0, Half, data>>0); - writeOam(addr+2, Half, data>>16); - return; - } - - objinfo& obj = this->obj[addr/8]; - affineparam& tf = this->objTransform[addr/32]; - - switch(addr & 6) { - case 0: - obj.y = data>>0; - obj.renderMode = data>>8; - obj.kind = data>>10; - obj.mosaic = data>>12; - obj.depth = data>>13; - obj.shape = data>>14; - return; - - case 2: - obj.x = data>>0; - obj.transform = data>>9; - obj.size = data>>14; - return; - - case 4: - obj.index = data>>0; - obj.priority = data>>10; - obj.palette = data>>12; - return; - - case 6: - tf.m[addr>>3 & 3] = data; - return; - } -} - - - -uint32 PPU::regControl() { - return bgMode<<0 | bg0FromGPU<<3 | forceBlank<<7 | objInHBlank<<23 - | objTileMode<<4 | objBitmapMode<<5 | objTileStep<<20 | objBitmapStep<<22 - | bg[0].enable<<8 | bg[1].enable<<9 | bg[2].enable<<10 | bg[3].enable<<11 - | objEnable<<12 | winEnable[0]<<13 | winEnable[1]<<14 | winEnable[2]<<15 - | bgTileBase<<24 | bgMapBase<<27 | bgLargePal<<30 | objLargePal<<31; -} - -void PPU::regControl(uint32 data, uint32 mask) { - if(mask & 0x000000ff) { - bgMode = data>>0; - bg0FromGPU = data>>3; - objTileMode = data>>4; - objBitmapMode = data>>5; - forceBlank = data>>7; - } - if(mask & 0x0000ff00) { - bg[0].enable = data>>8; - bg[1].enable = data>>9; - bg[2].enable = data>>10; - bg[3].enable = data>>11; - objEnable = data>>12; - winEnable[0] = data>>13; - winEnable[1] = data>>14; - winEnable[2] = data>>15; - } - if(mask & 0x00f00000) { - objTileStep = data>>20; - objBitmapStep = data>>22; - objInHBlank = data>>23; - } - if(mask & 0xff000000) { - bgTileBase = data>>24; - bgMapBase = data>>27; - bgLargePal = data>>30; - objLargePal = data>>31; - } -} - -uint32 PPU::regBg(unsigned no) { - return bg[no].priority<<0 - | bg[no].tiles<<2 | bg[no].mosaic<<6 | bg[no].depth<<7 - | bg[no].map<<8 | bg[no].affineWrap<<13 | bg[no].size<<14; -} - -void PPU::regBg(unsigned no, uint32 data, uint32 mask) { - //bg0 = 17 00 map 23, size -, tiles --, pri 0, 3D - //bg1 = f8 8b map 24, size 3, tiles 02, pri 3, 256 color - //bg2 = b0 01 map 16, size 2, tiles 00, pri 1, 16-bit affine - //bg3 = b4 0a map 20, size 2, tiles 02, pri 2, 16-bit affine - if(mask & 0x00ff) { - bg[no].priority = data>>0; - bg[no].tiles = data>>2; - bg[no].mosaic = data>>6; - bg[no].depth = data>>7; - } - if(mask & 0xff00) { - bg[no].map = data>>8; - bg[no].affineWrap = data>>13; - bg[no].size = data>>14; - } -} - -uint32 PPU::regBgOffs(unsigned no) { - return bg[no].hoffs | bg[no].voffs<<16; -} - -void PPU::regBgOffs(unsigned no, uint32 data, uint32 mask) { - bg[no].hoffs ^= (bg[no].hoffs ^ data) & mask; data >>= 16; mask >>= 16; - bg[no].voffs ^= (bg[no].voffs ^ data) & mask; -} - -void PPU::regBgAffine(unsigned no, unsigned index, uint32 data, uint32 mask) { - if(index < 2) { - bg[no].transform.m[2*index+0] ^= (bg[no].transform.m[2*index+0] ^ data) & mask; data >>= 16; mask >>= 16; - bg[no].transform.m[2*index+1] ^= (bg[no].transform.m[2*index+1] ^ data) & mask; - } - if(index == 2) { - bg[no].originx ^= (bg[no].originx ^ data) & mask; - bg[no].linex = bg[no].originx; - } - if(index == 3) { - bg[no].originy ^= (bg[no].originy ^ data) & mask; - bg[no].liney = bg[no].originy; - } -} - -void PPU::regWinDims(unsigned index, uint32 data, uint32 mask) { - auto dims = index == 0? winX : winY; - - if(mask & 0x000000ff) dims[0][1] = data>>0; - if(mask & 0x0000ff00) dims[0][0] = data>>8; - if(mask & 0x00ff0000) dims[1][1] = data>>16; - if(mask & 0xff000000) dims[1][0] = data>>24; -} - -uint32 PPU::regWinArea() { - return winArea[0] | winArea[1]<<8 | winArea[3]<<16 | winArea[2]<<24; -} - -void PPU::regWinArea(uint32 data, uint32 mask) { - if(mask & 0x0000003f) winArea[0] = data>>0 & 0x3f; - if(mask & 0x00003f00) winArea[1] = data>>8 & 0x3f; - if(mask & 0x003f0000) winArea[3] = data>>16 & 0x3f; - if(mask & 0x3f000000) winArea[2] = data>>24 & 0x3f; -} - -uint32 PPU::regBlend() { - return blendAbove<<0 | blendMode<<6 | blendBelow<<8; -} - -void PPU::regBlend(unsigned index, uint32 data, uint32 mask) { - uint64 maskl = uint64(mask) << 32*index; - - if(maskl & 0x000000003full) blendAbove = data>>0; - if(maskl & 0x00000000c0ull) blendMode = data>>6; - if(maskl & 0x0000003f00ull) blendBelow = data>>8; - if(maskl & 0x00001f0000ull) blendAf = data>>16; - if(maskl & 0x001f000000ull) blendBf = data>>24; - if(maskl & 0x1f00000000ull) blendYf = data>>0; -} - - - -} \ No newline at end of file diff --git a/bsnes/nds/ppu/ppu.hpp b/bsnes/nds/ppu/ppu.hpp deleted file mode 100644 index 22049f2b..00000000 --- a/bsnes/nds/ppu/ppu.hpp +++ /dev/null @@ -1,148 +0,0 @@ - -struct PPU { - PPU(); - - void power(); - void scanline(); - - struct objinfo; - - void renderBgs(unsigned y); - void renderTiledBg(unsigned no, unsigned mapW, unsigned mapH, unsigned y); - void renderAffineBg(unsigned no, unsigned mapDepth, unsigned mapW, unsigned mapH, unsigned y); - void renderBitmapBg(unsigned no, unsigned mapDepth, unsigned mapW, unsigned mapH, unsigned y); - - void renderObjs(unsigned y); - void renderTiledObj (objinfo& obj, unsigned objw, unsigned objh, unsigned y); - void renderBitmapObj(objinfo& obj, unsigned objw, unsigned objh, unsigned y); - - uint32 readPalette(uint32 addr); - void writePalette(uint32 addr, uint32 size, uint32 data); - - uint32 readOam(uint32 addr); - void writeOam(uint32 addr, uint32 size, uint32 data); - - uint32 regControl(); - void regControl(uint32 data, uint32 mask); - - uint32 regBg(unsigned no); - void regBg(unsigned no, uint32 data, uint32 mask); - - uint32 regBgOffs(unsigned no); - void regBgOffs(unsigned no, uint32 data, uint32 mask); - - void regBgAffine(unsigned no, unsigned index, uint32 data, uint32 mask); - - void regWinDims(unsigned index, uint32 data, uint32 mask); - - uint32 regWinArea(); - void regWinArea(uint32 data, uint32 mask); - - uint32 regBlend(); - void regBlend(unsigned index, uint32 data, uint32 mask); - - // PPU #0: PPU #1: - // Has access to VRAM banks 0..6 More limited features - // BG0 can source 3D GPU output Has access to VRAM banks 2,3,7,8 - // Can use frame- and render-buffers Max 128K BG, 128K OBJ - // Max 512K BG, 256K OBJ - int which; - uint1 powered; - - // Internal pixel format: pplllMBAF aaaaa bbbbbb gggggg rrrrrr - enum { - pxPriority = 1<<30, // p - from BG control - pxLayer = 1<<27, // l - 1: OBJ, 2..5:BG, 6:backdrop - pxMosaic = 1<<26, // M - pxBlendBelow = 1<<25, // B - pxBlendAbove = 1<<24, // A - pxBlendForce = 1<<23, // F - for 3D/OBJ pixel - pxAlpha = 1<<18, // a - alpha (0=solid) - }; - - uint32 output[256]; - - uint32 above[256 + 16]; - uint32 below[256 + 16]; - uint32 objLayer[256 + 16]; - - uint32 bgPal[256]; - uint32 objPal[256]; - - union affineparam { - struct { - int16 dx_dh, dx_dv; // A, B - int16 dy_dh, dy_dv; // C, D - }; - int16 m[4]; - }; - - struct bginfo { - uint1 enable; - uint1 mosaic, depth; - uint1 affineWrap; - uint2 priority; - uint2 size; - uint5 map; // 2K offset for maps / 16K for bitmaps - uint4 tiles; // 16K offset for tiles - uint2 palette; // 8K offset for large palette mode - - uint9 hoffs, voffs; // Tiled scrolling - int32 originx, originy; // Affine settings - int32 linex, liney; - affineparam transform; - }; - - struct objinfo { - uint2 kind; enum { none=0, blend=1, window=2, bitmap=3 }; - uint2 renderMode; enum { normal=0, affine=1, hidden=2, affineDouble=3 }; - uint1 mosaic; - uint1 depth; - uint2 size; - uint2 shape; enum { square=0, wide=1, tall=2 }; - uint5 transform; enum { hflip=8, vflip=16 }; - int9 x; - uint8 y; - uint10 index; - uint2 priority; - uint4 palette; // subpalette for tiled; alpha for bitmap sprites - }; - - uint1 forceBlank; - - uint1 bgLargePal; // 256-color BGs use system.vmap.bgpal - uint1 bg0FromGPU; // Display 3D rendering on BG0 - uint3 bgMode; // Determines affine vs. tiled layers - uint3 bgTileBase; // 64K starting base for tiles - uint3 bgMapBase; // 64K starting base for maps - uint4 bgMosaicX; - uint4 bgMosaicY; - bginfo bg[4]; - - uint1 objEnable; - uint1 objInHBlank; - uint1 objLargePal; // 256-color OBJs use system.vmap.objpal - uint1 objTileMode; // 0 = 256x256 px sprite sheet, 1 = linear - uint2 objBitmapMode; // 0 = 128x256, 1 = 256x256, 2..3 = linear - uint2 objTileStep; // tile index << in linear mode - uint1 objBitmapStep; // - uint4 objMosaicX; - uint4 objMosaicY; - objinfo obj[128]; - - affineparam objTransform[32]; - - uint1 winEnable[3]; // [win0, win1, winobj, winout] - uint8 winArea[4]; // BLD, OBJ, BG3..BG0 - uint8 winX[2][2]; // - uint8 winY[2][2]; // not uint9 - Nintendo's oversight - uint8 window[256+16]; // window no.<<6 | area - - uint2 blendMode; enum { alphaBlend=1, lighten=2, darken=3 }; - uint6 blendAbove; // BG0..BG3, OBJ, lignten/darken BD - uint6 blendBelow; // BG0..BG3, OBJ, blend over BD - uint5 blendAf, blendBf; // alphaBlend coefficients - uint5 blendYf; // lighten/darken coefficient -}; - -extern PPU ppu[2]; diff --git a/bsnes/nds/slot1/slot1.cpp b/bsnes/nds/slot1/slot1.cpp deleted file mode 100644 index f30232d9..00000000 --- a/bsnes/nds/slot1/slot1.cpp +++ /dev/null @@ -1,244 +0,0 @@ -#include - -namespace NintendoDS { - -Slot1 slot1; - - -Slot1::Slot1() { - card = nullptr; -} - -void Slot1::power() { - if(card) { - card->power(); - if(card->spi) - card->spi->power(); - } - enable = true; - - decryptLatency = 0; - responseLatency = 0; - xorData = 0; - xorCmds = 0; - dataReady = 0; - blockSize = 0; - clock = 0; - secureMode = 0; - transferPending = 0; - transferIrq = 0; - transferLength = 0; - - command = 0; - lfsr[0] = 0; - lfsr[1] = 0; - - spi.data = 0; - spi.baud = 0; - spi.hold = 0; - spi.busy = 0; - spi.enable = 0; -} - -void Slot1::load(GameCard* card) { - this->card = card; - if(card->spi) - card->spi->power(); -} - -GameCard* Slot1::unload() { - //if(card && card->spi) - // card->spi->select(false); - - auto r = card; - card = nullptr; - return r; -} - - -void Slot1::startRomTransfer() { - transferPending = true; - transferLength = 0; - - if(blockSize == 7) transferLength = 4; - else if(blockSize) transferLength = 512 << (blockSize-1); - - if(transferLength) dataReady = true; - else transferPending = false; - - if(card) card->command(command); - - // Hack for now, until we implement timing. Should test whether the ARM9 - // halts during this entire DMA - one complete word transfers every 40 or - // 64 clocks at 66MHz. - CPUCore *arm = arm9.slot1access? (CPUCore*)&arm9 : (CPUCore*)&arm7; - //while(transferLength > 0 && arm->dmaTrigger(0xf, 5)) /**/; - int ch = -1; - for(unsigned n = 0; n < 4; n++) - if(arm->dma[n].enable && arm->dma[n].trigger == 5) - ch = n; - - while(ch >= 0 && transferLength > 0) - arm->dmaTransfer(ch); -} - -uint8 Slot1::readRom() { - uint8 data = 0xff; - - if(transferLength) { - // Empty slot simply returns 0xff - if(card) data = card->read(); - - if(!--transferLength) { - dataReady = false; - transferPending = false; - - if(transferIrq) { - if(arm9.slot1access == 0) arm7.interrupt.flags |= CPUCore::irqCardDone; - if(arm9.slot1access == 1) arm9.interrupt.flags |= CPUCore::irqCardDone; - } - } - } - return data; -} - -uint8 Slot1::spiTransfer(uint8 data) { - if(!card || !card->spi) - return 0xff; - - auto device = card->spi; - device->select(true); - uint8 r = device->transfer(data); - device->select(spi.hold); - return r; -} - - -GameCard::~GameCard() { - delete spi; -} - -GameCard::GameCard(uint32 id) { - rom.size = 0x10000; - rom.data = new uint8[rom.size]; - memset(rom.data, 0xff, rom.size); - - size = bit::round(rom.size); - chipId = id; - spi = nullptr; -} - -GameCard::GameCard(const stream& memory, uint32 esize, uint32 id) { - rom.size = esize; - rom.data = new uint8[rom.size]; - memset(rom.data, 0xff, rom.size); - memory.read(rom.data, min(memory.size(), rom.size)); - - size = bit::round(rom.size); - sha256 = nall::sha256(rom.data, rom.size); - chipId = id; - spi = nullptr; -} - -void GameCard::power() { - state = idle; -} - -void GameCard::command(uint64 command) { - if((command>>56) == 0xb7) { - state = readData; - offset = command>>24 & 0x00000fff; - block = command>>24 & 0xfffff000; - block &= size-1; - - // Once initialized, forbid reading the header and startup code. - if(block < 0x8000) block += 0x8000; - } - if((command>>56) == 0xb8) { - state = readId; - offset = 0; - } -} - -uint8 GameCard::read() { - uint8 r = 0xff; - - if(state == readData) { - // We remain in this state indefinitely, until the next command. - // However, reading from most (?) game cards wraps at 4K intervals. - uint32 addr = (block + offset++) & size-1; - offset &= 0xfff; - - // Cards come in 2^n ROM sizes, however many images have the empty space - // trimmed off. Homebrew images aren't even padded out! Rather than waste - // memory, just check for this and return $ff. - if(addr < rom.size) - r = rom.data[addr]; - } - - if(state == readId) { - // Need to ensure the matching ID is in RAM or games won't run - // (where does the firmware put it?) - r = 0;/**/chipId >> 8*offset++; - offset &= 3; - } - return r; -} - - - -void IRPort::power() { - bypass = false; - command = 0; - if(slave) - slave->power(); -} - -void IRPort::select(bool state) { - if(bypass) { - slave->select(state); - } - if(state == false) { - bypass = false; - command = 0; - } -} - -uint8 IRPort::transfer(uint8 data) { - if(bypass) { - // Pass transfers through to flash memory - if(slave) return slave->transfer(data); - else return 0xff; - } - - if(command == 0x00) { - command = data; - - // Engage passthrough mode - allows access to save data. - if(command == 0x00) { - bypass = true; - return 0xff; - } - - if(command == 0x01) { - // Receive? HG/SS expect an 8-bit packet size, - // then 0..185 bytes, all XORed with $aa. - return 0x00; - } - - if(command == 0x02) { - // Write a packet, maybe to transmit buffer - return 0xff; - } - - if(command == 0x08) { - // ID of some kind? Is it even a valid command? - // Returns $aa after powerup - haven't tested the Pokewalker with it. - // Pokemon HG/SS frequently check this, even when not communicating. - return 0xaa; - } - } - return 0xff; -} - -} diff --git a/bsnes/nds/slot1/slot1.hpp b/bsnes/nds/slot1/slot1.hpp deleted file mode 100644 index 05219ef6..00000000 --- a/bsnes/nds/slot1/slot1.hpp +++ /dev/null @@ -1,113 +0,0 @@ - -struct GameCard; -struct SPIDevice; - -// Pins 1-17: GND, Clock, -, /ROM, /RESET, /SPI, /IRQ, VCC, D0-D7, GND -// -// This is a hybrid serial-parallel bus, one byte transferred each clock. -// Both the cards and the slot support XOR obfuscation using a 39-bit LFSR, -// and some commands are further encrypted via a Blowfish variant. -// -// Transfer rates are 33MHz /5 or /8, which is 4-6MB/sec, and there's a -// 32-bit buffer making it possible to DMA straight to VRAM. For perspective, -// 6MB/s is enough to stream 256x192x16bpp video + audio at 60fps. - -struct Slot1 { - Slot1(); - void power(); - void load(GameCard* card); - GameCard* unload(); - - void startRomTransfer(); - uint8 readRom(); - uint8 spiTransfer(uint8 data); - - GameCard *card; - - uint1 enable; - - // ROM interface - uint1 clock; // 33MHz / {5, 8} - uint13 decryptLatency; // clocks to wait for card to decrypt command - uint6 responseLatency; // clocks to wait for response (data buffering?) - uint2 xorData; // XOR data received (2 bits?) - uint1 xorCmds; // XOR commands sent - uint1 dataReady; // 32 bits buffered and ready in read port - uint3 blockSize; // {0, 512 bytes (usual), 1K-16K, 32 bits} - uint1 secureMode; // ? - uint1 transferIrq; // generate IRQ at end of block - uint1 transferPending; // still more bytes to transfer? - uint32 transferLength; // # bytes remaining - - uint64 command; // latch holding 8 command bytes for next transfer - uint64 lfsr[2]; // registers used to obfuscate communication - - // Serial interface for EEPROM, flash, and peripheral access. - // Each transfer writes and reads 8 bits, one bit per clock. - // Pins D6/D7 do double duty as data in/out respectively. - struct SPI { - uint8 data; // read from last transfer - uint2 baud; // 4MHz >> n - uint1 enable, busy, hold; - } spi; -}; - -struct GameCard { - virtual ~GameCard(); - GameCard(uint32 id); - GameCard(const stream& memory, uint32 size, uint32 id); - - virtual void power(); - virtual void command(uint64 command); - virtual uint8 read(); - - int state; enum { idle, readData, readId }; - uint32 block; // 4K block for reading - uint32 offset; // byte offset - uint32 size; // power of 2 rom size - uint64 lfsr[2]; // for obfuscation - uint32 chipId; - string sha256; - - StaticMemory rom; - SPIDevice *spi; -}; - -struct IRPort : SPIDevice { - IRPort() : slave(nullptr) { } - IRPort(SPIDevice *slave) : slave(slave) { } - - void power(); - void select(bool state); - uint8 transfer(uint8 data); - - SPIDevice *slave; - bool bypass; - uint8 command; -}; - -struct S1EEPROM : SPIDevice, StaticMemory { - void select(bool state); - uint8 transfer(uint8 data); - - int state; enum { idle, params, dataIo }; - uint8 command; enum { - cmdWriteDisable, cmdWriteEnable, // 0x04, 0x06 - cmdWriteStatus, cmdReadStatus, // 0x01, 0x05 - cmdWrite, cmdRead, // 0x02, 0x03 - cmdReadID, // 0x9f - }; - uint8 numArgs; - uint32 offset; - - // Status register - uint1 busy; - uint1 writeEnable; - uint2 writeProtect; - uint1 statusLock; - - uint1 unlockable; // /W pin, presumably enabled on game cards -}; - - -extern Slot1 slot1; diff --git a/bsnes/nds/slot2/slot2.cpp b/bsnes/nds/slot2/slot2.cpp deleted file mode 100644 index e69de29b..00000000 diff --git a/bsnes/nds/slot2/slot2.hpp b/bsnes/nds/slot2/slot2.hpp deleted file mode 100644 index e69de29b..00000000 diff --git a/bsnes/nds/system/clock.cpp b/bsnes/nds/system/clock.cpp deleted file mode 100644 index 3ddd7376..00000000 --- a/bsnes/nds/system/clock.cpp +++ /dev/null @@ -1,239 +0,0 @@ - -Clock::~Clock() { } - -Clock::Clock() { - stoppedSec = 0; - stoppedUSec = 0; -} - -void Clock::reset() { - status1 = 0; year = 0; hour = 0; - status2 = 0; month = 1; minute = 0; - adjust = 0; day = 1; second = 0; - userByte = 0; weekday = 0; - - for(int i = 0; i < 2; i++) - for(int j = 0; j < 3; j++) - alarm[i].setting[j] = 0; -} - -void Clock::power() { - secondsTickPending = hold = false; - intr[0] = intr[1] = lag = 0; - lastClk = lastCs = output = false; - command = buffer = nbits = dataOut = 0; - - // The clock is 32768 Hz but we need twice that, because serial - // interrupts are edge sensitive. - event.action = [&]() { - tick(); - arm7.event.queue.add(2*33513982/(2*32768), event); - }; - arm7.event.queue.add(2*33513982/(2*32768), event); -} - -uint4 Clock::io(uint4 pins) { - uint1 dataIn = pins>>0; - uint1 clk = pins>>1; - uint1 cs = pins>>2; - - if(cs != lastCs && !(lastCs = cs)) { - command = nbits = 0; - output = false; - return 0xf; - } - // Wait for falling CLK edge with CS high.. - if(clk != lastClk && !(lastClk = clk)) { - // Rotate data through the buffer - dataOut = buffer; - buffer = dataIn<<7 | buffer>>1; - - if(++nbits == 0) { - // Have we got a full byte to act on? - - // Accept a new command. They're MSB first, unlike data: - if(!command && (buffer & 0x0f) == 6) { // 0110 - command = buffer & 0x7f; // ccc - output = buffer & 0x80; // D - index = 0; - - // Prevent the time changing while read - if(command == 0x26 || command == 0x66) - hold = true; - - if(output == false) return 0xf; - else /*fall through and latch output byte for reading*/; - } - if(command == 0x06) field(status1, resetBit|hourMode); - if(command == 0x46) field(status2, int1Mode|int2Mode|testMode); - if(command == 0x26) dateTime(); - if(command == 0x66) dateTime(); - if(command == 0x16) alarmTime(0); - if(command == 0x56) alarmTime(1); - if(command == 0x36) field(adjust, 0xff); - if(command == 0x76) field(userByte, 0xff); - } - } - return output? dataOut | 0xe : 0xf; -} - - - -void Clock::field(uint8& src, uint8 mask) { - if(command == 0x06 && output == 0 && (buffer & resetBit)) { - reset(); buffer &= ~resetBit; - } - if(output) buffer = src; - else src ^= (src ^ buffer) & mask; -} - -void Clock::dateTime() { - if(index >= 7) return; - if(command == 0x66) // start from time field - index = max(4, index); - - bool fixHour = !(status1 & hourMode) && index == 4; - - if(output) { - buffer = time[index++]; - if(fixHour && buffer >= 0x12) - buffer += 0x40 - 0x12; // Convert back to 12-hour + AM/PM - return; - } - time[index] = buffer; // Should correct these properly.. - if(fixHour && (buffer & 0x40)) - time[index] += 0x12 - 0x40; // Convert from 12-hour mode - index++; -} - -void Clock::alarmTime(unsigned no) { - if(index >= 3) return; - if(output) buffer = alarm[no].setting[index++]; - else alarm[no].setting[index++] = buffer; -} - - - -bool Clock::incBCD(uint8& val, uint8 first, uint8 last) { - val++; - if((val & 0x0f) == 0x0a) val += 0x06; - if((val & 0xf0) == 0xa0) val += 0x60; - if(val > last) val = first; - return val == first; // carry out -} - -void Clock::tick() { - bool previously = intr[0] | intr[1]; - - if(++counter == 0) - secondsTickPending = true; - - // Ticks can be held for up to 500 ms while reading the time. - if(secondsTickPending && (hold == false || counter >= 2*16384)) { - lag = counter; - tickSecond(); - } - - switch(status2 & int2Mode /*0..1*/) { - case 0: intr[1] = 0; break; - default: break; // Alarm 2 - checked in tickSecond - } - - switch(status2 & int1Mode /*0..15*/) { - case 0: intr[0] = 0; break; - case 4: break; // Alarm 1 - checked in tickSecond - - case 1: /**/; - case 5: // Selectable frequency - often used as seconds interrupt. - intr[0] = 0; // /IRQ output is the AND of the selected divisors. - for(unsigned divisor = 0; divisor <= 4; divisor++) // 1..16 Hz - intr[0] |= (~counter >> 15-divisor) & (alarm[0].minute >> divisor) & 1; - break; - - case 2: /**/; // Start-of-minute interrupts - case 6: intr[0] |= !second && counter-lag < 2*4u; break; // latched - case 3: intr[0] = second < 0x30; break; // 30 sec duty - case 7: intr[0] = counter-lag < lag+2*128u; break; // 128 ticks duty - - default: intr[0] = !(counter & 1<<0); break; // 32KHz clock - } - - if(intr[0]) status1 |= int1Flag; - if(intr[1]) status1 |= int2Flag; - - bool interrupt = intr[0] | intr[1]; - - if(arm7.sio.irq && interrupt && previously == false) { - //arm7.raiseIrq(CPUCore::irqClock); - arm7.interrupt.flags |= CPUCore::irqClock; - } -} - -void Clock::tickSecond() { - secondsTickPending = false; - - if( incBCD(second, 0, 0x59) - && incBCD(minute, 0, 0x59) - && incBCD(hour, 0, 0x23)) - tickDay(); - - // Check alarms - not sure how this is supposed to work yet. - // The datasheet implies this is checked each minute, something like: - // d:hh:mm weekly d:**:mm hourly for one day a week? - // *:hh:mm daily d:**:** every minute for one day a week? - // *:**:mm hourly? d:hh:** every minute for one hour on one day? - // *:**:** every minute? *:hh:** every minute for one hour a day - if(second == 0x00) { - bool enable[2] = { - (status2 & int1Mode) == 4, // Alarm 1 - (status2 & int2Mode) != 0, // Alarm 2 - }; - // Triggered at start of minute; cleared by disabling alarm - for(unsigned i = 0; i < 2; i++) - if(enable[i] - && (weekday == (alarm[i].weekday & 0x07) || alarm[i].weekday < 0x80) - && (hour == (alarm[i].hour & 0x1f) || alarm[i].hour < 0x80) - && (minute == (alarm[i].minute & 0x3f) || alarm[i].minute < 0x80)) - intr[i] = 1; - - } -} - -void Clock::tickDay() { - if(++weekday == 7) weekday = 0; - - unsigned y = 10*(year>>4) + (year & 15); - unsigned daysIn[32] = { 0, // (invalid) - 0x31,0x28+!(y % 4), // Jan..Feb - 0x31,0x30,0x31,0x30,0x31, // Mar..Jul - 0x31,0x30, 0,0,0,0,0,0, // Aug..Sep (+ invalid months) - 0x31,0x30,0x31 // Oct..Dec - }; - incBCD(day, 1, daysIn[month & 31]) - && incBCD(month, 1, 0x12) - && incBCD(year, 0, 0x99); -} - - -void Clock::thaw(int64 curSec, int64 curUSec) { - // Calculate time elapsed while the emulation wasn't running.. - // Then advance RTC to make up for it. - int64 secs = curSec - stoppedSec; - int64 usecs = curUSec - stoppedUSec; - if(usecs < 0) secs -= 1, usecs += 1000000; - - int32 ticks = counter + usecs * 32768/1000000; - counter = ticks; - if(ticks >= 32768) secs += 1; - - while(secs > 86400) { secs -= 86400; tickDay(); } - while(secs > 0) { secs -= 1; tickSecond(); } - - stoppedSec = curSec; - stoppedUSec = curUSec; -} - -void Clock::freeze(int64 curSec, int64 curUSec) { - stoppedSec = curSec; - stoppedUSec = curUSec; -} diff --git a/bsnes/nds/system/eventqueue.hpp b/bsnes/nds/system/eventqueue.hpp deleted file mode 100644 index 6ae71226..00000000 --- a/bsnes/nds/system/eventqueue.hpp +++ /dev/null @@ -1,120 +0,0 @@ - -template struct Event_of { - uint32 time; - uint32 node; - T action; - - Event_of() : time(0), node(0) {} - Event_of(T action) : time(0), node(0), action(action) {} - inline bool operator<(const Event_of& rhs) const { return time - rhs.time >= 0x80000000u; } - inline bool operator<(uint32 rhs) const { return time - rhs >= 0x80000000u; } -}; - -template struct EventQueue_of { - typedef Event_of Elem; - - uint32 time; - - EventQueue_of(uint32 capacity) : size(0), time(0) { - //items.reserve(capacity+1); // to simplify math, items[0] is unused - for(unsigned n = 0; n < capacity+1; n++) - items[n] = nullptr; - } - - void reset() { - clear(); - time = 0; - } - void clear() { - for(unsigned n = 1; n <= size; n++) { - items[n]->node = 0; - items[n] = nullptr; - } - size = 0; - } - bool valid(uint32 n = 1) { - return (2*n+0 > size || *(items[n]) < items[2*n+0]->time+1 && valid(2*n+0)) - && (2*n+1 > size || *(items[n]) < items[2*n+1]->time+1 && valid(2*n+1)); - } - void add(uint32 dt, Elem& e) { - if(e.node) { - remove(e); - return add(dt, e); - } - uint32 old = e.time; - e.time = time + dt; - e.node = ++size; - bubble(e); - if(valid() == false) asm volatile("\n\t int $3"); - } - void remove(Elem& e) { - if(e.node == 0) return; - - items[e.node] = items[size]; - items[e.node]->node = e.node; - items[size--] = nullptr; - - if(size > 1 && e.node <= size) { - Elem& m = *(items[e.node]); - - if(m < e) { - // This can happen if removing something besides the min element. - bubble(m); - if(valid() == false) asm volatile("\n\t int $3"); - } - else { - while(2*m.node <= size) { - uint32 l = 2*m.node; - uint32 r = 2*m.node + (l < size); - uint32 c = *(items[r]) < *(items[l])? r : l; - - if(!(*(items[c]) < m)) break; - - items[m.node] = items[c]; - items[m.node]->node = m.node; - m.node = c; - } - items[m.node] = &m; - if(valid() == false) asm volatile("\n\t int $3"); - } - } - e.node = 0; - } - - inline void step(uint32 ticks) { - ticks += time; // relative -> absolute time - time = ticks; // default case for early out - - // Caution! We're running under the assumption our queue is never empty. - // Fortunately, due to audio/video events, that's true in dasShiny. - // Gives around 16% speedup in some cases. - if(!(*(items[1]) < ticks)) return; // early out, nothing to do - - auto &next = items[1]; - do { - Elem& e = *next; - time = e.time; // update the time so add() - remove(e); // works during the callback. - e.action(); - } while(/*size && */*next < ticks); - - if(time - ticks >= 0x80000000u) - time = ticks; - } - -//private: - //linear_vector items; - Elem* items[64]; - uint32 size; - - void bubble(Elem& e) { - while(1 < e.node && e < *(items[e.node/2])) { - items[e.node] = items[e.node/2]; - items[e.node]->node = e.node; - e.node /= 2; - } - items[e.node] = &e; - } - - EventQueue_of(); -}; diff --git a/bsnes/nds/system/powermgr.cpp b/bsnes/nds/system/powermgr.cpp deleted file mode 100644 index cfb56820..00000000 --- a/bsnes/nds/system/powermgr.cpp +++ /dev/null @@ -1,14 +0,0 @@ - -PowerMgr::~PowerMgr() { } - -void PowerMgr::power() { - -} - -void PowerMgr::select(bool state) { - -} - -uint8 PowerMgr::transfer(uint8 data) { - return 0; -} diff --git a/bsnes/nds/system/system.cpp b/bsnes/nds/system/system.cpp deleted file mode 100644 index 61c5e60b..00000000 --- a/bsnes/nds/system/system.cpp +++ /dev/null @@ -1,547 +0,0 @@ -#if !defined(_WIN32) - #include - #include -#else - // Suppress mingw's timeval which uses 32-bit longs - #define _TIMEVAL_DEFINED - #include - #include - #include - - #if defined(__amd64__) || defined(_M_AMD64) - struct timeval { - int64_t tv_sec, tv_usec; - }; - #define timegm(tm) _mkgmtime64(tm) - #define gmtime(tv) _gmtime64(tv) - #else - //Windows 32-bit run-time doesn't have 64-bit time functions - struct timeval { - time_t tv_sec, tv_usec; - }; - #define timegm(tm) mktime(tm) - #define gmtime(tv) localtime(tv) - #endif - - #define gettimeofday(tv,tz) gettimeofday64(tv,tz) - - int gettimeofday64(struct timeval *tv, struct timezone *tz) { - FILETIME ft; - GetSystemTimeAsFileTime(&ft); // UTC in 100ns units - - // UNIX epoch: Jan 1 1970 - // Windows epoch: Jan 1 1601 - // - // 1970 - 1601 = 369 years = 11636784000 sec - // 89 leap years => +89 days = +7689600 sec - int64_t diff = 11644473600LL * 10000000LL; - int64_t ns = ft.dwLowDateTime + ft.dwHighDateTime * (1LL<<32) - diff; - - tv->tv_sec = ns / 10000000; - tv->tv_usec = ns % 10000000 / 10; - } -#endif - - -namespace NintendoDS { - -System system; - - -SPIDevice::~SPIDevice() { } - - -VRAMMapping::VRAMMapping() { - data = nullptr; size = 0; - dirtyBits = nullptr; -} -VRAMMapping::VRAMMapping(HalfMemory& target, uint8 *dirtyBits, unsigned pageno) - : dirtyBits(dirtyBits + pageno*256/0x4000) -{ - data = target.data + 0x4000/2*pageno; size = 0; -} -VRAMMapping::~VRAMMapping() { - data = nullptr; size = 0; - dirtyBits = nullptr; -} - -uint16& VRAMMapping::operator[](uint32 addr) { - return data? data[addr>>1 & 0x1fff] - : system.unmappedVram[addr>>1 & 0x1fff]; -} - -uint32 VRAMMapping::read(uint32 addr, uint32 size) { - if(!data) return 0; - return HalfMemory::read(addr & 0x3fff, size); -} -void VRAMMapping::write(uint32 addr, uint32 size, uint32 word) { - if(!data) return; HalfMemory::write(addr & 0x3fff, size, word); - if(!dirtyBits) return; dirtyBits[(addr & 0x3fff)/256] = 0xff; -} -bool VRAMMapping::dirty(uint32 addr) { - return dirtyBits && dirtyBits[(addr & 0x3fff)/256]; -} - - -System::System() { - firmware.data = new uint8 [(firmware.size = 0x080000)/1](); - - ewram.data = new uint16[(ewram.size = 0x400000)/2]; - iwram.data = new uint32[(iwram.size = 0x010000)/4]; - swram[0].data = new uint32[(swram[0].size = 0x004000)/4]; - swram[1].data = new uint32[(swram[1].size = 0x004000)/4]; - - vram[0].data = new uint16[(vram[0].size = 0x020000)/2]; - vram[1].data = new uint16[(vram[1].size = 0x020000)/2]; - vram[2].data = new uint16[(vram[2].size = 0x020000)/2]; - vram[3].data = new uint16[(vram[3].size = 0x020000)/2]; - vram[4].data = new uint16[(vram[4].size = 0x010000)/2]; - vram[5].data = new uint16[(vram[5].size = 0x004000)/2]; - vram[6].data = new uint16[(vram[6].size = 0x004000)/2]; - vram[7].data = new uint16[(vram[7].size = 0x008000)/2]; - vram[8].data = new uint16[(vram[8].size = 0x004000)/2]; - - wxram.data = new uint16[(wxram.size = 0x002000)/2]; - - memset(firmware.data, 0, firmware.size); - - callerThread = nullptr; - activeThread = nullptr; - running = false; -} - -void System::mapVram(VRAMMapping* loc, uint8 *dirtyBits, unsigned npages, HalfMemory& bank) { - for(unsigned offset = 0; offset < npages; offset++) - loc[offset] = VRAMMapping{ bank, dirtyBits, offset % (bank.size/0x4000) }; -} - -void System::clearVmap() { - for(unsigned n = 0; n < 8; n++) { - for(auto &m : vmap.arm9[n]) m = VRAMMapping{}; - } - for(auto &m : vmap.arm7) m = VRAMMapping{}; - for(auto &m : vmap.tex) m = VRAMMapping{}; - for(auto &m : vmap.texpal) m = VRAMMapping{}; - for(auto &m : vmap.bgpal[0]) m = VRAMMapping{}; - for(auto &m : vmap.objpal[0]) m = VRAMMapping{}; - for(auto &m : vmap.bgpal[1]) m = VRAMMapping{}; - for(auto &m : vmap.objpal[1]) m = VRAMMapping{}; -} - -void System::updateVmap() { - static const uint32 offsets[] = { - 0x00000, 0x20000, 0x40000, 0x60000, 0x80000, 0x90000, 0x94000, 0x98000, 0xa0000 - }; - static const uint32 altOffsets[] = { - 0x00000, 0x04000, 0x10000, 0x14000 - }; - - clearVmap(); - gpu.texCache.reset(); - - auto bank = vmap.regs; - - for(unsigned n = 0; n < 7; n++) { - if(!bank[n].enable) continue; - - unsigned offset = offsets[n] >> 14; - unsigned npages = vram[n].size >> 14; - - int sel = bank[n].bus; - - // Restrict MST to valid options (some are mirrored) - if(n < 2 || n < 4 && sel > 4 || sel > 5) sel &= 3; - - if(sel == VRAMConfig::display) - mapVram(&vmap.arm9[4][offset], &vmap.dirty[offsets[n]/256], npages, vram[n]); - } - - // Banks 0-3, all are 128K, mapped at increments of the same size. - for(unsigned n = 0; n < 4; n++) { - if(!bank[n].enable) continue; - - unsigned offset = offsets[bank[n].offset] >> 14; - unsigned npages = vram[n].size >> 14; - - uint8* dirty = &vmap.dirty[offsets[n]/256]; - uint8* dirtyEnd = &vmap.dirty[offsets[n+1]/256]; - - VRAMMapping *bus = nullptr; - int sel = bank[n].bus; - if(n < 2 || sel > 4) sel &= 3; - - if( sel == VRAMConfig::bg0) bus = &vmap.bg(0, offset); - if(n < 2 && sel == VRAMConfig::obj0) bus = &vmap.obj(0, offset); - if(n >= 2 && sel == VRAMConfig::arm7) bus = &vmap.arm7[offset]; - if(n == 2 && sel == VRAMConfig::ppu1) bus = &vmap.bg(1, 0); - if(n == 3 && sel == VRAMConfig::ppu1) bus = &vmap.obj(1, 0); - - if(sel == VRAMConfig::tex) { - bus = &vmap.tex[offset]; - - // Discard dirty textures, then mark the locked pages clean. Lines - // 191..213 are available for texture updates; games wishing to do so - // will perform at least one {unlock, DMA, lock} cycle in that time. - gpu.texCache.flushDirty(n); - memset(dirty, 0, dirtyEnd-dirty); - } - if(bus) mapVram(bus, dirty, npages, vram[n]); - } - - // Banks 4-6 are 32K + 16K + 16K and carry over from the GBA. - // They always map into the first 128K of address space. - for(unsigned n = 4; n < 7; n++) { - if(!bank[n].enable) continue; - - uint8* dirty = &vmap.dirty[offsets[n]/256]; - uint8* dirtyEnd = &vmap.dirty[offsets[n+1]/256]; - - unsigned offset = n > 4? altOffsets[bank[n].offset] >> 14 : 0; - unsigned npages = vram[n].size >> 14; - - VRAMMapping *bus = nullptr; - int sel = bank[n].bus; - if(sel > 5) sel &= 3; - - if(sel == VRAMConfig::bg0) bus = &vmap.bg(0, offset); - if(sel == VRAMConfig::obj0) bus = &vmap.obj(0, offset); - if(sel == VRAMConfig::bgpal0) bus = &vmap.bgpal[0][offset]; - if(sel == VRAMConfig::objpal0) bus = &vmap.objpal[0][offset]; - - if(sel == VRAMConfig::texpal) { - bus = &vmap.texpal[offset]; - - // The current implementation caches textures in ABGR format, - // so we need to check for dirty palettes, too. - gpu.texCache.flushDirty(n); - memset(dirty, 0, dirtyEnd-dirty); - } - - if(bus) { - // Banks 5 and 6 (x) have offset 0 [x x ..............] - // mirroring that allows them to 1 [ x x ..128K banks..] - // map adjacent to larger banks. 2 [ x x ..............] - // Bank 4 (f) is fixed: 3 [ffff x x..............] - mapVram(bus + 0, dirty, npages, vram[n]); - if(n > 4) mapVram(bus + 2, dirty, npages, vram[n]); - } - } - - // These two banks are only used with PPU1. - for(unsigned n = 8; n < 10; n++) { - if(!bank[n].enable) continue; - - uint8* dirty = &vmap.dirty[offsets[n-1]/256]; - int sel = bank[n].bus & 3; - - if(sel == VRAMConfig::bg1) { - // These map in an odd sequence [hh hh ] - // where the Is mirror in pairs: [ ii ii] - mapVram(&vmap.bg(1, n==9? 2 : 0), dirty, 2, vram[n-1]); - mapVram(&vmap.bg(1, n==9? 6 : 4), dirty, 2, vram[n-1]); - } - if(n == 9 && sel == VRAMConfig::obj1) mapVram(&vmap.obj(1, 0), dirty, 8, vram[n-1]); - if(n == 8 && sel == VRAMConfig::bgpal1) mapVram(&vmap.bgpal[1][0], dirty, 8, vram[n-1]); - if(n == 9 && sel == VRAMConfig::objpal1) mapVram(&vmap.objpal[1][0], dirty, 8, vram[n-1]); - if(n == 8 && sel == VRAMConfig::display) mapVram(&vmap.arm9[4][38], dirty, 2, vram[n-1]); - if(n == 9 && sel == VRAMConfig::display) mapVram(&vmap.arm9[4][40], dirty, 1, vram[n-1]); - } - - // Still unimplemented: bank[7] for SWRAM - // (currently both ARM7 and ARM9 have access) - - // Apply mirroring to address spaces smaller than 512K - // Only needed in cases where it's possible to read out of bounds. - for(unsigned n = 0; n < 8; n++) { - // OBJ0 - 256K - vmap.obj(0, n+16) = vmap.obj(0, n+0); - vmap.obj(0, n+24) = vmap.obj(0, n+8); - // BG1, OBJ1 - 128K - vmap.bg(1, n+ 8) = vmap.bg(1, n); - vmap.bg(1, n+16) = vmap.bg(1, n); - vmap.bg(1, n+24) = vmap.bg(1, n); - vmap.obj(1, n+ 8) = vmap.obj(1, n); - vmap.obj(1, n+16) = vmap.obj(1, n); - vmap.obj(1, n+24) = vmap.obj(1, n); - } - - for(unsigned i = 0; i < 4; i++) - for(unsigned n = 0; n < 32; n++) - vmap.arm9[i][n+32] = vmap.arm9[i][n+0]; -} - -uint32 System::regVmap(unsigned index) { - if(index == 0) return vmap.regs[3]<<24 | vmap.regs[2]<<16 | vmap.regs[1]<<8 | vmap.regs[0]<<0; - if(index == 1) return vmap.regs[7]<<24 | vmap.regs[6]<<16 | vmap.regs[5]<<8 | vmap.regs[4]<<0; - if(index == 2) return vmap.regs[9]<<8 | vmap.regs[8]<<0; -} - -void System::regVmap(unsigned index, uint32 data, uint32 mask) { - if(mask & 0x000000ff) vmap.regs[4*index + 0] = data>>0; - if(mask & 0x0000ff00) vmap.regs[4*index + 1] = data>>8; - if(mask & 0x00ff0000 && index < 2) vmap.regs[4*index + 2] = data>>16; - if(mask & 0xff000000 && index < 2) vmap.regs[4*index + 3] = data>>24; - - updateVmap(); -} - - - -void System::loadArm7Bios(const stream& stream) { - delete[] arm7.bios.data; - - arm7.bios.size = stream.size(); - arm7.bios.data = new uint32[(arm7.bios.size + 3)/4]; - - for(unsigned n = 0; n < arm7.bios.size; n += 4) - arm7.bios.write(n, Word, stream.readl(4)); -} - - -void System::loadArm9Bios(const stream& stream) { - delete[] arm9.bios.data; - - arm9.bios.size = stream.size(); - arm9.bios.data = new uint32[(arm9.bios.size + 3)/4]; - - for(unsigned n = 0; n < arm9.bios.size; n += 4) - arm9.bios.write(n, Word, stream.readl(4)); -} - - -void System::loadFirmware(const stream& stream) { - delete[] firmware.data; - - firmware.size = stream.size(); - firmware.data = new uint8[firmware.size]; - for(unsigned n = 0; n < firmware.size; n++) - firmware.write(n, Byte, stream.read()); -} - -void System::saveFirmware(const stream& stream) { - for(unsigned n = 0; n < firmware.size; n++) - stream.write(firmware.read(n, Byte)); -} - - -void System::loadRTC(const stream& stream) { - struct timeval cur = {}; - gettimeofday(&cur, 0); - - clock.reset(); - clock.stoppedSec = cur.tv_sec; - clock.stoppedUSec = cur.tv_usec; - - if(!stream.size()) return; - - uint8* xml = new uint8[stream.size() + 1]; - stream.read(xml, stream.size()); - xml[stream.size()] = 0; - - XML::Document document((const char*)xml); - delete[] xml; - - if(document["rtc"].exists() == false) - return; - - auto &rtc = document["rtc"]; - //string model = rtc["model"].data; - - if(rtc["settings"].exists()) { - clock.status1 = hex(rtc["settings"]["status"].data); - clock.status2 = hex(rtc["settings"]["mode"].data); - clock.adjust = hex(rtc["settings"]["adjust"].data); - clock.userByte = hex(rtc["settings"]["scratch"].data); - } - if(rtc["clock"].exists()) { - lstring date = rtc["clock"]["date"].data.split("/"); - lstring time = rtc["clock"]["time"].data.split(":"); - string wday = rtc["clock"]["day"].data; - - if(date.size() >= 3 && time.size() >= 3) { - string sec = time[2]; - string frac = "0"; - - if(sec.position(".")) { - frac = sec.split(".")[1]; - sec = sec.split(".")[0]; - } - clock.weekday = hex(wday) & 0x07; - clock.year = hex(date[0]) & 0xff; - clock.month = hex(date[1]) & 0x1f; - clock.day = hex(date[2]) & 0x3f; - clock.hour = hex(time[0]) & 0x3f; - clock.minute = hex(time[1]) & 0x7f; - clock.second = hex(sec) & 0x7f; - clock.counter = hex(frac); - } - } - - for(unsigned i = 0; i < 2; i++) { - string alarm = {"alarm", i+1}; - if(rtc[alarm].exists() == false) continue; - - string wday = rtc[alarm]["day"].data; - lstring time = rtc[alarm]["time"].data.split(":"); - lstring mode = rtc[alarm]["mode"].data.split(","); - - clock.alarm[i].setting[0] = hex(wday) & 0x07; - - if(time.size() >= 2) { - clock.alarm[i].setting[1] = hex(time[0]) & 0x7f; - clock.alarm[i].setting[2] = hex(time[1]) & 0x7f; - } - for(auto &select : mode) { - if(select.iequals("day")) clock.alarm[i].weekday |= 0x80; - if(select.iequals("hour")) clock.alarm[i].hour |= 0x80; - if(select.iequals("minute")) clock.alarm[i].minute |= 0x80; - } - } - - if(rtc["saved"].exists()) { - lstring savedOn = rtc["saved"]["on"].data.split("/"); - lstring savedAt = rtc["saved"]["at"].data.split(":"); - string savedDst = rtc["saved"]["dst"].data; - - if(savedOn.size() >= 3 && savedAt.size() >= 3) { - struct tm last = {}; - string sec = savedAt[2]; - string usec = "0"; - - if(sec.position(".")) { - usec = sec.split(".")[1]; - sec = sec.split(".")[0]; - } - last.tm_isdst = savedDst != ""? integer(savedDst) : -1; - last.tm_yday = -1; - last.tm_year = decimal(savedOn[0]) - 1900; - last.tm_mon = decimal(savedOn[1]) - 1; - last.tm_mday = decimal(savedOn[2]); - last.tm_wday = -1; - last.tm_hour = decimal(savedAt[0]); - last.tm_min = decimal(savedAt[1]); - last.tm_sec = decimal(sec); - - struct timeval now = {}; - gettimeofday(&now, nullptr); - - clock.freeze(timegm(&last), decimal(usec)); - clock.thaw(now.tv_sec, now.tv_usec); - } - } -} - - -void System::saveRTC(const stream& stream) { - struct timeval tv = {}; - gettimeofday(&tv, nullptr); - clock.thaw(tv.tv_sec, tv.tv_usec); - clock.freeze(tv.tv_sec, tv.tv_usec); - - struct tm now = *gmtime(&tv.tv_sec); - - string saveDate = { decimal(1900 + now.tm_year), "/", decimal<2,'0'>(now.tm_mon+1), "/", decimal<2,'0'>(now.tm_mday) }; - string saveTime = { decimal<2,'0'>(now.tm_hour), ":", decimal<2,'0'>(now.tm_min), ":", decimal<2,'0'>(now.tm_sec), ".", decimal<6,'0'>(tv.tv_usec) }; - - string dateStr = { hex<4>(0x2000 + clock.year), "/", hex<2>(clock.month), "/", hex<2>(clock.day) }; - string timeStr = { hex<2>(clock.hour), ":", hex<2>(clock.minute), ":", hex<2>(clock.second), ".", hex<4>(clock.counter) }; - - string alarmTime[2], alarmDay[2], alarmMode[2]; - - for(unsigned i = 0; i < 2; i++) { - lstring conditions; - if(clock.alarm[i].weekday & 0x80) conditions[i].append("day"); - if(clock.alarm[i].hour & 0x80) conditions[i].append("hour"); - if(clock.alarm[i].minute & 0x80) conditions[i].append("minute"); - - alarmMode[i] = conditions.concatenate(","); - alarmDay[i] = hex<1>(clock.alarm[i].weekday & 7); - alarmTime[i] = { hex<2>(clock.alarm[i].hour & 0x3f), - ":", hex<2>(clock.alarm[i].minute & 0x7f) }; - }; - - string xml{ - "\n", - "\n", - " \n", - "\n", - " \n", - "\n", - " \n", - "\n", - " \n", - " \n", - "" - }; - stream.write((uint8*)(const char*)xml, xml.length()); -} - - - -void System::power() { - // Clear memory - memset(ewram.data, 0, ewram.size); - memset(iwram.data, 0, iwram.size); - memset(swram[0].data, 0, swram[0].size); - memset(swram[1].data, 0, swram[1].size); - memset(unmappedVram, 0, sizeof unmappedVram); - - for(unsigned n = 0; n < 9; n++) - memset(vram[n].data, 0, vram[n].size); - - // Reset VRAM mappings - for(auto &r : vmap.regs) r = 0x00; - clearVmap(); - memset(vmap.dirty, 0xff, sizeof vmap.dirty); - - arm9.config.arm9 = true; - arm9.config.arm7 = false; - arm7.config.arm9 = false; - arm7.config.arm7 = true; - arm9.other = &arm7; - arm7.other = &arm9; - - ppu[0].which = 0; - ppu[1].which = 1; - - arm7.power(); - arm9.power(); - clock.power(); - powerMgr.power(); - firmware.power(); - touchscreen.power(); - slot1.power(); - video.power(); - gpu.power(); - ppu[0].power(); - ppu[1].power(); - apu.power(); - wifi.power(); - - callerThread = co_active(); - activeThread = arm7.thread; // Required since right now ARM7 loads the binaries.. -} - -void System::run() { - callerThread = co_active(); - co_switch(activeThread); -} - -void System::frame() { - interface->videoRefresh(video.output, 256*4, 256, 384); - activeThread = co_active(); - co_switch(callerThread); -} - -#include "clock.cpp" -#include "powermgr.cpp" -#include "touchscreen.cpp" - -} diff --git a/bsnes/nds/system/system.hpp b/bsnes/nds/system/system.hpp deleted file mode 100644 index e1d8a73c..00000000 --- a/bsnes/nds/system/system.hpp +++ /dev/null @@ -1,231 +0,0 @@ -#include "eventqueue.hpp" - -typedef function Action; -typedef EventQueue_of EventQueue; -typedef EventQueue_of::Elem Event; - - -enum class Input : unsigned { - // REG_KEYINPUT (10 bits) - A, B, Select, Start, Right, Left, Up, Down, R, L, - - // REG_AUXINPUT (8 bits) - // - C, Z, W seem present, but unconnected - // - D is supposedly on debug units - X, Y, C, D, Z, W, Pen, Lid, - - // Touchscreen - PenX, PenY, PenZ1, PenZ2, -}; - - -struct SPIDevice { - virtual ~SPIDevice(); - virtual void power() = 0; - virtual void select(bool state) = 0; - virtual uint8 transfer(uint8 data) = 0; -}; - -#include "../memory/eeprom.hpp" -#include "../memory/fram.hpp" -#include "../memory/flash.hpp" - -struct PowerMgr : SPIDevice { - ~PowerMgr(); - void power(); - void select(bool state); - uint8 transfer(uint8 data); -}; - - -struct Touchscreen : SPIDevice { - ~Touchscreen(); - void power(); - void select(bool state); - uint8 transfer(uint8 data); - - bool penDown(); - - uint1 bitDepth; enum { read12, read8 }; - uint1 refMode; enum { diff, single }; - uint2 powerMode; enum { powerAuto, powerADC, powerRef, powerFull }; - uint3 input; enum { - temp0 = 0, temp1 = 7, - vbatt = 2, aux = 6, - ypos = 1, xpos = 5, - pressure0 = 3, pressure1 = 4, - }; - - uint32 adc; - uint12 last; -}; - - -struct Clock { - Clock(); - ~Clock(); - void reset(); - void power(); - uint4 io(uint4 pins); - - void dateTime(); - void alarmTime(unsigned no); - void field(uint8& src, uint8 mask); - - void tick(); - void tickSecond(); - void tickDay(); - bool incBCD(uint8& val, uint8 first, uint8 last); - - void freeze(int64 curSec, int64 curUSec); - void thaw(int64 curSec, int64 curUSec); - - - int64 stoppedSec, stoppedUSec; - - uint1 lastCs, lastClk; - uint8 buffer, dataOut; - uint3 nbits; - uint8 command, index; - bool output; - - uint8 status1; enum { - resetBit = 0x01, hourMode = 0x02, - int1Flag = 0x10, int2Flag = 0x20, - powerLow = 0x40, powerLost = 0x80 - }; - uint8 status2; enum { - int1Mode = 0x0f, - int2Mode = 0x40, testMode = 0x80 - }; - uint8 adjust; // clock rate fine adjustment - uint8 userByte; - - Event event; - uint16 counter; // 32KHz subsecond counter - uint1 intr[2]; // Interrupts (both go to IRQ pin) - uint1 hold; // Delays seconds tick while reading the time - uint16 lag; // How long the seconds tick was delayed - uint1 secondsTickPending; - - union { - struct { uint8 year, month, day, weekday, hour, minute, second; }; - struct { uint8 time[7]; }; - }; - union { - struct { uint8 weekday, hour, minute; }; - struct { uint8 setting[3]; }; - } alarm[2]; -}; - - -struct VRAMMapping : HalfMemory { - VRAMMapping(); - VRAMMapping(HalfMemory& target, uint8* dirtyBits, unsigned pageno); - ~VRAMMapping(); - - uint16& operator[](uint32 addr); - uint32 read(uint32 addr, uint32 size); - void write(uint32 addr, uint32 size, uint32 word); - bool dirty(uint32 addr); - void clearDirty(uint32 addr, uint32 size); - - uint8 *dirtyBits; -}; - - -struct System { - cothread_t callerThread; - cothread_t activeThread; - bool running; - - Flash firmware; - Touchscreen touchscreen; - PowerMgr powerMgr; - Clock clock; - - SDRAM ewram; // 4MB shared external WRAM - SRAM iwram; // 64KB 32-bit work RAM, private to ARM7 - SRAM swram[2]; // 16KB x 2 banks switchable 32-bit WRAM - HalfMemory vram[9]; // 656KB in 9 banks of 16-bit VRAM - HalfMemory wxram; // 8KB wireless packet buffer - - uint16 unmappedVram[0x2000]; - - struct VRAMConfig { - uint1 enable; - uint2 offset; - uint3 bus; // aka. MST or "Magic Selector Thing" - enum { - display=0, // all banks - bg0=1, // A,B,C,D,E,F,G - obj0=2, // A,B, E,F,G - arm7=2, // C,D - tex=3, // A,B,C,D - texpal=3, // E,F,G - bgpal0=4, // E,F,G - objpal0=5, // E?,F,G - ppu1=4, // C,D - bg1=1, // H,I - obj1=2, // I - bgpal1=2, // H - objpal1=3, // I - }; - - operator uint8() { - return enable<<7 | offset<<3 | bus<<0; - } - VRAMConfig& operator=(uint8 data) { - enable = data>>7; - offset = data>>3; - bus = data>>0; - return *this; - } - }; - - struct { - // Mappings for each graphics bus that can have VRAM banked onto it. - // Each page is 16K, the finest granularity. - VRAMMapping arm9[8][64]; // 8x1M arm9 map - 0x060,062,064,066,068,.. - VRAMMapping arm7[16]; // 256K arm7 map - 0x060.. - - // Locked memory can be used by the GPU, but isn't mapped in CPU space. - VRAMMapping tex[32]; // 512K locked texture memory - VRAMMapping texpal[8]; // 128K locked texture palettes - VRAMMapping bgpal[2][8]; // 32K locked BG palettes - VRAMMapping objpal[2][8]; // 8K locked OBJ palettes - - VRAMMapping &bg(int w, int i) { return arm9[0+w][i]; } - VRAMMapping &obj(int w, int i) { return arm9[2+w][i]; } - VRAMMapping &display(int i) { return arm9[4][i&31]; } - - VRAMConfig regs[10]; // A,B,C,D, E,F,G,SWRAM, H,I - - uint8 dirty[(512 + 96 + 48)*1024 / 256]; - } vmap; - - - void clearVmap(); - void updateVmap(); - void mapVram(VRAMMapping* loc, uint8 *dirtyBits, unsigned npages, HalfMemory& bank); - - uint32 regVmap(unsigned index); - void regVmap(unsigned index, uint32 data, uint32 mask); - - void loadArm7Bios(const stream&); - void loadArm9Bios(const stream&); - void loadFirmware(const stream&); - void loadRTC(const stream&); - - void saveFirmware(const stream&); - void saveRTC(const stream&); - - void power(); - void run(); - - void frame(); - - System(); -}; - -extern System system; diff --git a/bsnes/nds/system/touchscreen.cpp b/bsnes/nds/system/touchscreen.cpp deleted file mode 100644 index 0db32907..00000000 --- a/bsnes/nds/system/touchscreen.cpp +++ /dev/null @@ -1,112 +0,0 @@ - -Touchscreen::~Touchscreen() { } - -void Touchscreen::power() { - input = 0; - bitDepth = 0; - refMode = 0; - powerMode = 0; - adc = 0; - last = 0; -} - -void Touchscreen::select(bool state) { - if(state) return; - - adc = 0; -} - -bool Touchscreen::penDown() { - if(powerMode == 3) return true; // differs between NDS Lite and original? - - signed x = interface->inputPoll(ID::Port::Touchpad, 0, ID::Touchpad::X); - signed y = interface->inputPoll(ID::Port::Touchpad, 0, ID::Touchpad::Y); - signed p = interface->inputPoll(ID::Port::Touchpad, 0, ID::Touchpad::Pressure); - signed d = 0;//interface->inputPoll(ID::Port::Touchpad, 0, ID::Touchpad::PressureD); - - if(y < 0) y = -0x8000; - - if(x == -0x8000 || y == -0x8000) { - return 0; // no touch input - } - if(p == -0x8000) // no analog pressure - p = d? 0 : -0x7fff; // use digital - - return p > -0x7ff0; -} - -uint8 Touchscreen::transfer(uint8 data) { - if(data & 0x80) { - // Start a new measurement - input = data>>4; - bitDepth = data>>3; - refMode = data>>2; - powerMode = data>>0; - - signed NONE = -0x8000; - signed x = interface->inputPoll(ID::Port::Touchpad, 0, ID::Touchpad::X); - signed y = interface->inputPoll(ID::Port::Touchpad, 0, ID::Touchpad::Y); - signed p = interface->inputPoll(ID::Port::Touchpad, 0, ID::Touchpad::Pressure); - signed d = 0;//interface->inputPoll(ID::Port::Touchpad, 0, ID::Touchpad::PressureD); - - if(p==NONE) p = !d? -0x7fff : -0x3fff; // no analog? use digital pen - if(x==NONE || y==NONE) p = NONE; // check if pen offscreen - if(y < 0) p = NONE; // restrict to bottom screen - - x += 0x7fff; y *= 2; - p += 0x7fff; - - if(p > 0) { - signed z1 = 0x000, z2 = 0xfff, r = 0xffff - p; - if(x > 0) { // bleh, div-by-zero, just use medium pressure for now - z1 = 0xc00; //0xffffff / (0x1000 + 0x1000/x + 0x1000*(r - y)/x); - z2 = 0x400; //z1*(0x1000 + 0x1000*r/x) / 0x1000; - } - x /= 16; - y /= 16; - - // Without any pressure, there's no connection, and the input floats. - // The measurements seem to return previous values to some extent. - if(input == xpos) last = x; // y+ (along x-/x+ axis) - if(input == ypos) last = y; // x+ (along y-/y+ axis) - if(input == pressure0) last = z1; // x+ (along x-/y+ diagonal?) - if(input == pressure1) last = z2; // y- (along x-/y+ diagonal?) - } - - signed vref = 0x34cc; // reference = 3.3V - signed room = (273 + 25)*0x1000; // 25*C in kelvin - signed k = room; - signed t1 = 0x1000*600 - (k-room)*21/10; // t1 = 600mV @ room - 2.1mV/*K + error - signed t2 = t1 + k * 0x1000/0x292b; // t2 = t1 + k/2.573 - - if(input == temp0) last = t1 * 0xfff/vref; // temperature - if(input == temp1) last = t2 * 0xfff/vref; // temp (w/bias) - if(input == vbatt) last = 0x000; // grounded - if(input == aux) { - // This was split into two inputs - reference is always "single" mode - if(refMode==single) last = 0x800; // microphone - if(refMode==diff) last = 0xfff; // Vcc (NDS Lite) - } - - adc |= last; - - // 8-bit isn't any faster since you have to read two bytes over the serial - // interface either way. Bumping the clock to 4MHz may not provide enough - // time for the ADC to settle, producing less accurate results. - if(bitDepth == read8) - adc &= ~0xf; - } - // Response is 1 bit delay + 8 or 12 bits data. - // This causes some misalignment: - // -------- 0hhhhhhhlllll - after command - // 0hhhhhhh lllll000----- - after first read - // lllll000 [0hhhhhhhlllll] - after second read [+ command] - // [0hhhhhhh lllll000-----] - ... - // [lllll000 0hhhhhhhlllll] - - // response next data - // - // It's perfectly legit (and common) to send a new command while reading the - // low byte. By doing this, you receive a stream of readings with no gaps or - // command overhead in between. - return adc <<= 8, adc >> 21; -} diff --git a/bsnes/nds/video/video.cpp b/bsnes/nds/video/video.cpp deleted file mode 100644 index 5c535b79..00000000 --- a/bsnes/nds/video/video.cpp +++ /dev/null @@ -1,180 +0,0 @@ -#include - -namespace NintendoDS { - -Video video; - -void Video::scanline(unsigned y) { - gpu.scanline(); - ppu[0].scanline(); - ppu[1].scanline(); - - if(line < 192) { - bool display = source[0] == srcFrameBuffer; - bool read = write && sourceB == srcFrameBuffer; - - unsigned srcline = y + 64*(frameBuffer & (display? 0xc : 0xf)); - unsigned destline = y + 64*targetBuffer; - - uint16 *src = &system.vmap.display(srcline / 32)[512*(srcline % 32)]; - uint16 *dest = &system.vmap.display(destline / 32)[512*(destline % 32)]; - - if(read || display) { - for(unsigned x = 0; x < 256; x++) { - uint16 c = src[x]; - uint5 r = c>>0, g = c>>5, b = c>>10; - - frameBufData[x] = b<<13 | g<<7 | r<<1; - } - } - if(write) { - uint32 *aData = sourceA == srcGPU? &gpu.output[256*line] : ppu[0].output; - uint32 *bData = sourceB == srcFifo? fifoData : frameBufData; - - unsigned af = min((unsigned)blendAf, 16u); - unsigned bf = min((unsigned)blendBf, 16u); - - if(targetSource == 0) af = 16, bf = 0; - if(targetSource == 1) af = 0, bf = 16; - - // Need to see what happens with alpha bit.. - for(unsigned x = 0; x < 256; x++) { - uint32 a = aData[x], b = bData[x]; - - uint6 ar = a>>0, ag = a>>6, ab = a>>12; - uint6 br = b>>0, bg = b>>6, bb = b>>12; - - ar = (ar*af + br*bf + 8) / 32u; - ag = (ag*af + bg*bf + 8) / 32u; - ab = (ab*af + bb*bf + 8) / 32u; - - dest[x] = 0x8000 | ab<<10 | ag<<5 | ar<<0; - } - } - - uint32* line[2] = { &output[256*(y + 192*(ppu0Screen == 0))], - &output[256*(y + 192*(ppu0Screen == 1))] }; - - if(source[0] == srcNone) memcpy(line[0], blankData, 256*4); - if(source[0] == srcPPU) memcpy(line[0], ppu[0].output, 256*4); - if(source[0] == srcFrameBuffer) memcpy(line[0], frameBufData, 256*4); - if(source[0] == srcFifo) memcpy(line[0], fifoData, 256*4); - - if(source[1] == srcNone) memcpy(line[1], blankData, 256*4); - if(source[1] == srcPPU) memcpy(line[1], ppu[1].output, 256*4); - if(source[1] == srcFrameBuffer) memcpy(line[1], blankData, 256*4); - if(source[1] == srcFifo) memcpy(line[1], blankData, 256*4); - - for(unsigned s = 0; s < 2; s++) { - if(!fade[s] || !blendYf[s]) continue; - - uint64 yf = min(32, 2*blendYf[s]); - uint64 y = 02000200020; - if(fade[s] == lighten) - y += 07700770077*yf; - - for(unsigned x = 0; x < 256; x++) { - uint64 bgr = (line[s][x] & 0777777)*01000001ull & 07700770077ull; - - bgr = (bgr*(32-yf) + y)/32; - - if(bgr & 010000000000) bgr |= 007700000000; - if(bgr & 000001000000) bgr |= 000000770000; - if(bgr & 000000000100) bgr |= 000000000077; - bgr &= 007700770077; - - line[s][x] = (bgr | bgr>>18) & 0777777; - } - } - } -} - -uint32 Video::regCapture() { - return blendAf<<0 | blendBf<<8 - | (targetBuffer<<14 & 3<<16) - | (targetBuffer<<18 & 3<<18) - | (frameBuffer<<26 & 3<<26) - | (sourceA == srcGPU? 1<<24 : 0) - | (sourceB == srcFifo? 1<<25 : 0) - | targetSource<<29 | write<<31; -} - -void Video::regCapture(uint32 data, uint32 mask) { - if(mask & 0x000000ff) { - blendAf = data>>0; - } - if(mask & 0x0000ff00) { - blendBf = data>>8; - } - if(mask & 0x00ff0000) { - targetBuffer = data>>14 & 0xc; - targetBuffer += data>>18 & 0x3; - targetSize = data>>20; - } - if(mask & 0xff000000) { - frameBuffer &= ~3; - frameBuffer += data>>26 & 0x3; - sourceA = data & 1<<24? srcGPU : srcPPU; - sourceB = data & 1<<25? srcFifo : srcFrameBuffer; - targetSource = data>>29; - write = data>>31; - } -} - -void Video::regFifo(uint32 data) { -} - -uint32 Video::regBrightness(unsigned index) { - return fade[index]<<14 | blendYf[index]<<0; -} - -void Video::regBrightness(unsigned index, uint32 data, uint32 mask) { - if(mask & 0x001f) blendYf[index] = data>>0; - if(mask & 0xc000) fade[index] = data>>14; -} - - -void Video::power() { - for(unsigned x = 0; x < 256; x++) - blankData[x] = 0x3ffff; - - line = 262; - ppu0Screen = 0; - source[0] = srcNone; - source[1] = srcNone; - frameBuffer = 0; - fade[0] = 0; - fade[1] = 0; - blendYf[0] = 0; - blendYf[1] = 0; - - write = false; - sourceA = srcNone; - sourceB = srcNone; - blendAf = blendBf = 0; - targetBuffer = 0; - - hdrawEvent.action = [&]() { - if(++line == 263) { - line = 0; - } - if(line == 192) { - write = false; - system.frame(); - } - scanline(line); - arm9.event.queue.add(12*256, hblankEvent); - arm7.hdraw(); - arm9.hdraw(); - }; - - hblankEvent.action = [&]() { - arm9.event.queue.add(12*99, hdrawEvent); - arm7.hblank(); - arm9.hblank(); - }; - - arm9.event.queue.add(0, hdrawEvent); -} - -} diff --git a/bsnes/nds/video/video.hpp b/bsnes/nds/video/video.hpp deleted file mode 100644 index b3df3fa8..00000000 --- a/bsnes/nds/video/video.hpp +++ /dev/null @@ -1,44 +0,0 @@ -struct Video { - void power(); - void scanline(unsigned y); - - uint32 regCapture(); - void regCapture(uint32 data, uint32 mask); - void regFifo(uint32 data); - - uint32 regBrightness(unsigned index); - void regBrightness(unsigned index, uint32 data, uint32 mask); - - uint32 output[256*384]; - - uint32 blankData[256]; - uint32 frameBufData[256]; - uint32 fifoData[256]; - - uint9 line; - Event hdrawEvent; - Event hblankEvent; - - // Display and rendering on NDS are more loosely coupled, although - // the GPU and PPUs are still all locked to 60fps. - enum { srcNone, srcPPU, srcFrameBuffer, srcFifo, srcGPU }; - - // For display onscreen - uint1 screensPowered; - uint1 ppu0Screen; // 0 is bottom, 1 is top - int source[2]; - int fade[2]; enum { lighten=1, darken=2 }; - uint5 blendYf[2]; - - // For rendering to VRAM - bool write; - int sourceA; // PPU0 or GPU - int sourceB; // framebuffer or FIFO - uint5 blendAf, blendBf; // for blending A + B - uint2 targetSize; - uint2 targetSource; - uint4 targetBuffer; - uint4 frameBuffer; -}; - -extern Video video; diff --git a/bsnes/nds/wifi/wifi.cpp b/bsnes/nds/wifi/wifi.cpp deleted file mode 100644 index dfebb566..00000000 --- a/bsnes/nds/wifi/wifi.cpp +++ /dev/null @@ -1,488 +0,0 @@ -#include - -namespace NintendoDS { - -WIFI wifi; - - -void WIFI::power() { - // This isn't really cleared but we have to be deterministic. - memset(system.wxram.data, 0, system.wxram.size); - - powered = true; - - reg004 = 0; - reg034 = 0; - swMode = 0; - wepMode = 0; - memset(macAddr, 0, sizeof macAddr); - memset(bssId, 0, sizeof bssId); - assocIdl = 0; - assocIdf = 0; - - rxControl = 0; - wepControl = 0; - reg034 = 0; - baseBandPower = 0; - - interrupt.flags = 0; - interrupt.enable = 0; - interrupt.counterFlags = 0; - interrupt.counterEnable = 0; - interrupt.oflowFlags = 0; - interrupt.oflowEnable = 0; - - pm.txIdle = 0; - pm.wakeRequest = 0; - pm.wakePending = 0; - pm.sleeping = 0; - - bb.event.action = [&]() { bbTransferBit(); }; - bb.time = 0; - bb.busy = 0; - bb.read = 0; - bb.write = 0; - bb.header = 0; - bb.powerl = 0; - bb.powerh = 0; - bb.mode8 = 0; - bb.modeE = 0; - bb.clock = 0; - - memset(bb.regs, 0, sizeof bb.regs); - - bb.regs[0x00] = 0x6d; - bb.regs[0x4d] = 0xff; - bb.regs[0x5d] = 0x01; - bb.regs[0x64] = 0xff; - - rf.event.action = [&]() { rfTransferBit(); }; - rf.time = 0; - rf.busy = 0; - rf.data = 0; - rf.length = 24; - rf.type = 0; - rf.reserved = 0; - - memset(rf.regs, 0, sizeof rf.regs); - - rf.regs[0x00] = 0x00007; - rf.regs[0x01] = 0x09003; - rf.regs[0x02] = 0x00022; - rf.regs[0x03] = 0x1ff78; - rf.regs[0x04] = 0x09003; - rf.regs[0x05] = 0x01780; - rf.regs[0x06] = 0x00000; - rf.regs[0x07] = 0x14578; - rf.regs[0x08] = 0x1e742; - rf.regs[0x09] = 0x00120; - rf.regs[0x0a] = 0x00000; - rf.regs[0x0b] = 0x00000; - rf.regs[0x0c] = 0x00000; - rf.regs[0x1b] = 0x0000f; - rf.regs[0x0e] = 0x00022; - rf.regs[0x1f] = 0x00001; - - txWritePos = 0; rxBufBegin = 0; - txWriteCounter = 0; rxBufEnd = 0; - txGapBegin = 0; rxWritePos = 0; - txGapSize = 0; rxWritePosLatch = 0; - txTimOffset = 0; rxReadPos = 0; - txBeacon = 0; rxSoftReadPos = 0; - txMultiCmd = 0; rxReadCounter = 0; - txSlots[0] = 0; rxGapBegin = 0; - txSlots[1] = 0; rxGapSize = 0; - txSlots[2] = 0; reg00a = 0; - txStatControl = 0; - txRetryLimit = 0; - - reg1a0l = 0; - reg1a0m = 0; - reg1a0n = 0; - reg1a0h = 0; - reg1a2 = 0; - reg1a4 = 0; - - listenCount = 0; - listenInterval = 0; - beaconInterval = 0; - preamble = 0; - random = 1; - - timer.enable = false; - timer.enableIrq = false; - timer.enableTxMP = false; - timer.count = 0; - timer.compare = 0; - - config120l = 0; config140 = 0; config154l = 0; - config120h = 0; config142 = 0; config154m = 0; - config122 = 0; config144 = 0; config154h = 0; - config124 = 0; config146 = 0; - config128 = 0; config148 = 0; config0d4 = 0; - config130 = 0; config14a = 0; config0d8 = 0; - config132l = 0; config14c = 0; config0da = 0; - config132h = 0; config150l = 0; config0ecl = 0; - configBeaconCount = 0; config150h = 0; config0ech = 0; - - stats.reg1b0 = 0; - stats.reg1b2 = 0; - stats.reg1b4 = 0; - stats.reg1b6 = 0; - stats.reg1b8 = 0; - stats.reg1ba = 0; - stats.reg1bc = 0; - stats.reg1be = 0; - stats.txErrors = 0; - stats.rxPackets = 0; - memset(stats.mpErrors, 0, sizeof stats.mpErrors); -} - -void WIFI::bbTransfer() { - // Assuming 22MHz (66MHz/3) clock here. Probably wrong. - bb.busy = 0; - bb.read = 0; - bb.time = 16 + 8; - arm7.event.queue.add(3, bb.event); -} - -void WIFI::bbTransferBit() { - if(--bb.time) { - // Small delay before setting busy bit - if(bb.time == 20) bb.busy = 1; - - arm7.event.queue.add(3, bb.event); - return; - } - // Finished, commit the read or write. - bb.busy = 0; - - uint1 start = bb.header>>14; - uint1 rd = bb.header>>13; - uint1 wr = bb.header>>12; - uint8 addr = bb.header>>0; - - if(start) { - if(rd) { - bb.read = addr < 0x69? bb.regs[addr] : 0; - //print("bb read ",hex<2>(addr)," = ",hex<2>(bb.read),"\n"); - } - if(wr) { - if(0x0d <= addr && addr <= 0x12) return; - if(0x16 <= addr && addr <= 0x1a) return; - if(0x5d <= addr && addr <= 0x61) return; - if(0x00 == addr || 0x27 == addr) return; - if(0x4d == addr || 0x64 == addr) return; - if(0x66 == addr || 0x69 <= addr) return; - - if(addr < 0x69) bb.regs[addr] = bb.write; - //print("bb write ",hex<2>(addr)," : ",hex<2>(bb.write),"\n"); - } - } -} - -void WIFI::rfTransfer() { - rf.busy = 1; - rf.time = 18 + 6; - arm7.event.queue.add(3, rf.event); -} - -void WIFI::rfTransferBit() { - if(--rf.time) { - arm7.event.queue.add(3, rf.event); - return; - } - //Finished, commit the read or write. - rf.busy = 0; - - uint1 rd = rf.data>>23; - uint5 addr = rf.data>>18; - uint18 data = rf.data>>0; - - if(rd) { - rf.data = rf.regs[addr]; - //print("rf read ",hex<2>(addr)," = ",hex<5>(rf.data),"\n"); - } - else { - rf.regs[addr] = data; - //print("rf write ",hex<2>(addr)," : ",hex<5>(data),"\n"); - } -} - -uint32 WIFI::read(uint32 addr, uint32 size) { - if(addr & 0x4000) - return system.wxram.read(addr & 0x1fff, size); - - if(size==Word) { return read(addr&~2, Half)<<0 - | read(addr| 2, Half)<<16; } - //if(addr != 0x480015e && addr != 0x4800180) - // print("wifi r ",hex<8>(addr),"\n"); - - switch(addr & 0xffe) { - case 0x000: return 0xc340; // chip ID - case 0x004: return reg004; - case 0x006: return swMode<<0 | wifi.wepMode<<3; - case 0x008: return txStatControl; - case 0x00a: return reg00a; - case 0x010: return interrupt.flags; - case 0x012: return interrupt.enable; - - case 0x018: return macAddr[0] | macAddr[1]<<8; - case 0x01a: return macAddr[2] | macAddr[3]<<8; - case 0x01c: return macAddr[4] | macAddr[5]<<8; - case 0x020: return bssId[0] | bssId[1]<<8; - case 0x022: return bssId[2] | bssId[3]<<8; - case 0x024: return bssId[4] | bssId[5]<<8; - case 0x028: return assocIdl; - case 0x02a: return assocIdf; - case 0x02c: return txRetryLimit; - - case 0x030: return rxControl; - case 0x032: return wepControl; - case 0x034: return reg034; - case 0x036: return bb.clock; - case 0x038: return pm.txIdle; - case 0x03c: return pm.wakeRequest | pm.wakePending<<8 | pm.sleeping<<9; - case 0x040: return 0;//wifi.pm.; - - case 0x044: { - uint11 data = random; - random = random<<1 | random>>10; - random ^= data & 1; - return data; - } - - case 0x050: return rxBufBegin; - case 0x052: return rxBufEnd; - case 0x054: return rxWritePos; - case 0x056: return rxWritePosLatch; - case 0x058: return rxReadPos<<1; - case 0x05a: return rxSoftReadPos; - case 0x05c: return rxReadCounter; - case 0x060: break;//return rxBufRead(); - case 0x062: return rxGapBegin<<1; - case 0x064: return rxGapSize; - - case 0x068: return txWritePos<<1; - case 0x06c: return txWriteCounter; - case 0x074: return txGapBegin<<1; - case 0x076: return txGapSize; - case 0x080: return txBeacon; - case 0x084: return txTimOffset; - case 0x088: return listenCount; - case 0x08c: return beaconInterval; - case 0x08e: return listenInterval; - - case 0x0bc: return preamble; - - case 0x0d4: return config0d4; - case 0x0d8: return config0d8; - case 0x0da: return config0da; - case 0x0e8: return timer.enable; - case 0x0ea: return timer.enableIrq; - case 0x0ec: return config0ecl | config0ech<<8; - case 0x0ee: return timer.enableTxMP; - - case 0x110: return preBeacon; - - case 0x120: return config120l | config120h<<15; - case 0x122: return config122; - case 0x124: return config124; - case 0x128: return config128; - case 0x130: return config130; - case 0x132: return config132l | config132h<<15; - case 0x134: return configBeaconCount; - case 0x140: return config140; - case 0x142: return config142; - case 0x144: return config144; - case 0x146: return config146; - case 0x148: return config148; - case 0x14a: return config14a; - case 0x14c: return config14c; - case 0x150: return config150l | config150h<<8; - case 0x154: return config154l | config154m<<9 | config154h<<11; - - case 0x15c: return bb.read; - case 0x15e: return bb.busy; - case 0x160: return bb.mode8<<8 | bb.modeE<<14; - case 0x168: return bb.powerl<<0 | bb.powerh<<15; - - case 0x17c: return rf.data>>16; - case 0x17e: return rf.data>>0; - case 0x180: return rf.busy; - - case 0x1a0: return reg1a0l | reg1a0m<<4 | reg1a0n<<8 | reg1a0h<<11; - case 0x1a2: return reg1a2; - case 0x1a4: return reg1a4; - - case 0x244: return 0x0000; - case 0x254: return 0xeeee; - case 0x290: return 0xffff; - } - //print("r ",hex<8>(addr),": unimplemented\n"); - return 0; -} - -void WIFI::write(uint32 addr, uint32 size, uint32 data) { - if(size==Byte) return; - if(size==Word) { write(addr&~2, Half, data & 0xffff); - write(addr| 2, Half, data >> 16); return; } - if(addr & 0x4000) - return system.wxram.write(addr & 0x1fff, Half, size); - - //print("wifi w ",hex<8>(addr)," : ",hex<4>(data),"\n"); - - switch(addr & 0xffe) { - case 0x004: - if((reg004 ^ data) & 1<<0) { - if(data & 1) { - reg034 = 0x2; - //rf.pins = 0x46; - //rf.status = 9; - //reg27c = 5; - //reg2a2 = ..; - } - else { - reg034 = 0xa; - } - } - if(data & 1<<13) { - rxWritePosLatch = 0; - //reg0c0 = 0; - //reg0c4 = 0; - //reg1a4 = 0; - //reg278 = 0xf; - } - if(data & 1<<14) { - swMode = 0; - wepMode = 0; - //txStatCnt = 0; - //reg00a = 0; - memset(macAddr, 0, sizeof macAddr); - memset(bssId, 0, sizeof bssId); - assocIdl = 0; - assocIdf = 0; - //txRetryLimit = 0; - //reg02e = 0; - rxBufBegin = 0x4000; - rxBufEnd = 0x4800; - txTimOffset = 0; - //reg0bc = 1; - //reg0d0 = 0x401; - config0d4 = 1; - //reg0e0 = 8; - config0ecl = 3; - config0ech = 0x3f; - //reg194 = 0; - //reg198 = 0; - //reg1a2 = 1; - //reg224 = 3; - //reg230 = 0x47; - } - reg004 = data; - return; - - case 0x006: swMode = data>>0; wepMode = data>>3; return; - case 0x008: txStatControl = data; return; - case 0x00a: reg00a = data; return; - case 0x21c: interrupt.flags |= data & ~0x400; return; - case 0x010: interrupt.flags &= ~data; return; - case 0x012: interrupt.enable = data; return; - - case 0x018: macAddr[0] = data; macAddr[1] = data>>8; return; - case 0x01a: macAddr[2] = data; macAddr[3] = data>>8; return; - case 0x01c: macAddr[4] = data; macAddr[5] = data>>8; return; - case 0x020: bssId[0] = data; bssId[1] = data>>8; return; - case 0x022: bssId[2] = data; bssId[3] = data>>8; return; - case 0x024: bssId[4] = data; bssId[5] = data>>8; return; - case 0x028: assocIdl = data; return; - case 0x02a: assocIdf = data; return; - case 0x02c: txRetryLimit = data; return; - - case 0x030: rxControl = data; return; - case 0x032: wepControl = data & 0x8000; return; - case 0x034: reg034 = data; return; - case 0x036: bb.clock = data; return; - case 0x038: pm.txIdle = data; return; - case 0x03c: pm.wakeRequest = data>>1; return; - case 0x040: if(data & 1<<15) { - reg034 = 2; - pm.sleeping = data>>0; - } - return; - - case 0x050: rxBufBegin = data; return; - case 0x052: rxBufEnd = data; return; - case 0x056: rxWritePosLatch = data; return; - case 0x058: rxReadPos = data>>1; return; - case 0x05a: rxSoftReadPos = data; return; - case 0x05c: rxReadCounter = data; return; - case 0x062: rxGapBegin = data>>1; return; - case 0x064: rxGapSize = data; return; - - case 0x068: txWritePos = data>>1; return; - case 0x06c: txWriteCounter = data; return; - case 0x070: break;//return txBufWrite(data); - case 0x074: txGapBegin = data>>1; return; - case 0x076: txGapSize = data; return; - - case 0x080: txBeacon = data; return; - case 0x084: txTimOffset = data; return; - case 0x088: listenCount = data; return; - case 0x08c: beaconInterval = data; return; - case 0x08e: listenInterval = data; return; - - case 0x0b4: return; //txBufReset - case 0x0bc: preamble = data; return; - - case 0x0d4: config0d4 = data; return; - case 0x0d8: config0d8 = data; return; - case 0x0da: config0da = data; return; - case 0x0e8: timer.enable = data; return; - case 0x0ec: config0ecl = data; config0ech = data>>8; return; - case 0x0ea: timer.enableIrq = data; return;//if bit 1 trigger irq14 - case 0x0ee: timer.enableTxMP = data; return; - - case 0x110: preBeacon = data; return; - - case 0x120: config120l = data; config120h = data>>15; return; - case 0x122: config122 = data; return; - case 0x124: config124 = data; return; - case 0x128: config128 = data; return; - case 0x130: config130 = data; return; - case 0x132: config132l = data; config132h = data>>15; return; - case 0x134: configBeaconCount = data; return; - case 0x140: config140 = data; return; - case 0x142: config142 = data; return; - case 0x144: config144 = data; return; - case 0x146: config146 = data; return; - case 0x148: config148 = data; return; - case 0x14a: config14a = data; return; - case 0x14c: config14c = data; return; - case 0x150: config150l = data; config150h = data>>8; return; - case 0x154: config154l = data; config154m = data>>9; config154h = data>>11; return; - - case 0x158: bb.header = data; return wifi.bbTransfer(); - case 0x15a: bb.write = data; return; - case 0x160: bb.mode8 = data>>8; bb.modeE = data>>14; return; - case 0x168: bb.powerl = data>>0; bb.powerh = data>>15; return; - - case 0x17c: rf.data &= 0xffff; rf.data |= data<<16; return wifi.rfTransfer(); - case 0x17e: rf.data &= ~0xffff; rf.data |= data<<0; return; - case 0x184: rf.length = data>>0; - rf.type = data>>8; - rf.reserved = data>>14; return; - - case 0x1a0: reg1a0l = data; reg1a0m = data>>4; reg1a0n = data>>8; reg1a0h = data>>11; return; - case 0x1a2: reg1a2 = data; return; - case 0x1a4: reg1a4 = data; return; - - case 0x244: return; - case 0x254: return; - case 0x290: return; - } - //print("w ",hex<8>(addr),": unimplemented\n"); -} - - -} diff --git a/bsnes/nds/wifi/wifi.hpp b/bsnes/nds/wifi/wifi.hpp deleted file mode 100644 index 548940e6..00000000 --- a/bsnes/nds/wifi/wifi.hpp +++ /dev/null @@ -1,153 +0,0 @@ - -struct WIFI { - void power(); - - void bbTransfer(); - void bbTransferBit(); - - void rfTransfer(); - void rfTransferBit(); - - uint32 read(uint32 addr, uint32 size); - void write(uint32 addr, uint32 size, uint32 data); - - uint1 powered; - - uint16 reg004; - uint3 swMode, wepMode; - - uint8 macAddr[6]; - uint8 bssId[6]; - uint4 assocIdl; - uint11 assocIdf; - - uint16 rxControl, wepControl; - uint16 reg034, baseBandPower; - - uint16 rxBufBegin, rxBufEnd; - uint12 rxWritePos, rxWritePosLatch; - uint12 rxReadPos, rxSoftReadPos; - uint12 rxGapBegin, rxGapSize; - uint12 rxReadCounter; - uint16 reg00a; - - uint12 txWritePos; - uint12 txGapBegin, txGapSize; - uint16 txBeacon; - uint16 txMultiCmd; - uint16 txSlots[3]; - uint8 txTimOffset; - uint12 txWriteCounter; - uint16 txStatControl; - uint16 txRetryLimit; - - uint8 listenCount; - uint8 listenInterval; - uint10 beaconInterval; - uint2 preamble; - uint16 preBeacon; - uint11 random; - - struct { - uint1 enable; - uint1 enableIrq; - uint1 enableTxMP; - uint64 count; - uint64 compare; - } timer; - - uint2 config0d4; - uint12 config0d8; - uint16 config0da; - uint5 config0ecl; - uint6 config0ech; - - uint9 config120l; - uint1 config120h; - uint16 config122; - uint16 config124; - uint16 config128; - uint12 config130; - uint12 config132l; - uint1 config132h; - uint16 configBeaconCount; - - uint16 config140; - uint16 config142; - uint8 config144; - uint8 config146; - uint8 config148; - uint8 config14a; - uint16 config14c; - - uint6 config150l; - uint8 config150h; - uint7 config154l; - uint1 config154m; - uint4 config154h; - - uint2 reg1a0l; - uint2 reg1a0m; - uint1 reg1a0n; - uint1 reg1a0h; - uint2 reg1a2; - uint16 reg1a4; - - struct { - uint16 enable, counterEnable, oflowEnable; - uint16 flags, counterFlags, oflowFlags; - } interrupt; - - struct { - uint8 reg1b0; - uint16 reg1b2; - uint16 reg1b4; - uint16 reg1b6; - uint8 reg1b8; - uint8 reg1ba; - uint16 reg1bc; - uint16 reg1be; - uint16 txErrors; - uint16 rxPackets; - uint8 mpErrors[16]; - } stats; - - struct { - uint4 txIdle; - uint2 wakeRequest; - uint1 wakePending; - uint1 sleeping; - } pm; - - // Baseband serial interface - struct { - uint16 header; // 01rw0000 aaaaaaaa (r/w, address) - uint8 read, write; // data sent and received - uint4 powerl; - uint1 powerh; - uint1 mode8, modeE; - uint1 busy; - uint1 clock; - - uint8 time; - Event event; - - uint8 regs[0x69]; - } bb; - - // RF serial interface - struct { - uint32 data; // r aaaaa dd dddddddd dddddddd (r/w, address, data) - uint6 length; // should be 24 bits - uint1 type; // should be 0 - uint1 reserved; - uint1 busy; - - uint8 time; - Event event; - - uint18 regs[0x20]; - } rf; -}; - -extern WIFI wifi; \ No newline at end of file diff --git a/bsnes/obj/.gitignore b/bsnes/obj/.gitignore deleted file mode 100644 index 72e8ffc0..00000000 --- a/bsnes/obj/.gitignore +++ /dev/null @@ -1 +0,0 @@ -* diff --git a/bsnes/out/.gitignore b/bsnes/out/.gitignore deleted file mode 100644 index 72e8ffc0..00000000 --- a/bsnes/out/.gitignore +++ /dev/null @@ -1 +0,0 @@ -* diff --git a/bsnes/profile/Nintendo DS.sys/manifest.xml b/bsnes/profile/Nintendo DS.sys/manifest.xml deleted file mode 100644 index 732887a3..00000000 --- a/bsnes/profile/Nintendo DS.sys/manifest.xml +++ /dev/null @@ -1,31 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - diff --git a/bsnes/Makefile b/higan/Makefile old mode 100644 new mode 100755 similarity index 95% rename from bsnes/Makefile rename to higan/Makefile index 65ad25d5..da93b18b --- a/bsnes/Makefile +++ b/higan/Makefile @@ -4,7 +4,7 @@ fc := fc sfc := sfc gb := gb gba := gba -nds := nds +# nds := nds profile := accuracy target := ethos @@ -105,7 +105,7 @@ sync: rm -r phoenix/test archive: - if [ -f bsnes.tar.xz ]; then rm bsnes.tar.xz; fi - tar -cJf bsnes.tar.xz `ls` + if [ -f higan.tar.xz ]; then rm higan.tar.xz; fi + tar -cJf higan.tar.xz `ls` help:; diff --git a/bsnes/data/cheats.xml b/higan/data/cheats.xml old mode 100644 new mode 100755 similarity index 99% rename from bsnes/data/cheats.xml rename to higan/data/cheats.xml index 0619442d..1f94df58 --- a/bsnes/data/cheats.xml +++ b/higan/data/cheats.xml @@ -1,5 +1,5 @@ - + 1942 (Japan, USA) @@ -423,6 +423,14 @@ Invincibility AVISVG + + One hit kills + EIKVVIEY + + + No enemies + GXUIZIAI + Addams Family, The (USA) @@ -3845,6 +3853,10 @@ Super fast punching AEUZITPA + + Force 2-player mode + AENTAIPL + Start with 1 life PENVZILA @@ -4383,6 +4395,13 @@ ZAXAYGAA + + Bio Miracle Bokutte Upa (Japan).nes + + Hit anywhere - normal enemies + AAKTZTIG+AEOLVGTZ + + Bionic Commando (USA) @@ -4417,10 +4436,30 @@ Autofire - main game XYXUUOEN + + Longer grapple line - sidescrolling levels + AINPTZAL+TSEOGZAG+YIVPAXZU + + + Longest grapple line - sidescrolling levels + EINPYZEP+EIVPPZEP+ESEOIZEP + + + Longer range for normal 3-way gun - sidescrolling levels + YOVUESPA + + + Longer range for fireball 3-way gun - sidescrolling levels + IPKLKVGA + Use with BIO Code 11 for improved autofire with normal gun AAKUOOZA + + Have all items (using the hidden gun will crash the game) + ELKLZAEY+EIXLTPEY + Start with 3 life energy capsules LAUKOZAA+XTUKUXVU @@ -9647,6 +9686,13 @@ PAUIEZIA + + Donkey Kong Jr. Math (USA, Europe).nes + + Always get the correct answer + AAKILSZA+AAUILSZP + + Donkey Kong Classics (USA, Europe) @@ -11273,6 +11319,10 @@ Infinite lives (alt) SGXGZGVG + + Multi-jump + ENVVIPNP+PXVVPOVP+XOVVTPXT+ZKVVGOGK + Take more damage APONPXAA @@ -13634,6 +13684,14 @@ Infinite credits SXXGSVVK + + Hit anywhere + AIUPKZEL+APUPSZGX+ASEOEPEL+EUEZTGGN+GKEZIKOS+KXEZYGIA+ZUEOOOAI + + + Get items from anywhere + AINPXZEL+YPNPUXPX + Galactic Crusader (USA) (Unl) @@ -15140,6 +15198,18 @@ Infinite special weapons SXVZTXSE + + One hit kills + EIEIYYEP + + + Enemies die automatically + AAUZLOAP+AUSSANAO+SAUZTOVK + + + Get items from anywhere + AUVSINKU+AVVSTNAP + Invincibility (alt) 0400:02 @@ -15546,6 +15616,13 @@ SLONNKSO + + Heracles no Eikou - Toujin Makyou Den (Japan) + + No random battles + AVSVTZAZ + + Hogan's Alley (World) @@ -17257,6 +17334,14 @@ Take less damage PTYSEK + + Hit anywhere + GKKEAZSK+OVKEPXPA+XEKEZZEP + + + Multi-jump + AEOTTIGA + 9 Tornado Attacks on pick-up PESIKYYE @@ -18643,6 +18728,14 @@ Press Start to complete the level GEXGUALU+LEXGSALU+OXXGXAIK + + Hit anywhere - throwing + ELXKKESZ+TIXKSAYA + + + Multi-jump when falling + ESXPZZEY+KOXPLZKS+OKOOYZOX+PEXPPXSG+PXXPAZES + One life after continue PASKOILA @@ -18889,6 +18982,14 @@ Infinite lives SXKTPKVG + + Hit anywhere (spitting) + AOOEIOOV+AOOETPYE+EANEZAAT+GGNEAESN+GXKEIPEL+VGNEPAGY + + + Inhale from anywhere + AASELZZG+AINEYZEP+SZNEGXSV + Less health from 'pep drinks' ZAKLLXAA @@ -18948,6 +19049,14 @@ Infinite lives SXKTPKVG + + Hit anywhere (spitting) + AEKAIEIA+AEXAIPTL+AOOAGEOV+AOOAIAYE+GXKEIPEL + + + Inhale from anywhere + AASELZZG+GXEAGZEL + Less health from 'pep drinks' ZAKLLXAA @@ -21342,6 +21451,10 @@ Magic of Scheherazade, The (USA) + + Invincibility + OXUYZKPX + Infinite HP OTSXLGSV @@ -21350,6 +21463,18 @@ Infinite lives SXEVPLVG + + Hit anywhere + AEEYYGLA+ALNNIGEP+SZNNLGSG+TZNNTKPA+UGNNGKPE + + + Never lose Mashroobs + SZEAEKVK + + + Get coins from anywhere + TEXAXLLA + Less energy gained from Bread POKAOZZU @@ -21358,10 +21483,6 @@ Less magic gained from Mashroobs ZAEEXGIA - - Never lose Mashroobs - SZEAEKVK - Start with only 20 Gold Coins ZAUTAZIA @@ -25957,6 +26078,13 @@ 03E2:1D + + Otaku no Seiza - An Adventure in the Otaku Galaxy (Japan) + + No random battles + AVEIXKOZ + + Over Horizon (Europe) @@ -27001,7 +27129,7 @@ - Princess Tomato in Salad Kingdom (USA) + Princess Tomato in the Salad Kingdom (USA) Infinite gold coins 03CB:09 @@ -29841,6 +29969,10 @@ Infinite time SZEVYZVG + + Hit anywhere + AKSZANEL+ATUILYEI+OXSZPNEX + 200 Machine Gun bullets on pick-up EKSTEAGV @@ -30578,6 +30710,13 @@ AANOLAZE + + Shinsenden (Japan) + + No random battles + ATXUPAAL + + Shooting Range (USA) @@ -33991,6 +34130,10 @@ Quick pick-up SXUASXOU + + Twice as much time in sub-space + NNXPZIAV + Infinite magic carpet time SLNZZLVI @@ -34194,6 +34337,10 @@ Quick pick-up SXUASXOU + + Twice as much time in sub-space + NNXPZIAV + Jump as high as a squat jump AEUEKKGL @@ -38384,6 +38531,10 @@ Vice - Project Doom (USA) + + Invincibility + AANSEIYP + Infinite lives SZSKIOVK @@ -38404,6 +38555,14 @@ Infinite power SXVYVKSE + + Hit anywhere + AEEYXEET + + + Multi-jump + XVVKISZK + 10 coins for an extra life ZEOYNGGV @@ -39101,10 +39260,22 @@ Wing of Madoola, The (Japan) (Sample) + + Invincibility + SXKGXTSA + Infinite hits and magic SLUUVYSP + + Hit anywhere + AAOGEVPA+AAOGSVZI+PZOGKTSN + + + One hit kills + APXKETSV+APXKOVEE + Start with 9999 hits OOKZKPAE+OOKXEPAO @@ -40490,6 +40661,17 @@ YYKSKIPE + + Ys III - Wanderers from Ys (Japan).nes + + Hit anywhere + XTKXSAAV+XTNXUAAV+XTVZKAAV+XVOZXAAV + + + One hit kills + AAEZYYGA + + Yume Koujou Doki Doki Panic (Japan) [b] (FDS) @@ -40567,6 +40749,10 @@ Zanac (USA) + + Invincibility + Hit anywhere + ALSEGZEU+ATSEIZPL+SZOELXOO + Infinite lives OXEENYVK @@ -42123,9 +42309,14 @@ Infinite lives DD67-4468 - - - DDB3-C764 + + Hit anywhere + 40B5-17A4+40B6-14A4+40BB-17D4+40BC-1DA4 + + + One hit kills + DDB3-C764 + Small magic power-up adds 3 instead of 1 D7C0-37A7 @@ -42923,6 +43114,14 @@ Infinite lives C282-34A1 + + Hit anywhere + DDA0-476A+DDA9-4F6A + + + Moon jump + 5C88-1D09+7D88-1DA9+DD83-17A9 + Adventures of Rocky and Bullwinkle and Friends, The (USA) @@ -44468,6 +44667,25 @@ 6D14-7DD4 + + Ashita no Joe (Japan) + + Hit anywhere - P1 + DD81-64AF + + + Hit anywhere - P2 + DD8A-A46D + + + Invincibility - P1 + 6D8A-6DDD + + + Invincibility - P2 + 6D81-0FDF + + Asterix (Europe) (En,Fr,De,Es) @@ -44775,6 +44993,10 @@ Infinite weapons (except for Flame) 3C37-A7D4 + + Hit anywhere + DDE2-6D04+DDEF-AD04 + Max weapons on pick-up DDC0-C770 @@ -46107,6 +46329,10 @@ Infinite Hyper Bombs - Neptune C2C3-DF67 + + Hit anywhere + 1D85-AD0F+1D8B-ADAF+C28A-D7A4+7685-ADDF+768B-AD6F + Start with 1 ship DD6E-6707 @@ -46178,6 +46404,10 @@ Infinite Discs 8289-CFDF + + Multi-jump + 6D21-CFAF+6D29-CD6F + Bobby's World (USA) (Proto) @@ -46186,13 +46416,25 @@ 2DB7-1DD8 - Infinite energy + Infinite health 82BC-1468 + + Infinite health (alt) + 7E139B03 + Infinite lives 822D-17AF + + Infinite lives (alt) + 7E139509 + + + Multi-jump + DDB3-17AC + Bonkers (USA) @@ -46216,6 +46458,10 @@ Infinite dash C98C-CD0F + + Hit anywhere + 6DE1-1F04+9DE1-1F64 + Boogerman - A Pick and Flick Adventure (USA) @@ -46286,6 +46532,14 @@ Boxing Legends of the Ring (USA) + + Invincibility - P1 + 6D6A-C4A9 + + + Invincibility - P2 + 6D66-3D05 + Infinite super punches - P1 C26D-3F05 @@ -46302,6 +46556,22 @@ Infinite time per round C2BA-A7A7 + + Hit anywhere - P1 + 1DBD-4460+F6BD-4400 + + + Hit anywhere - P2 + 1D69-3FD9+F669-3DA9 + + + Blocking disabled - P1 + DD62-CD09 + + + Blocking disabled - P2 + DD66-3FA5 + Each round is 1 minute DF8D-CDA7 @@ -48406,6 +48676,13 @@ D460-CD0D + + Bulls vs Blazers and the NBA Playoffs (USA) + + Never miss a shot + DD66-C4BD + + Bust-A-Move (USA) @@ -49569,6 +49846,14 @@ Infinite lives DDEC-CF6D + + Hit anywhere + DD6B-ADA4 + + + Multi-jump + DDA2-DDDF + Stay as Super Congo (you may change if you walk on spikes) CB69-34D7 @@ -50107,6 +50392,22 @@ Infinite Nutty attacks C287-34AD + + Hit anywhere + DD33-1DDF + + + Get items from anywhere + DD20-C7A4+DD26-1FD4+DD27-CFA7+DD3C-1D6D + + + One hit kills + 6D86-17DF + + + Disable recoil + DD89-CFAD + Juice cans set health to 1/2 D121-CD64 @@ -50774,6 +51075,14 @@ Invincibility after one hit C92A-44A7 + + Hit anywhere + DD66-47DC+DD6C-4D6C+6D6D-3DDC+6D64-3DAC + + + Get GP from anywhere + DDA5-176C + Large health refills full health C9AC-176C @@ -51490,6 +51799,10 @@ Infinite credits - both players C260-67F7 + + Hit and stomp anywhere + 6DAE-6469+F9AE-64A9 + Clock runs faster 7A64-D420 @@ -53648,9 +53961,17 @@ EE2E-54A1 - Fast money (buy a bread w/the code off, turn code on and sell it for $32,646) + Fast money (buy a bread with the code disabled, enable and sell it for $32,646) EE9A-E5F5 + + Dad never calls + E395-87DD + + + Massive numbers of enemies (piracy check) + 6D4F-7704 + Start with a level 9 character DB23-77D1 @@ -53683,10 +54004,6 @@ Start with a lot of PSI BB2F-54A1 - - Dad never calls - E395-87DD - Infinite health 7E9A13:E7+7E9A14:03 @@ -60503,8 +60820,16 @@ Imperium (USA) - Invincibility against lesser robots, weapons and lasers - 1D34-D4A1+1DC3-DDF7 + Invincibility + 6DCC-DD27+DD38-AFA9 + + + Hit anywhere + 6D31-DDA1+C236-DD01 + + + Infinite bombs + C2A9-D46F Start with 1 life point @@ -60683,6 +61008,18 @@ Health doesn't decrease when Hulked-out C260-4746 + + Hit anywhere + 0AB3-4D00+2DB3-4DD0+3DB2-4700+DDB2-4760+DDB2-47A0 + + + One hit kills + DDBF-47D0 + + + Get items from anywhere + 6DBF-17CB + Get 4 shots from gun D0BC-173B @@ -61373,6 +61710,13 @@ 7E0269:03 + + Jeopardy! (USA) + + Always get the correct answer + 6DC8-6D67+6DCE-64A7 + + Jetsons, The - Invasion of the Planet Pirates (USA) @@ -61499,6 +61843,10 @@ Hit anywhere 6DC3-0DAD+C9E5-DDDD+DDC4-076D + + One hit kills + 40CC-07DD + Start with 2 lives CBC8-6404+DFC8-6464 @@ -64516,10 +64864,9 @@ Pit death disabled 1DA9-04D1 - - Get 1 gold for each creature killed - 1BB5-D769+DFB5-D7A9+3CB6-DDD9 - + + + 1BB5-D769+DFB5-D7A9+3CB6-DDD9 Get 100 gold for each creature killed 1BB5-D769+10B5-D7A9+3CB6-DDD9 @@ -65106,6 +65453,10 @@ Dash without having the Pegasus Boots EEE5-2356 + + Dash without charge up + 45B8-D49A + Use the Magic Mirror to warp between the Light and Dark Worlds freely 6DC9-0D23 @@ -70208,6 +70559,10 @@ Infinite timeouts - both players (slightly glitchy) 8250-5700 + + Cannot be tackled (hold X) + 6D59-7FD7+7D59-7F67+C959-7DA7+DC59-7F07+E959-7FA7 + Field goals worth 0 points DD6F-8404 @@ -70283,6 +70638,10 @@ Infinite timeouts 8297-7F09 + + Cannot be tackled (hold X) + 6D6C-EFDF+7D6C-EF6F+C96C-EDAF+DC6C-EF0F+E96C-EFAF + Safeties are worth 0 points DD62-EFA7 @@ -70348,6 +70707,20 @@ DF65-E7A7 + + Madden NFL 97 (USA) + + Cannot be tackled (hold X) + 6D66-7767+7D6B-7DD7+C966-7707+DC66-77A7+E96B-7D07 + + + + Madden NFL 98 (USA) + + Cannot be tackled (hold X) + 6D6F-5407+7D6F-54A7+C96F-54D7+DC6F-5467+E96F-57D7 + + Magic Boy (USA) @@ -71254,7 +71627,7 @@ Infinite weapon energy - FEC2-E405 + FE42-E405 One hit kills @@ -71268,6 +71641,50 @@ Multi-jump DC51-ED65+BD51-EDA5+D751-EFD5+4D51-EF05+8551-EF65+7451-EFA5+4D51-E4D5+BC51-E405+FF51-E465+1D51-E4A5+1DFC-E400+5EFC-E460+C951-EDD5+0951-ED05 + + Always Shoot Shots + FF40-E405 + + + Always shoot Freeze Cracker + 4040-E405 + + + Always shoot Scorch Wheel + 4140-E405 + + + Always shoot Danger Wrap Bombs + 4340-E405 + + + Always shoot Noise Crush + 1140-E405 + + + Always shoot Fully Charged Mega Buster Blasts + 5240-E405 + + + Always shoot Slash Claw + BA40-E405 + + + Always shoot Thunder Bolt + 8940-E405 + + + Always shoot Wild Coil + E740-E405 + + + Always shoot Charged Wild Coils + EE40-E405 + + + White Shots/Special Weapons + EE02-E465 + Infinite E-Tanks (alt) 7E0BA0:FF @@ -71379,6 +71796,14 @@ Multi-jump 4065-17A9+EA66-1409+B966-1469 + + Enemies always drop large energy + C4CB-3DBD+D4CB-3D2D + + + Enemies always drop large weapon energy + C4CB-3DBD+D0CB-3D2D + Bogus jump (may go back to normal jumps) D08A-1FBC @@ -71482,6 +71907,14 @@ Multi-jump 4065-1F09+E465-17A9+B966-1DD9 + + Enemies always drop large energy + C4C6-379D+D4C6-37BD + + + Enemies always drop large weapon energy + C4C6-379D+D0C6-37BD + Bogus jump (may go back to normal jumps) D08A-1FBC @@ -71553,6 +71986,10 @@ Mega Man X2 (USA) + + Invincibility + D6B0-DD4F + Infinite health C223-0414 @@ -71573,10 +72010,6 @@ Multi-jump 40BE-DD44+26BE-D4C4+8BBE-D434 - - Invincibility - 8944008 - Infinite health (alt 2) 7E09FF:20 @@ -71680,6 +72113,14 @@ Multi-jump 4064-042F+D367-0F9F+C567-0FBF + + Enemies always drop large energy + C42E-0D2F+D42E-0FFF + + + Enemies always drop large weapon energy + C42E-0D2F+D02E-0FFF + Super-jump D586-6F26 @@ -71751,6 +72192,14 @@ View ending (select Capcom Championship) 81829B:EE+81829C:E0 + + Unlock Capcom Championship mode ending + 82D1F0:EA+82D1F1:EA+82D1F2:EA+82D1F3:EA + + + Unlock Tournament mode ending + 82D29C:EA+82D29D:EA+82D29E:EA+82D29F:EA + Metal Combat - Falcon's Revenge (USA) @@ -72097,6 +72546,10 @@ Infinite bombs on pick-up C2B7-0FF7 + + Collect items from anywhere + 4084-D794+6D8A-0724+F282-0DF4 + Mega-jump EC6A-ADF7 @@ -76654,6 +77107,10 @@ PGA Tour Golf (USA) + + Ball goes in from anywhere + 6D85-67AD+6DCC-ADD7 + Allow 14 clubs for full set instead of 13 D235-6D07+D22A-D40F @@ -78807,6 +79264,10 @@ Infinite lives - P2 3CB5-0467 + + Hit anywhere + 44E8-6446+6DE8-6F36+C9E3-6446 + Replacement planes carry 0 bombs - P1 CEB7-DFD7+62B7-DF07 @@ -79431,9 +79892,14 @@ No score lost when special attack is used DD62-A7A6 - - - EEC4-OD6F+EE64-646C+EE63-04A7+EE68-A7A1 + + Hit anywhere (might make some enemies invisible) + 6DB6-69EA+F9B6-617A + + + Start with more health + EEC4-OD6F+EE64-646C+EE63-04A7+EE68-A7A1 + Start with less health FEC4-0D6F+FE64-646C+FE63-04A7+FE68-A7A1 @@ -83080,9 +83546,14 @@ Infinite health C208-87D1 - - - FDDB-5FB9 + + Hit anywhere + 40F8-84B0 + + + Don't blink after getting hit + FDDB-5FB9 + Falling doesn't use life points C2F4-7FD1 @@ -87983,6 +88454,10 @@ Spin jump in mid air (hold for float down) F53F-6767+DD3F-67A7 + + Press R to scroll through items in the items box + D2AF-6407+D2AF-6DD7+DFAF-6F67+17AF-6FD7+1DAF-6467+62AF-6FA7+A4AD-67A7+A4AD-67D7+A4AF-64D7+CBAF-6F07+D1AF-6D67+D2AD-6707 + Low jump D02C-AF6F @@ -88500,6 +88975,10 @@ Infinite Power Bombs (alt) 17DA-9E8C + + Hit anywhere + 40C8-18DD+6DB1-3C6F+6DC2-1BDD + Super-jumps don't drain energy C22A-456D @@ -89717,6 +90196,28 @@ D4E9-6DEF + + Super Solitaire (USA) (En,Fr,De,Es,It) + + Move cards to any pile - Klondike + 6D8C-476F+DD8A-34AD+DD88-3D0D + + + Move cards to any pile - Free Cell + 6D8F-44A4 + + + + Super Soukoban (Japan) + + Infinite steps + C2CC-64AB + + + Walk through walls + DD88-D4A6+DD88-D706 + + Super Star Wars (USA) (Rev 1) @@ -91357,6 +91858,14 @@ Infinite hits on armor C2AA-0FAF + + Hit anywhere + DD8D-DD0D+DDAB-D4DF + + + Get items from anywhere + 6D8A-AF67 + Heart worth more F684-0F0D @@ -92158,6 +92667,13 @@ 3C38-C25D + + Tecmo Super NBA Basketball (USA) + + Never miss a shot (hold Y and press the shot button) + 7D69-CDE7+C269-CD77+D869-CD57+DC69-CD87+FF69-CF77 + + Teenage Mutant Ninja Turtles IV - Turtles in Time (USA) @@ -92371,6 +92887,26 @@ Start with 7 continues D6B1-CF60 + + Infinite health + 7E0EE460 + + + Full power bar + 7E1AC060 + + + Empty power bar - opponent + 7E1B1000 + + + Opponent dizzy after every knockdown + 7E0FC210 + + + Win one round to win match + 7E195002 + Tengai Makyou Zero (Japan) @@ -93198,6 +93734,18 @@ Race in any country 6DB7-AFEA + + Don't slow down offroad + C229-D4F1 + + + Don't slow down against obstacles + DD23-6499 + + + Don't slow down against cars + DD38-D7F9+DD38-DF29 + Start with 1/2 fuel 972B-0F64 @@ -97118,6 +97666,10 @@ Zero the Kamikaze Squirrel (USA) + + Jump higher + E060-1D62+E060-CF03 + Invincibility 7E0E2C:02 @@ -98947,6 +99499,25 @@ FA1-21E-4C1 + + Bubble Bobble (USA, Europe) + + Hit anywhere + 00D-22E-C4A+18D-29E-08A + + + Hit anywhere - Bosses (except final boss) + 00C-05B-A29+00B-FCB-A29 + + + Get items from anywhere + 00C-02D-A29+00C-0BD-A29+00D-56D-A29+375-8FB-6EE+37D-5FD-A29+C95-90B-91E + + + One hit kill - final boss + AF8-B7B-19E + + Bubble Bobble Part 2 (USA, Europe) @@ -99001,6 +99572,17 @@ BE6-00E-19E + + Bug's Life, A (USA) (SGB Enhanced) + + Infinite lives + 006-2FD-3BE + + + Invincibility (can still drown) + 000-EEE-081 + + BurgerTime Deluxe (World) @@ -99702,6 +100284,13 @@ 0AB-0C8-E6E + + Deer Hunter (USA) + + Infinite time + 004-1FF-19A + + Dig Dug (USA) @@ -100961,6 +101550,14 @@ Kid Icarus - Of Myths and Monsters (USA, Europe) + + Hit anywhere + 008-B8B-5D4 + + + Run into enemies to get Hearts + 185-67B-4CA + Collected hammers seem to count towards your enemy kill number C9A-D18-08F+7AA-B48-E69 @@ -101067,6 +101664,14 @@ Infinite vitality bars except against end of stage boss FA4-63B-4C1 + + Hit anywhere + 003-E1B-F7E + + + Inhale from anywhere + 008-53B-08E+008-67B-7FE + Start with 2 lives 021-BBF-F7E @@ -101114,6 +101719,18 @@ Infinite lives FA1-C4B-4C1 + + Hit anywhere + 006-E5D-6EA+187-04D-2AA + + + Inhale from anywhere + 005-BED-19E+005-DFD-91A + + + Get items from anywhere + 18B-898-08A + One hit and you die AFA-9EC-A28 @@ -102119,6 +102736,17 @@ 095-B2E-E66 + + Ms. Pac-Man (USA) + + Invincibility + 009-06E-E62 + + + Get fruit from anywhere + 00B-21E-D56 + + Mysterium (USA) @@ -102161,6 +102789,44 @@ 084-B5F-F7A + + Nemesis (Europe) + + Hit anywhere - Default weapon + 008-A7D-A29+008-B8D-A29 + + + Hit anywhere - Laser + 009-5FD-A29+009-70D-A29 + + + Hit anywhere - Missiles + 009-CBD-A29+009-DCD-A29 + + + Get items from anywhere + 007-68D-A29 + + + + Nemesis (USA) + + Hit anywhere - normal weapon + 008-A5D-A29+008-94D-A29 + + + Hit anywhere - Laser + 009-5DD-A29+009-4CD-A29 + + + Hit anywhere - Missiles + 009-C9D-A29+009-B8D-A29 + + + Get items from anywhere + 007-55D-A29 + + NFL Football (USA) @@ -102184,6 +102850,13 @@ 08F-59F-F72 + + Ninja Boy (USA, Europe) + + Hit anywhere (can get items from anywhere by punching) + 00E-279-C43 + + Nintendo World Cup (USA, Europe) @@ -102316,6 +102989,17 @@ 081-ACF-E66 + + Pac-Man (USA) + + Invincibility + C97-7DE-A29 + + + Get fruit from anywhere + 009-22E-E69+009-28E-E69 + + Pagemaster, The (USA) (SGB Enhanced) diff --git a/bsnes/data/bsnes.Manifest b/higan/data/higan.Manifest old mode 100644 new mode 100755 similarity index 86% rename from bsnes/data/bsnes.Manifest rename to higan/data/higan.Manifest index e415f87a..2796a434 --- a/bsnes/data/bsnes.Manifest +++ b/higan/data/higan.Manifest @@ -1,6 +1,6 @@ - + diff --git a/bsnes/data/bsnes.desktop b/higan/data/higan.desktop old mode 100644 new mode 100755 similarity index 74% rename from bsnes/data/bsnes.desktop rename to higan/data/higan.desktop index d527e973..70a2242e --- a/bsnes/data/bsnes.desktop +++ b/higan/data/higan.desktop @@ -1,8 +1,8 @@ [Desktop Entry] -Name=bsnes +Name=higan Comment=SNES emulator -Exec=bsnes -Icon=bsnes +Exec=higan +Icon=higan Terminal=false Type=Application Categories=Game;Emulator; diff --git a/higan/data/higan.ico b/higan/data/higan.ico new file mode 100755 index 00000000..72b26f05 Binary files /dev/null and b/higan/data/higan.ico differ diff --git a/higan/data/higan.png b/higan/data/higan.png new file mode 100755 index 00000000..d9a0fcb3 Binary files /dev/null and b/higan/data/higan.png differ diff --git a/bsnes/data/laevateinn.hpp b/higan/data/laevateinn.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/data/laevateinn.hpp rename to higan/data/laevateinn.hpp diff --git a/bsnes/emulator/emulator.hpp b/higan/emulator/emulator.hpp old mode 100644 new mode 100755 similarity index 98% rename from bsnes/emulator/emulator.hpp rename to higan/emulator/emulator.hpp index 6f1cf2d2..89dbedd7 --- a/bsnes/emulator/emulator.hpp +++ b/higan/emulator/emulator.hpp @@ -2,7 +2,7 @@ #define EMULATOR_HPP namespace Emulator { - static const char Name[] = "bsnes"; + static const char Name[] = "higan"; static const char Version[] = "091"; static const char Author[] = "byuu"; static const char License[] = "GPLv3"; diff --git a/bsnes/emulator/interface.hpp b/higan/emulator/interface.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/emulator/interface.hpp rename to higan/emulator/interface.hpp diff --git a/bsnes/fc/Makefile b/higan/fc/Makefile old mode 100644 new mode 100755 similarity index 100% rename from bsnes/fc/Makefile rename to higan/fc/Makefile diff --git a/bsnes/fc/apu/apu.cpp b/higan/fc/apu/apu.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/fc/apu/apu.cpp rename to higan/fc/apu/apu.cpp diff --git a/bsnes/fc/apu/apu.hpp b/higan/fc/apu/apu.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/fc/apu/apu.hpp rename to higan/fc/apu/apu.hpp diff --git a/bsnes/fc/apu/dmc.cpp b/higan/fc/apu/dmc.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/fc/apu/dmc.cpp rename to higan/fc/apu/dmc.cpp diff --git a/bsnes/fc/apu/dmc.hpp b/higan/fc/apu/dmc.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/fc/apu/dmc.hpp rename to higan/fc/apu/dmc.hpp diff --git a/bsnes/fc/apu/envelope.cpp b/higan/fc/apu/envelope.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/fc/apu/envelope.cpp rename to higan/fc/apu/envelope.cpp diff --git a/bsnes/fc/apu/envelope.hpp b/higan/fc/apu/envelope.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/fc/apu/envelope.hpp rename to higan/fc/apu/envelope.hpp diff --git a/bsnes/fc/apu/noise.cpp b/higan/fc/apu/noise.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/fc/apu/noise.cpp rename to higan/fc/apu/noise.cpp diff --git a/bsnes/fc/apu/noise.hpp b/higan/fc/apu/noise.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/fc/apu/noise.hpp rename to higan/fc/apu/noise.hpp diff --git a/bsnes/fc/apu/pulse.cpp b/higan/fc/apu/pulse.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/fc/apu/pulse.cpp rename to higan/fc/apu/pulse.cpp diff --git a/bsnes/fc/apu/pulse.hpp b/higan/fc/apu/pulse.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/fc/apu/pulse.hpp rename to higan/fc/apu/pulse.hpp diff --git a/bsnes/fc/apu/serialization.cpp b/higan/fc/apu/serialization.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/fc/apu/serialization.cpp rename to higan/fc/apu/serialization.cpp diff --git a/bsnes/fc/apu/sweep.cpp b/higan/fc/apu/sweep.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/fc/apu/sweep.cpp rename to higan/fc/apu/sweep.cpp diff --git a/bsnes/fc/apu/sweep.hpp b/higan/fc/apu/sweep.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/fc/apu/sweep.hpp rename to higan/fc/apu/sweep.hpp diff --git a/bsnes/fc/apu/triangle.cpp b/higan/fc/apu/triangle.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/fc/apu/triangle.cpp rename to higan/fc/apu/triangle.cpp diff --git a/bsnes/fc/apu/triangle.hpp b/higan/fc/apu/triangle.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/fc/apu/triangle.hpp rename to higan/fc/apu/triangle.hpp diff --git a/bsnes/fc/cartridge/board/bandai-fcg.cpp b/higan/fc/cartridge/board/bandai-fcg.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/fc/cartridge/board/bandai-fcg.cpp rename to higan/fc/cartridge/board/bandai-fcg.cpp diff --git a/bsnes/fc/cartridge/board/board.cpp b/higan/fc/cartridge/board/board.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/fc/cartridge/board/board.cpp rename to higan/fc/cartridge/board/board.cpp diff --git a/bsnes/fc/cartridge/board/board.hpp b/higan/fc/cartridge/board/board.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/fc/cartridge/board/board.hpp rename to higan/fc/cartridge/board/board.hpp diff --git a/bsnes/fc/cartridge/board/konami-vrc1.cpp b/higan/fc/cartridge/board/konami-vrc1.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/fc/cartridge/board/konami-vrc1.cpp rename to higan/fc/cartridge/board/konami-vrc1.cpp diff --git a/bsnes/fc/cartridge/board/konami-vrc2.cpp b/higan/fc/cartridge/board/konami-vrc2.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/fc/cartridge/board/konami-vrc2.cpp rename to higan/fc/cartridge/board/konami-vrc2.cpp diff --git a/bsnes/fc/cartridge/board/konami-vrc3.cpp b/higan/fc/cartridge/board/konami-vrc3.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/fc/cartridge/board/konami-vrc3.cpp rename to higan/fc/cartridge/board/konami-vrc3.cpp diff --git a/bsnes/fc/cartridge/board/konami-vrc4.cpp b/higan/fc/cartridge/board/konami-vrc4.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/fc/cartridge/board/konami-vrc4.cpp rename to higan/fc/cartridge/board/konami-vrc4.cpp diff --git a/bsnes/fc/cartridge/board/konami-vrc6.cpp b/higan/fc/cartridge/board/konami-vrc6.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/fc/cartridge/board/konami-vrc6.cpp rename to higan/fc/cartridge/board/konami-vrc6.cpp diff --git a/bsnes/fc/cartridge/board/konami-vrc7.cpp b/higan/fc/cartridge/board/konami-vrc7.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/fc/cartridge/board/konami-vrc7.cpp rename to higan/fc/cartridge/board/konami-vrc7.cpp diff --git a/bsnes/fc/cartridge/board/nes-axrom.cpp b/higan/fc/cartridge/board/nes-axrom.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/fc/cartridge/board/nes-axrom.cpp rename to higan/fc/cartridge/board/nes-axrom.cpp diff --git a/bsnes/fc/cartridge/board/nes-bnrom.cpp b/higan/fc/cartridge/board/nes-bnrom.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/fc/cartridge/board/nes-bnrom.cpp rename to higan/fc/cartridge/board/nes-bnrom.cpp diff --git a/bsnes/fc/cartridge/board/nes-cnrom.cpp b/higan/fc/cartridge/board/nes-cnrom.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/fc/cartridge/board/nes-cnrom.cpp rename to higan/fc/cartridge/board/nes-cnrom.cpp diff --git a/bsnes/fc/cartridge/board/nes-exrom.cpp b/higan/fc/cartridge/board/nes-exrom.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/fc/cartridge/board/nes-exrom.cpp rename to higan/fc/cartridge/board/nes-exrom.cpp diff --git a/bsnes/fc/cartridge/board/nes-fxrom.cpp b/higan/fc/cartridge/board/nes-fxrom.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/fc/cartridge/board/nes-fxrom.cpp rename to higan/fc/cartridge/board/nes-fxrom.cpp diff --git a/bsnes/fc/cartridge/board/nes-gxrom.cpp b/higan/fc/cartridge/board/nes-gxrom.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/fc/cartridge/board/nes-gxrom.cpp rename to higan/fc/cartridge/board/nes-gxrom.cpp diff --git a/bsnes/fc/cartridge/board/nes-hkrom.cpp b/higan/fc/cartridge/board/nes-hkrom.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/fc/cartridge/board/nes-hkrom.cpp rename to higan/fc/cartridge/board/nes-hkrom.cpp diff --git a/bsnes/fc/cartridge/board/nes-nrom.cpp b/higan/fc/cartridge/board/nes-nrom.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/fc/cartridge/board/nes-nrom.cpp rename to higan/fc/cartridge/board/nes-nrom.cpp diff --git a/bsnes/fc/cartridge/board/nes-pxrom.cpp b/higan/fc/cartridge/board/nes-pxrom.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/fc/cartridge/board/nes-pxrom.cpp rename to higan/fc/cartridge/board/nes-pxrom.cpp diff --git a/bsnes/fc/cartridge/board/nes-sxrom.cpp b/higan/fc/cartridge/board/nes-sxrom.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/fc/cartridge/board/nes-sxrom.cpp rename to higan/fc/cartridge/board/nes-sxrom.cpp diff --git a/bsnes/fc/cartridge/board/nes-txrom.cpp b/higan/fc/cartridge/board/nes-txrom.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/fc/cartridge/board/nes-txrom.cpp rename to higan/fc/cartridge/board/nes-txrom.cpp diff --git a/bsnes/fc/cartridge/board/nes-uxrom.cpp b/higan/fc/cartridge/board/nes-uxrom.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/fc/cartridge/board/nes-uxrom.cpp rename to higan/fc/cartridge/board/nes-uxrom.cpp diff --git a/bsnes/fc/cartridge/board/sunsoft-5b.cpp b/higan/fc/cartridge/board/sunsoft-5b.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/fc/cartridge/board/sunsoft-5b.cpp rename to higan/fc/cartridge/board/sunsoft-5b.cpp diff --git a/bsnes/fc/cartridge/cartridge.cpp b/higan/fc/cartridge/cartridge.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/fc/cartridge/cartridge.cpp rename to higan/fc/cartridge/cartridge.cpp diff --git a/bsnes/fc/cartridge/cartridge.hpp b/higan/fc/cartridge/cartridge.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/fc/cartridge/cartridge.hpp rename to higan/fc/cartridge/cartridge.hpp diff --git a/bsnes/fc/cartridge/chip/chip.cpp b/higan/fc/cartridge/chip/chip.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/fc/cartridge/chip/chip.cpp rename to higan/fc/cartridge/chip/chip.cpp diff --git a/bsnes/fc/cartridge/chip/chip.hpp b/higan/fc/cartridge/chip/chip.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/fc/cartridge/chip/chip.hpp rename to higan/fc/cartridge/chip/chip.hpp diff --git a/bsnes/fc/cartridge/chip/mmc1.cpp b/higan/fc/cartridge/chip/mmc1.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/fc/cartridge/chip/mmc1.cpp rename to higan/fc/cartridge/chip/mmc1.cpp diff --git a/bsnes/fc/cartridge/chip/mmc3.cpp b/higan/fc/cartridge/chip/mmc3.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/fc/cartridge/chip/mmc3.cpp rename to higan/fc/cartridge/chip/mmc3.cpp diff --git a/bsnes/fc/cartridge/chip/mmc5.cpp b/higan/fc/cartridge/chip/mmc5.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/fc/cartridge/chip/mmc5.cpp rename to higan/fc/cartridge/chip/mmc5.cpp diff --git a/bsnes/fc/cartridge/chip/mmc6.cpp b/higan/fc/cartridge/chip/mmc6.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/fc/cartridge/chip/mmc6.cpp rename to higan/fc/cartridge/chip/mmc6.cpp diff --git a/bsnes/fc/cartridge/chip/vrc1.cpp b/higan/fc/cartridge/chip/vrc1.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/fc/cartridge/chip/vrc1.cpp rename to higan/fc/cartridge/chip/vrc1.cpp diff --git a/bsnes/fc/cartridge/chip/vrc2.cpp b/higan/fc/cartridge/chip/vrc2.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/fc/cartridge/chip/vrc2.cpp rename to higan/fc/cartridge/chip/vrc2.cpp diff --git a/bsnes/fc/cartridge/chip/vrc3.cpp b/higan/fc/cartridge/chip/vrc3.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/fc/cartridge/chip/vrc3.cpp rename to higan/fc/cartridge/chip/vrc3.cpp diff --git a/bsnes/fc/cartridge/chip/vrc4.cpp b/higan/fc/cartridge/chip/vrc4.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/fc/cartridge/chip/vrc4.cpp rename to higan/fc/cartridge/chip/vrc4.cpp diff --git a/bsnes/fc/cartridge/chip/vrc6.cpp b/higan/fc/cartridge/chip/vrc6.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/fc/cartridge/chip/vrc6.cpp rename to higan/fc/cartridge/chip/vrc6.cpp diff --git a/bsnes/fc/cartridge/chip/vrc7.cpp b/higan/fc/cartridge/chip/vrc7.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/fc/cartridge/chip/vrc7.cpp rename to higan/fc/cartridge/chip/vrc7.cpp diff --git a/bsnes/fc/cheat/cheat.cpp b/higan/fc/cheat/cheat.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/fc/cheat/cheat.cpp rename to higan/fc/cheat/cheat.cpp diff --git a/bsnes/fc/cheat/cheat.hpp b/higan/fc/cheat/cheat.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/fc/cheat/cheat.hpp rename to higan/fc/cheat/cheat.hpp diff --git a/bsnes/fc/cpu/cpu.cpp b/higan/fc/cpu/cpu.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/fc/cpu/cpu.cpp rename to higan/fc/cpu/cpu.cpp diff --git a/bsnes/fc/cpu/cpu.hpp b/higan/fc/cpu/cpu.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/fc/cpu/cpu.hpp rename to higan/fc/cpu/cpu.hpp diff --git a/bsnes/fc/cpu/serialization.cpp b/higan/fc/cpu/serialization.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/fc/cpu/serialization.cpp rename to higan/fc/cpu/serialization.cpp diff --git a/bsnes/fc/cpu/timing.cpp b/higan/fc/cpu/timing.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/fc/cpu/timing.cpp rename to higan/fc/cpu/timing.cpp diff --git a/bsnes/fc/fc.hpp b/higan/fc/fc.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/fc/fc.hpp rename to higan/fc/fc.hpp diff --git a/bsnes/fc/input/input.cpp b/higan/fc/input/input.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/fc/input/input.cpp rename to higan/fc/input/input.cpp diff --git a/bsnes/fc/input/input.hpp b/higan/fc/input/input.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/fc/input/input.hpp rename to higan/fc/input/input.hpp diff --git a/bsnes/fc/input/serialization.cpp b/higan/fc/input/serialization.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/fc/input/serialization.cpp rename to higan/fc/input/serialization.cpp diff --git a/bsnes/fc/interface/interface.cpp b/higan/fc/interface/interface.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/fc/interface/interface.cpp rename to higan/fc/interface/interface.cpp diff --git a/bsnes/fc/interface/interface.hpp b/higan/fc/interface/interface.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/fc/interface/interface.hpp rename to higan/fc/interface/interface.hpp diff --git a/bsnes/fc/memory/memory.cpp b/higan/fc/memory/memory.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/fc/memory/memory.cpp rename to higan/fc/memory/memory.cpp diff --git a/bsnes/fc/memory/memory.hpp b/higan/fc/memory/memory.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/fc/memory/memory.hpp rename to higan/fc/memory/memory.hpp diff --git a/bsnes/fc/ppu/ppu.cpp b/higan/fc/ppu/ppu.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/fc/ppu/ppu.cpp rename to higan/fc/ppu/ppu.cpp diff --git a/bsnes/fc/ppu/ppu.hpp b/higan/fc/ppu/ppu.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/fc/ppu/ppu.hpp rename to higan/fc/ppu/ppu.hpp diff --git a/bsnes/fc/ppu/serialization.cpp b/higan/fc/ppu/serialization.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/fc/ppu/serialization.cpp rename to higan/fc/ppu/serialization.cpp diff --git a/bsnes/fc/scheduler/scheduler.cpp b/higan/fc/scheduler/scheduler.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/fc/scheduler/scheduler.cpp rename to higan/fc/scheduler/scheduler.cpp diff --git a/bsnes/fc/scheduler/scheduler.hpp b/higan/fc/scheduler/scheduler.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/fc/scheduler/scheduler.hpp rename to higan/fc/scheduler/scheduler.hpp diff --git a/bsnes/fc/system/serialization.cpp b/higan/fc/system/serialization.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/fc/system/serialization.cpp rename to higan/fc/system/serialization.cpp diff --git a/bsnes/fc/system/system.cpp b/higan/fc/system/system.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/fc/system/system.cpp rename to higan/fc/system/system.cpp diff --git a/bsnes/fc/system/system.hpp b/higan/fc/system/system.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/fc/system/system.hpp rename to higan/fc/system/system.hpp diff --git a/bsnes/fc/video/video.cpp b/higan/fc/video/video.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/fc/video/video.cpp rename to higan/fc/video/video.cpp diff --git a/bsnes/fc/video/video.hpp b/higan/fc/video/video.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/fc/video/video.hpp rename to higan/fc/video/video.hpp diff --git a/bsnes/gb/Makefile b/higan/gb/Makefile old mode 100644 new mode 100755 similarity index 100% rename from bsnes/gb/Makefile rename to higan/gb/Makefile diff --git a/bsnes/gb/apu/apu.cpp b/higan/gb/apu/apu.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/gb/apu/apu.cpp rename to higan/gb/apu/apu.cpp diff --git a/bsnes/gb/apu/apu.hpp b/higan/gb/apu/apu.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/gb/apu/apu.hpp rename to higan/gb/apu/apu.hpp diff --git a/bsnes/gb/apu/master/master.cpp b/higan/gb/apu/master/master.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/gb/apu/master/master.cpp rename to higan/gb/apu/master/master.cpp diff --git a/bsnes/gb/apu/master/master.hpp b/higan/gb/apu/master/master.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/gb/apu/master/master.hpp rename to higan/gb/apu/master/master.hpp diff --git a/bsnes/gb/apu/noise/noise.cpp b/higan/gb/apu/noise/noise.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/gb/apu/noise/noise.cpp rename to higan/gb/apu/noise/noise.cpp diff --git a/bsnes/gb/apu/noise/noise.hpp b/higan/gb/apu/noise/noise.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/gb/apu/noise/noise.hpp rename to higan/gb/apu/noise/noise.hpp diff --git a/bsnes/gb/apu/serialization.cpp b/higan/gb/apu/serialization.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/gb/apu/serialization.cpp rename to higan/gb/apu/serialization.cpp diff --git a/bsnes/gb/apu/square1/square1.cpp b/higan/gb/apu/square1/square1.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/gb/apu/square1/square1.cpp rename to higan/gb/apu/square1/square1.cpp diff --git a/bsnes/gb/apu/square1/square1.hpp b/higan/gb/apu/square1/square1.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/gb/apu/square1/square1.hpp rename to higan/gb/apu/square1/square1.hpp diff --git a/bsnes/gb/apu/square2/square2.cpp b/higan/gb/apu/square2/square2.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/gb/apu/square2/square2.cpp rename to higan/gb/apu/square2/square2.cpp diff --git a/bsnes/gb/apu/square2/square2.hpp b/higan/gb/apu/square2/square2.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/gb/apu/square2/square2.hpp rename to higan/gb/apu/square2/square2.hpp diff --git a/bsnes/gb/apu/wave/wave.cpp b/higan/gb/apu/wave/wave.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/gb/apu/wave/wave.cpp rename to higan/gb/apu/wave/wave.cpp diff --git a/bsnes/gb/apu/wave/wave.hpp b/higan/gb/apu/wave/wave.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/gb/apu/wave/wave.hpp rename to higan/gb/apu/wave/wave.hpp diff --git a/bsnes/gb/cartridge/cartridge.cpp b/higan/gb/cartridge/cartridge.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/gb/cartridge/cartridge.cpp rename to higan/gb/cartridge/cartridge.cpp diff --git a/bsnes/gb/cartridge/cartridge.hpp b/higan/gb/cartridge/cartridge.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/gb/cartridge/cartridge.hpp rename to higan/gb/cartridge/cartridge.hpp diff --git a/bsnes/gb/cartridge/huc1/huc1.cpp b/higan/gb/cartridge/huc1/huc1.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/gb/cartridge/huc1/huc1.cpp rename to higan/gb/cartridge/huc1/huc1.cpp diff --git a/bsnes/gb/cartridge/huc1/huc1.hpp b/higan/gb/cartridge/huc1/huc1.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/gb/cartridge/huc1/huc1.hpp rename to higan/gb/cartridge/huc1/huc1.hpp diff --git a/bsnes/gb/cartridge/huc3/huc3.cpp b/higan/gb/cartridge/huc3/huc3.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/gb/cartridge/huc3/huc3.cpp rename to higan/gb/cartridge/huc3/huc3.cpp diff --git a/bsnes/gb/cartridge/huc3/huc3.hpp b/higan/gb/cartridge/huc3/huc3.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/gb/cartridge/huc3/huc3.hpp rename to higan/gb/cartridge/huc3/huc3.hpp diff --git a/bsnes/gb/cartridge/mbc0/mbc0.cpp b/higan/gb/cartridge/mbc0/mbc0.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/gb/cartridge/mbc0/mbc0.cpp rename to higan/gb/cartridge/mbc0/mbc0.cpp diff --git a/bsnes/gb/cartridge/mbc0/mbc0.hpp b/higan/gb/cartridge/mbc0/mbc0.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/gb/cartridge/mbc0/mbc0.hpp rename to higan/gb/cartridge/mbc0/mbc0.hpp diff --git a/bsnes/gb/cartridge/mbc1/mbc1.cpp b/higan/gb/cartridge/mbc1/mbc1.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/gb/cartridge/mbc1/mbc1.cpp rename to higan/gb/cartridge/mbc1/mbc1.cpp diff --git a/bsnes/gb/cartridge/mbc1/mbc1.hpp b/higan/gb/cartridge/mbc1/mbc1.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/gb/cartridge/mbc1/mbc1.hpp rename to higan/gb/cartridge/mbc1/mbc1.hpp diff --git a/bsnes/gb/cartridge/mbc2/mbc2.cpp b/higan/gb/cartridge/mbc2/mbc2.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/gb/cartridge/mbc2/mbc2.cpp rename to higan/gb/cartridge/mbc2/mbc2.cpp diff --git a/bsnes/gb/cartridge/mbc2/mbc2.hpp b/higan/gb/cartridge/mbc2/mbc2.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/gb/cartridge/mbc2/mbc2.hpp rename to higan/gb/cartridge/mbc2/mbc2.hpp diff --git a/bsnes/gb/cartridge/mbc3/mbc3.cpp b/higan/gb/cartridge/mbc3/mbc3.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/gb/cartridge/mbc3/mbc3.cpp rename to higan/gb/cartridge/mbc3/mbc3.cpp diff --git a/bsnes/gb/cartridge/mbc3/mbc3.hpp b/higan/gb/cartridge/mbc3/mbc3.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/gb/cartridge/mbc3/mbc3.hpp rename to higan/gb/cartridge/mbc3/mbc3.hpp diff --git a/bsnes/gb/cartridge/mbc5/mbc5.cpp b/higan/gb/cartridge/mbc5/mbc5.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/gb/cartridge/mbc5/mbc5.cpp rename to higan/gb/cartridge/mbc5/mbc5.cpp diff --git a/bsnes/gb/cartridge/mbc5/mbc5.hpp b/higan/gb/cartridge/mbc5/mbc5.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/gb/cartridge/mbc5/mbc5.hpp rename to higan/gb/cartridge/mbc5/mbc5.hpp diff --git a/bsnes/gb/cartridge/mmm01/mmm01.cpp b/higan/gb/cartridge/mmm01/mmm01.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/gb/cartridge/mmm01/mmm01.cpp rename to higan/gb/cartridge/mmm01/mmm01.cpp diff --git a/bsnes/gb/cartridge/mmm01/mmm01.hpp b/higan/gb/cartridge/mmm01/mmm01.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/gb/cartridge/mmm01/mmm01.hpp rename to higan/gb/cartridge/mmm01/mmm01.hpp diff --git a/bsnes/gb/cartridge/serialization.cpp b/higan/gb/cartridge/serialization.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/gb/cartridge/serialization.cpp rename to higan/gb/cartridge/serialization.cpp diff --git a/bsnes/gb/cheat/cheat.cpp b/higan/gb/cheat/cheat.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/gb/cheat/cheat.cpp rename to higan/gb/cheat/cheat.cpp diff --git a/bsnes/gb/cheat/cheat.hpp b/higan/gb/cheat/cheat.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/gb/cheat/cheat.hpp rename to higan/gb/cheat/cheat.hpp diff --git a/bsnes/gb/cpu/cpu.cpp b/higan/gb/cpu/cpu.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/gb/cpu/cpu.cpp rename to higan/gb/cpu/cpu.cpp diff --git a/bsnes/gb/cpu/cpu.hpp b/higan/gb/cpu/cpu.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/gb/cpu/cpu.hpp rename to higan/gb/cpu/cpu.hpp diff --git a/bsnes/gb/cpu/memory.cpp b/higan/gb/cpu/memory.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/gb/cpu/memory.cpp rename to higan/gb/cpu/memory.cpp diff --git a/bsnes/gb/cpu/mmio.cpp b/higan/gb/cpu/mmio.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/gb/cpu/mmio.cpp rename to higan/gb/cpu/mmio.cpp diff --git a/bsnes/gb/cpu/serialization.cpp b/higan/gb/cpu/serialization.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/gb/cpu/serialization.cpp rename to higan/gb/cpu/serialization.cpp diff --git a/bsnes/gb/cpu/timing.cpp b/higan/gb/cpu/timing.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/gb/cpu/timing.cpp rename to higan/gb/cpu/timing.cpp diff --git a/bsnes/gb/gb.hpp b/higan/gb/gb.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/gb/gb.hpp rename to higan/gb/gb.hpp diff --git a/bsnes/gb/interface/interface.cpp b/higan/gb/interface/interface.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/gb/interface/interface.cpp rename to higan/gb/interface/interface.cpp diff --git a/bsnes/gb/interface/interface.hpp b/higan/gb/interface/interface.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/gb/interface/interface.hpp rename to higan/gb/interface/interface.hpp diff --git a/bsnes/gb/memory/memory.cpp b/higan/gb/memory/memory.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/gb/memory/memory.cpp rename to higan/gb/memory/memory.cpp diff --git a/bsnes/gb/memory/memory.hpp b/higan/gb/memory/memory.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/gb/memory/memory.hpp rename to higan/gb/memory/memory.hpp diff --git a/bsnes/gb/ppu/cgb.cpp b/higan/gb/ppu/cgb.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/gb/ppu/cgb.cpp rename to higan/gb/ppu/cgb.cpp diff --git a/bsnes/gb/ppu/dmg.cpp b/higan/gb/ppu/dmg.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/gb/ppu/dmg.cpp rename to higan/gb/ppu/dmg.cpp diff --git a/bsnes/gb/ppu/mmio.cpp b/higan/gb/ppu/mmio.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/gb/ppu/mmio.cpp rename to higan/gb/ppu/mmio.cpp diff --git a/bsnes/gb/ppu/ppu.cpp b/higan/gb/ppu/ppu.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/gb/ppu/ppu.cpp rename to higan/gb/ppu/ppu.cpp diff --git a/bsnes/gb/ppu/ppu.hpp b/higan/gb/ppu/ppu.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/gb/ppu/ppu.hpp rename to higan/gb/ppu/ppu.hpp diff --git a/bsnes/gb/ppu/serialization.cpp b/higan/gb/ppu/serialization.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/gb/ppu/serialization.cpp rename to higan/gb/ppu/serialization.cpp diff --git a/bsnes/gb/scheduler/scheduler.cpp b/higan/gb/scheduler/scheduler.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/gb/scheduler/scheduler.cpp rename to higan/gb/scheduler/scheduler.cpp diff --git a/bsnes/gb/scheduler/scheduler.hpp b/higan/gb/scheduler/scheduler.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/gb/scheduler/scheduler.hpp rename to higan/gb/scheduler/scheduler.hpp diff --git a/bsnes/gb/system/serialization.cpp b/higan/gb/system/serialization.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/gb/system/serialization.cpp rename to higan/gb/system/serialization.cpp diff --git a/bsnes/gb/system/system.cpp b/higan/gb/system/system.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/gb/system/system.cpp rename to higan/gb/system/system.cpp diff --git a/bsnes/gb/system/system.hpp b/higan/gb/system/system.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/gb/system/system.hpp rename to higan/gb/system/system.hpp diff --git a/bsnes/gb/video/video.cpp b/higan/gb/video/video.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/gb/video/video.cpp rename to higan/gb/video/video.cpp diff --git a/bsnes/gb/video/video.hpp b/higan/gb/video/video.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/gb/video/video.hpp rename to higan/gb/video/video.hpp diff --git a/bsnes/gba/Makefile b/higan/gba/Makefile old mode 100644 new mode 100755 similarity index 100% rename from bsnes/gba/Makefile rename to higan/gba/Makefile diff --git a/bsnes/gba/apu/apu.cpp b/higan/gba/apu/apu.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/gba/apu/apu.cpp rename to higan/gba/apu/apu.cpp diff --git a/bsnes/gba/apu/apu.hpp b/higan/gba/apu/apu.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/gba/apu/apu.hpp rename to higan/gba/apu/apu.hpp diff --git a/bsnes/gba/apu/fifo.cpp b/higan/gba/apu/fifo.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/gba/apu/fifo.cpp rename to higan/gba/apu/fifo.cpp diff --git a/bsnes/gba/apu/mmio.cpp b/higan/gba/apu/mmio.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/gba/apu/mmio.cpp rename to higan/gba/apu/mmio.cpp diff --git a/bsnes/gba/apu/noise.cpp b/higan/gba/apu/noise.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/gba/apu/noise.cpp rename to higan/gba/apu/noise.cpp diff --git a/bsnes/gba/apu/registers.cpp b/higan/gba/apu/registers.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/gba/apu/registers.cpp rename to higan/gba/apu/registers.cpp diff --git a/bsnes/gba/apu/registers.hpp b/higan/gba/apu/registers.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/gba/apu/registers.hpp rename to higan/gba/apu/registers.hpp diff --git a/bsnes/gba/apu/sequencer.cpp b/higan/gba/apu/sequencer.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/gba/apu/sequencer.cpp rename to higan/gba/apu/sequencer.cpp diff --git a/bsnes/gba/apu/serialization.cpp b/higan/gba/apu/serialization.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/gba/apu/serialization.cpp rename to higan/gba/apu/serialization.cpp diff --git a/bsnes/gba/apu/square.cpp b/higan/gba/apu/square.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/gba/apu/square.cpp rename to higan/gba/apu/square.cpp diff --git a/bsnes/gba/apu/square1.cpp b/higan/gba/apu/square1.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/gba/apu/square1.cpp rename to higan/gba/apu/square1.cpp diff --git a/bsnes/gba/apu/square2.cpp b/higan/gba/apu/square2.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/gba/apu/square2.cpp rename to higan/gba/apu/square2.cpp diff --git a/bsnes/gba/apu/wave.cpp b/higan/gba/apu/wave.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/gba/apu/wave.cpp rename to higan/gba/apu/wave.cpp diff --git a/bsnes/gba/cartridge/cartridge.cpp b/higan/gba/cartridge/cartridge.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/gba/cartridge/cartridge.cpp rename to higan/gba/cartridge/cartridge.cpp diff --git a/bsnes/gba/cartridge/cartridge.hpp b/higan/gba/cartridge/cartridge.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/gba/cartridge/cartridge.hpp rename to higan/gba/cartridge/cartridge.hpp diff --git a/bsnes/gba/cartridge/eeprom.cpp b/higan/gba/cartridge/eeprom.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/gba/cartridge/eeprom.cpp rename to higan/gba/cartridge/eeprom.cpp diff --git a/bsnes/gba/cartridge/flashrom.cpp b/higan/gba/cartridge/flashrom.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/gba/cartridge/flashrom.cpp rename to higan/gba/cartridge/flashrom.cpp diff --git a/bsnes/gba/cartridge/memory.hpp b/higan/gba/cartridge/memory.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/gba/cartridge/memory.hpp rename to higan/gba/cartridge/memory.hpp diff --git a/bsnes/gba/cartridge/serialization.cpp b/higan/gba/cartridge/serialization.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/gba/cartridge/serialization.cpp rename to higan/gba/cartridge/serialization.cpp diff --git a/bsnes/gba/cpu/cpu.cpp b/higan/gba/cpu/cpu.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/gba/cpu/cpu.cpp rename to higan/gba/cpu/cpu.cpp diff --git a/bsnes/gba/cpu/cpu.hpp b/higan/gba/cpu/cpu.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/gba/cpu/cpu.hpp rename to higan/gba/cpu/cpu.hpp diff --git a/bsnes/gba/cpu/dma.cpp b/higan/gba/cpu/dma.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/gba/cpu/dma.cpp rename to higan/gba/cpu/dma.cpp diff --git a/bsnes/gba/cpu/memory.cpp b/higan/gba/cpu/memory.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/gba/cpu/memory.cpp rename to higan/gba/cpu/memory.cpp diff --git a/bsnes/gba/cpu/mmio.cpp b/higan/gba/cpu/mmio.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/gba/cpu/mmio.cpp rename to higan/gba/cpu/mmio.cpp diff --git a/bsnes/gba/cpu/registers.cpp b/higan/gba/cpu/registers.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/gba/cpu/registers.cpp rename to higan/gba/cpu/registers.cpp diff --git a/bsnes/gba/cpu/registers.hpp b/higan/gba/cpu/registers.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/gba/cpu/registers.hpp rename to higan/gba/cpu/registers.hpp diff --git a/bsnes/gba/cpu/serialization.cpp b/higan/gba/cpu/serialization.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/gba/cpu/serialization.cpp rename to higan/gba/cpu/serialization.cpp diff --git a/bsnes/gba/cpu/state.hpp b/higan/gba/cpu/state.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/gba/cpu/state.hpp rename to higan/gba/cpu/state.hpp diff --git a/bsnes/gba/cpu/timer.cpp b/higan/gba/cpu/timer.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/gba/cpu/timer.cpp rename to higan/gba/cpu/timer.cpp diff --git a/bsnes/gba/gba.hpp b/higan/gba/gba.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/gba/gba.hpp rename to higan/gba/gba.hpp diff --git a/bsnes/gba/interface/interface.cpp b/higan/gba/interface/interface.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/gba/interface/interface.cpp rename to higan/gba/interface/interface.cpp diff --git a/bsnes/gba/interface/interface.hpp b/higan/gba/interface/interface.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/gba/interface/interface.hpp rename to higan/gba/interface/interface.hpp diff --git a/bsnes/gba/memory/memory.cpp b/higan/gba/memory/memory.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/gba/memory/memory.cpp rename to higan/gba/memory/memory.cpp diff --git a/bsnes/gba/memory/memory.hpp b/higan/gba/memory/memory.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/gba/memory/memory.hpp rename to higan/gba/memory/memory.hpp diff --git a/bsnes/gba/memory/mmio.cpp b/higan/gba/memory/mmio.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/gba/memory/mmio.cpp rename to higan/gba/memory/mmio.cpp diff --git a/bsnes/gba/memory/serialization.cpp b/higan/gba/memory/serialization.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/gba/memory/serialization.cpp rename to higan/gba/memory/serialization.cpp diff --git a/bsnes/gba/ppu/background.cpp b/higan/gba/ppu/background.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/gba/ppu/background.cpp rename to higan/gba/ppu/background.cpp diff --git a/bsnes/gba/ppu/memory.cpp b/higan/gba/ppu/memory.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/gba/ppu/memory.cpp rename to higan/gba/ppu/memory.cpp diff --git a/bsnes/gba/ppu/mmio.cpp b/higan/gba/ppu/mmio.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/gba/ppu/mmio.cpp rename to higan/gba/ppu/mmio.cpp diff --git a/bsnes/gba/ppu/mosaic.cpp b/higan/gba/ppu/mosaic.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/gba/ppu/mosaic.cpp rename to higan/gba/ppu/mosaic.cpp diff --git a/bsnes/gba/ppu/object.cpp b/higan/gba/ppu/object.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/gba/ppu/object.cpp rename to higan/gba/ppu/object.cpp diff --git a/bsnes/gba/ppu/ppu.cpp b/higan/gba/ppu/ppu.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/gba/ppu/ppu.cpp rename to higan/gba/ppu/ppu.cpp diff --git a/bsnes/gba/ppu/ppu.hpp b/higan/gba/ppu/ppu.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/gba/ppu/ppu.hpp rename to higan/gba/ppu/ppu.hpp diff --git a/bsnes/gba/ppu/registers.cpp b/higan/gba/ppu/registers.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/gba/ppu/registers.cpp rename to higan/gba/ppu/registers.cpp diff --git a/bsnes/gba/ppu/registers.hpp b/higan/gba/ppu/registers.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/gba/ppu/registers.hpp rename to higan/gba/ppu/registers.hpp diff --git a/bsnes/gba/ppu/screen.cpp b/higan/gba/ppu/screen.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/gba/ppu/screen.cpp rename to higan/gba/ppu/screen.cpp diff --git a/bsnes/gba/ppu/serialization.cpp b/higan/gba/ppu/serialization.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/gba/ppu/serialization.cpp rename to higan/gba/ppu/serialization.cpp diff --git a/bsnes/gba/ppu/state.hpp b/higan/gba/ppu/state.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/gba/ppu/state.hpp rename to higan/gba/ppu/state.hpp diff --git a/bsnes/gba/scheduler/scheduler.cpp b/higan/gba/scheduler/scheduler.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/gba/scheduler/scheduler.cpp rename to higan/gba/scheduler/scheduler.cpp diff --git a/bsnes/gba/scheduler/scheduler.hpp b/higan/gba/scheduler/scheduler.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/gba/scheduler/scheduler.hpp rename to higan/gba/scheduler/scheduler.hpp diff --git a/bsnes/gba/system/bios.cpp b/higan/gba/system/bios.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/gba/system/bios.cpp rename to higan/gba/system/bios.cpp diff --git a/bsnes/gba/system/serialization.cpp b/higan/gba/system/serialization.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/gba/system/serialization.cpp rename to higan/gba/system/serialization.cpp diff --git a/bsnes/gba/system/system.cpp b/higan/gba/system/system.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/gba/system/system.cpp rename to higan/gba/system/system.cpp diff --git a/bsnes/gba/system/system.hpp b/higan/gba/system/system.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/gba/system/system.hpp rename to higan/gba/system/system.hpp diff --git a/bsnes/gba/video/video.cpp b/higan/gba/video/video.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/gba/video/video.cpp rename to higan/gba/video/video.cpp diff --git a/bsnes/gba/video/video.hpp b/higan/gba/video/video.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/gba/video/video.hpp rename to higan/gba/video/video.hpp diff --git a/bsnes/libco/amd64.c b/higan/libco/amd64.c old mode 100644 new mode 100755 similarity index 100% rename from bsnes/libco/amd64.c rename to higan/libco/amd64.c diff --git a/bsnes/libco/fiber.c b/higan/libco/fiber.c old mode 100644 new mode 100755 similarity index 100% rename from bsnes/libco/fiber.c rename to higan/libco/fiber.c diff --git a/bsnes/libco/libco.c b/higan/libco/libco.c old mode 100644 new mode 100755 similarity index 100% rename from bsnes/libco/libco.c rename to higan/libco/libco.c diff --git a/bsnes/libco/libco.h b/higan/libco/libco.h old mode 100644 new mode 100755 similarity index 100% rename from bsnes/libco/libco.h rename to higan/libco/libco.h diff --git a/bsnes/libco/ppc.c b/higan/libco/ppc.c old mode 100644 new mode 100755 similarity index 100% rename from bsnes/libco/ppc.c rename to higan/libco/ppc.c diff --git a/bsnes/libco/sjlj.c b/higan/libco/sjlj.c old mode 100644 new mode 100755 similarity index 100% rename from bsnes/libco/sjlj.c rename to higan/libco/sjlj.c diff --git a/bsnes/libco/ucontext.c b/higan/libco/ucontext.c old mode 100644 new mode 100755 similarity index 100% rename from bsnes/libco/ucontext.c rename to higan/libco/ucontext.c diff --git a/bsnes/libco/x86.c b/higan/libco/x86.c old mode 100644 new mode 100755 similarity index 100% rename from bsnes/libco/x86.c rename to higan/libco/x86.c diff --git a/bsnes/nall/Makefile b/higan/nall/Makefile old mode 100644 new mode 100755 similarity index 100% rename from bsnes/nall/Makefile rename to higan/nall/Makefile diff --git a/bsnes/nall/algorithm.hpp b/higan/nall/algorithm.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/nall/algorithm.hpp rename to higan/nall/algorithm.hpp diff --git a/bsnes/nall/any.hpp b/higan/nall/any.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/nall/any.hpp rename to higan/nall/any.hpp diff --git a/bsnes/nall/atoi.hpp b/higan/nall/atoi.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/nall/atoi.hpp rename to higan/nall/atoi.hpp diff --git a/bsnes/nall/base64.hpp b/higan/nall/base64.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/nall/base64.hpp rename to higan/nall/base64.hpp diff --git a/bsnes/nall/bit.hpp b/higan/nall/bit.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/nall/bit.hpp rename to higan/nall/bit.hpp diff --git a/bsnes/nall/bmp.hpp b/higan/nall/bmp.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/nall/bmp.hpp rename to higan/nall/bmp.hpp diff --git a/bsnes/nall/bps/delta.hpp b/higan/nall/bps/delta.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/nall/bps/delta.hpp rename to higan/nall/bps/delta.hpp diff --git a/bsnes/nall/bps/linear.hpp b/higan/nall/bps/linear.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/nall/bps/linear.hpp rename to higan/nall/bps/linear.hpp diff --git a/bsnes/nall/bps/metadata.hpp b/higan/nall/bps/metadata.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/nall/bps/metadata.hpp rename to higan/nall/bps/metadata.hpp diff --git a/higan/nall/bps/multi.hpp b/higan/nall/bps/multi.hpp new file mode 100755 index 00000000..f4a9b670 --- /dev/null +++ b/higan/nall/bps/multi.hpp @@ -0,0 +1,232 @@ +#ifndef NALL_BPS_MULTI_HPP +#define NALL_BPS_MULTI_HPP + +#include +#include +#include + +namespace nall { + +struct bpsmulti { + enum : unsigned { + CreatePath = 0, + CreateFile = 1, + ModifyFile = 2, + MirrorFile = 3, + }; + + bool create(const string &patchName, const string &sourcePath, const string &targetPath, bool delta = false, const string &metadata = "") { + if(fp.open()) fp.close(); + fp.open(patchName, file::mode::write); + checksum = ~0; + + writeString("BPM1"); //signature + writeNumber(metadata.length()); + writeString(metadata); + + lstring sourceList, targetList; + ls(sourceList, sourcePath, sourcePath); + ls(targetList, targetPath, targetPath); + + for(auto &targetName : targetList) { + if(targetName.endswith("/")) { + writeNumber(CreatePath | ((targetName.length() - 1) << 2)); + writeString(targetName); + } else if(auto position = sourceList.find(targetName)) { //note: sourceName == targetName + file sp, dp; + sp.open({sourcePath, targetName}, file::mode::read); + dp.open({targetPath, targetName}, file::mode::read); + + bool identical = sp.size() == dp.size(); + uint32_t cksum = ~0; + + for(unsigned n = 0; n < sp.size(); n++) { + uint8_t byte = sp.read(); + if(identical && byte != dp.read()) identical = false; + cksum = crc32_adjust(cksum, byte); + } + + writeNumber((identical ? MirrorFile : ModifyFile) | ((targetName.length() - 1) << 2)); + writeString(targetName); + writeNumber(targetName.length() - 1); + writeString(targetName); + if(identical) { + writeChecksum(~cksum); + continue; + } + + if(delta == false) { + bpslinear patch; + patch.source({sourcePath, targetName}); + patch.target({targetPath, targetName}); + patch.create({temppath(), "temp.bps"}); + } else { + bpsdelta patch; + patch.source({sourcePath, targetName}); + patch.target({targetPath, targetName}); + patch.create({temppath(), "temp.bps"}); + } + + auto buffer = file::read({temppath(), "temp.bps"}); + writeNumber(buffer.size()); + for(auto &byte : buffer) write(byte); + } else { + writeNumber(CreateFile | ((targetName.length() - 1) << 2)); + writeString(targetName); + auto buffer = file::read({targetPath, targetName}); + writeNumber(buffer.size()); + for(auto &byte : buffer) write(byte); + writeChecksum(crc32_calculate(buffer.data(), buffer.size())); + } + } + + //checksum + writeChecksum(~checksum); + fp.close(); + return true; + } + + bool apply(const string &patchName, const string &sourcePath, const string &targetPath) { + directory::remove(targetPath); //start with a clean directory + directory::create(targetPath); + + if(fp.open()) fp.close(); + fp.open(patchName, file::mode::read); + checksum = ~0; + + if(readString(4) != "BPM1") return false; + auto metadataLength = readNumber(); + while(metadataLength--) read(); + + while(fp.offset() < fp.size() - 4) { + auto encoding = readNumber(); + unsigned action = encoding & 3; + unsigned targetLength = (encoding >> 2) + 1; + string targetName = readString(targetLength); + + if(action == CreatePath) { + directory::create({targetPath, targetName}); + } else if(action == CreateFile) { + file fp; + fp.open({targetPath, targetName}, file::mode::write); + auto fileSize = readNumber(); + while(fileSize--) fp.write(read()); + uint32_t cksum = readChecksum(); + } else if(action == ModifyFile) { + auto sourceLength = readNumber() + 1; + string sourceName = readString(sourceLength); + auto patchSize = readNumber(); + vector buffer; + buffer.resize(patchSize); + for(unsigned n = 0; n < patchSize; n++) buffer[n] = read(); + bpspatch patch; + patch.modify(buffer.data(), buffer.size()); + patch.source({sourcePath, sourceName}); + patch.target({targetPath, targetName}); + if(patch.apply() != bpspatch::result::success) return false; + } else if(action == MirrorFile) { + auto sourceLength = readNumber() + 1; + string sourceName = readString(sourceLength); + file::copy({sourcePath, sourceName}, {targetPath, targetName}); + uint32_t cksum = readChecksum(); + } + } + + uint32_t cksum = ~checksum; + if(read() != (uint8_t)(cksum >> 0)) return false; + if(read() != (uint8_t)(cksum >> 8)) return false; + if(read() != (uint8_t)(cksum >> 16)) return false; + if(read() != (uint8_t)(cksum >> 24)) return false; + + fp.close(); + return true; + } + +protected: + file fp; + uint32_t checksum; + + //create() functions + void ls(lstring &list, const string &path, const string &basepath) { + lstring paths = directory::folders(path); + for(auto &pathname : paths) { + list.append(string{path, pathname}.ltrim<1>(basepath)); + ls(list, {path, pathname}, basepath); + } + + lstring files = directory::files(path); + for(auto &filename : files) { + list.append(string{path, filename}.ltrim<1>(basepath)); + } + } + + void write(uint8_t data) { + fp.write(data); + checksum = crc32_adjust(checksum, data); + } + + void writeNumber(uint64_t data) { + while(true) { + uint64_t x = data & 0x7f; + data >>= 7; + if(data == 0) { + write(0x80 | x); + break; + } + write(x); + data--; + } + } + + void writeString(const string &text) { + unsigned length = text.length(); + for(unsigned n = 0; n < length; n++) write(text[n]); + } + + void writeChecksum(uint32_t cksum) { + write(cksum >> 0); + write(cksum >> 8); + write(cksum >> 16); + write(cksum >> 24); + } + + //apply() functions + uint8_t read() { + uint8_t data = fp.read(); + checksum = crc32_adjust(checksum, data); + return data; + } + + uint64_t readNumber() { + uint64_t data = 0, shift = 1; + while(true) { + uint8_t x = read(); + data += (x & 0x7f) * shift; + if(x & 0x80) break; + shift <<= 7; + data += shift; + } + return data; + } + + string readString(unsigned length) { + string text; + text.reserve(length + 1); + for(unsigned n = 0; n < length; n++) text[n] = read(); + text[length] = 0; + return text; + } + + uint32_t readChecksum() { + uint32_t checksum = 0; + checksum |= read() << 0; + checksum |= read() << 8; + checksum |= read() << 16; + checksum |= read() << 24; + return checksum; + } +}; + +} + +#endif diff --git a/bsnes/nall/bps/patch.hpp b/higan/nall/bps/patch.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/nall/bps/patch.hpp rename to higan/nall/bps/patch.hpp diff --git a/bsnes/nall/compositor.hpp b/higan/nall/compositor.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/nall/compositor.hpp rename to higan/nall/compositor.hpp diff --git a/bsnes/nall/config.hpp b/higan/nall/config.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/nall/config.hpp rename to higan/nall/config.hpp diff --git a/bsnes/nall/crc32.hpp b/higan/nall/crc32.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/nall/crc32.hpp rename to higan/nall/crc32.hpp diff --git a/bsnes/nall/directory.hpp b/higan/nall/directory.hpp old mode 100644 new mode 100755 similarity index 85% rename from bsnes/nall/directory.hpp rename to higan/nall/directory.hpp index 4dba2b70..36db7532 --- a/bsnes/nall/directory.hpp +++ b/higan/nall/directory.hpp @@ -1,6 +1,7 @@ #ifndef NALL_DIRECTORY_HPP #define NALL_DIRECTORY_HPP +#include #include #include #include @@ -18,7 +19,7 @@ namespace nall { struct directory { static bool create(const string &pathname, unsigned permissions = 0755); //recursive - static bool remove(const string &pathname); + static bool remove(const string &pathname); //recursive static bool exists(const string &pathname); static lstring folders(const string &pathname, const string &pattern = "*"); static lstring files(const string &pathname, const string &pattern = "*"); @@ -27,19 +28,22 @@ struct directory { #if defined(PLATFORM_WINDOWS) inline bool directory::create(const string &pathname, unsigned permissions) { - string fullpath = pathname, path; - fullpath.transform("/", "\\"); - fullpath.rtrim<1>("\\"); - lstring pathpart = fullpath.split("\\"); - bool result = false; - for(auto &part : pathpart) { - path.append(part, "\\"); - result = _wmkdir(utf16_t(path)) == 0; + string path; + lstring list = string{pathname}.transform("\\", "/").rtrim<1>("/").split("/"); + bool result = true; + for(auto &part : list) { + path.append(part, "/"); + result &= (_wmkdir(utf16_t(path)) == 0); } return result; } inline bool directory::remove(const string &pathname) { + lstring list = directory::contents(pathname); + for(auto &name : list) { + if(name.endswith("/")) directory::remove({pathname, name}); + else file::remove({pathname, name}); + } return _wrmdir(utf16_t(pathname)) == 0; } @@ -116,17 +120,22 @@ struct directory { } #else inline bool directory::create(const string &pathname, unsigned permissions) { - string fullpath = pathname, path = "/"; - fullpath.trim<1>("/"); - lstring pathpart = fullpath.split("/"); - for(auto &part : pathpart) { - if(!directory::exists(path)) mkdir(path, permissions); + string path; + lstring list = string{pathname}.rtrim<1>("/").split("/"); + bool result = true; + for(auto &part : list) { path.append(part, "/"); + result &= (mkdir(path, permissions) == 0); } - return mkdir(path, permissions) == 0; + return result; } inline bool directory::remove(const string &pathname) { + lstring list = directory::contents(pathname); + for(auto &name : list) { + if(name.endswith("/")) directory::remove({pathname, name}); + else file::remove({pathname, name}); + } return rmdir(pathname) == 0; } diff --git a/bsnes/nall/dl.hpp b/higan/nall/dl.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/nall/dl.hpp rename to higan/nall/dl.hpp diff --git a/bsnes/nall/dsp.hpp b/higan/nall/dsp.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/nall/dsp.hpp rename to higan/nall/dsp.hpp diff --git a/bsnes/nall/dsp/buffer.hpp b/higan/nall/dsp/buffer.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/nall/dsp/buffer.hpp rename to higan/nall/dsp/buffer.hpp diff --git a/bsnes/nall/dsp/core.hpp b/higan/nall/dsp/core.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/nall/dsp/core.hpp rename to higan/nall/dsp/core.hpp diff --git a/bsnes/nall/dsp/resample/average.hpp b/higan/nall/dsp/resample/average.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/nall/dsp/resample/average.hpp rename to higan/nall/dsp/resample/average.hpp diff --git a/bsnes/nall/dsp/resample/cosine.hpp b/higan/nall/dsp/resample/cosine.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/nall/dsp/resample/cosine.hpp rename to higan/nall/dsp/resample/cosine.hpp diff --git a/bsnes/nall/dsp/resample/cubic.hpp b/higan/nall/dsp/resample/cubic.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/nall/dsp/resample/cubic.hpp rename to higan/nall/dsp/resample/cubic.hpp diff --git a/bsnes/nall/dsp/resample/hermite.hpp b/higan/nall/dsp/resample/hermite.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/nall/dsp/resample/hermite.hpp rename to higan/nall/dsp/resample/hermite.hpp diff --git a/bsnes/nall/dsp/resample/lib/sinc.hpp b/higan/nall/dsp/resample/lib/sinc.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/nall/dsp/resample/lib/sinc.hpp rename to higan/nall/dsp/resample/lib/sinc.hpp diff --git a/bsnes/nall/dsp/resample/linear.hpp b/higan/nall/dsp/resample/linear.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/nall/dsp/resample/linear.hpp rename to higan/nall/dsp/resample/linear.hpp diff --git a/bsnes/nall/dsp/resample/nearest.hpp b/higan/nall/dsp/resample/nearest.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/nall/dsp/resample/nearest.hpp rename to higan/nall/dsp/resample/nearest.hpp diff --git a/bsnes/nall/dsp/resample/sinc.hpp b/higan/nall/dsp/resample/sinc.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/nall/dsp/resample/sinc.hpp rename to higan/nall/dsp/resample/sinc.hpp diff --git a/bsnes/nall/dsp/settings.hpp b/higan/nall/dsp/settings.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/nall/dsp/settings.hpp rename to higan/nall/dsp/settings.hpp diff --git a/bsnes/nall/emulation/famicom.hpp b/higan/nall/emulation/famicom.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/nall/emulation/famicom.hpp rename to higan/nall/emulation/famicom.hpp diff --git a/bsnes/nall/emulation/game-boy-advance.hpp b/higan/nall/emulation/game-boy-advance.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/nall/emulation/game-boy-advance.hpp rename to higan/nall/emulation/game-boy-advance.hpp diff --git a/bsnes/nall/emulation/game-boy.hpp b/higan/nall/emulation/game-boy.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/nall/emulation/game-boy.hpp rename to higan/nall/emulation/game-boy.hpp diff --git a/bsnes/nall/emulation/satellaview.hpp b/higan/nall/emulation/satellaview.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/nall/emulation/satellaview.hpp rename to higan/nall/emulation/satellaview.hpp diff --git a/bsnes/nall/emulation/sufami-turbo.hpp b/higan/nall/emulation/sufami-turbo.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/nall/emulation/sufami-turbo.hpp rename to higan/nall/emulation/sufami-turbo.hpp diff --git a/bsnes/nall/emulation/super-famicom-usart.hpp b/higan/nall/emulation/super-famicom-usart.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/nall/emulation/super-famicom-usart.hpp rename to higan/nall/emulation/super-famicom-usart.hpp diff --git a/bsnes/nall/emulation/super-famicom.hpp b/higan/nall/emulation/super-famicom.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/nall/emulation/super-famicom.hpp rename to higan/nall/emulation/super-famicom.hpp diff --git a/bsnes/nall/endian.hpp b/higan/nall/endian.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/nall/endian.hpp rename to higan/nall/endian.hpp diff --git a/bsnes/nall/file.hpp b/higan/nall/file.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/nall/file.hpp rename to higan/nall/file.hpp diff --git a/bsnes/nall/filemap.hpp b/higan/nall/filemap.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/nall/filemap.hpp rename to higan/nall/filemap.hpp diff --git a/bsnes/nall/function.hpp b/higan/nall/function.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/nall/function.hpp rename to higan/nall/function.hpp diff --git a/bsnes/nall/gzip.hpp b/higan/nall/gzip.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/nall/gzip.hpp rename to higan/nall/gzip.hpp diff --git a/bsnes/nall/http.hpp b/higan/nall/http.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/nall/http.hpp rename to higan/nall/http.hpp diff --git a/bsnes/nall/image.hpp b/higan/nall/image.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/nall/image.hpp rename to higan/nall/image.hpp diff --git a/bsnes/nall/inflate.hpp b/higan/nall/inflate.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/nall/inflate.hpp rename to higan/nall/inflate.hpp diff --git a/bsnes/nall/input.hpp b/higan/nall/input.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/nall/input.hpp rename to higan/nall/input.hpp diff --git a/bsnes/nall/interpolation.hpp b/higan/nall/interpolation.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/nall/interpolation.hpp rename to higan/nall/interpolation.hpp diff --git a/bsnes/nall/intrinsics.hpp b/higan/nall/intrinsics.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/nall/intrinsics.hpp rename to higan/nall/intrinsics.hpp diff --git a/bsnes/nall/invoke.hpp b/higan/nall/invoke.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/nall/invoke.hpp rename to higan/nall/invoke.hpp diff --git a/bsnes/nall/ips.hpp b/higan/nall/ips.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/nall/ips.hpp rename to higan/nall/ips.hpp diff --git a/bsnes/nall/lzss.hpp b/higan/nall/lzss.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/nall/lzss.hpp rename to higan/nall/lzss.hpp diff --git a/bsnes/nall/map.hpp b/higan/nall/map.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/nall/map.hpp rename to higan/nall/map.hpp diff --git a/bsnes/nall/mosaic.hpp b/higan/nall/mosaic.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/nall/mosaic.hpp rename to higan/nall/mosaic.hpp diff --git a/bsnes/nall/mosaic/bitstream.hpp b/higan/nall/mosaic/bitstream.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/nall/mosaic/bitstream.hpp rename to higan/nall/mosaic/bitstream.hpp diff --git a/bsnes/nall/mosaic/context.hpp b/higan/nall/mosaic/context.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/nall/mosaic/context.hpp rename to higan/nall/mosaic/context.hpp diff --git a/bsnes/nall/mosaic/parser.hpp b/higan/nall/mosaic/parser.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/nall/mosaic/parser.hpp rename to higan/nall/mosaic/parser.hpp diff --git a/bsnes/nall/nall.hpp b/higan/nall/nall.hpp old mode 100644 new mode 100755 similarity index 98% rename from bsnes/nall/nall.hpp rename to higan/nall/nall.hpp index 9a8f1dfa..ff2ce9ab --- a/bsnes/nall/nall.hpp +++ b/higan/nall/nall.hpp @@ -39,6 +39,7 @@ #include #include #include +#include #include #include #include diff --git a/bsnes/nall/platform.hpp b/higan/nall/platform.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/nall/platform.hpp rename to higan/nall/platform.hpp diff --git a/bsnes/nall/png.hpp b/higan/nall/png.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/nall/png.hpp rename to higan/nall/png.hpp diff --git a/bsnes/nall/priority-queue.hpp b/higan/nall/priority-queue.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/nall/priority-queue.hpp rename to higan/nall/priority-queue.hpp diff --git a/bsnes/nall/property.hpp b/higan/nall/property.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/nall/property.hpp rename to higan/nall/property.hpp diff --git a/bsnes/nall/public-cast.hpp b/higan/nall/public-cast.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/nall/public-cast.hpp rename to higan/nall/public-cast.hpp diff --git a/bsnes/nall/random.hpp b/higan/nall/random.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/nall/random.hpp rename to higan/nall/random.hpp diff --git a/bsnes/nall/serial.hpp b/higan/nall/serial.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/nall/serial.hpp rename to higan/nall/serial.hpp diff --git a/bsnes/nall/serializer.hpp b/higan/nall/serializer.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/nall/serializer.hpp rename to higan/nall/serializer.hpp diff --git a/bsnes/nall/set.hpp b/higan/nall/set.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/nall/set.hpp rename to higan/nall/set.hpp diff --git a/bsnes/nall/sha256.hpp b/higan/nall/sha256.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/nall/sha256.hpp rename to higan/nall/sha256.hpp diff --git a/bsnes/nall/sort.hpp b/higan/nall/sort.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/nall/sort.hpp rename to higan/nall/sort.hpp diff --git a/bsnes/nall/stdint.hpp b/higan/nall/stdint.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/nall/stdint.hpp rename to higan/nall/stdint.hpp diff --git a/bsnes/nall/stream.hpp b/higan/nall/stream.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/nall/stream.hpp rename to higan/nall/stream.hpp diff --git a/bsnes/nall/stream/auto.hpp b/higan/nall/stream/auto.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/nall/stream/auto.hpp rename to higan/nall/stream/auto.hpp diff --git a/bsnes/nall/stream/file.hpp b/higan/nall/stream/file.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/nall/stream/file.hpp rename to higan/nall/stream/file.hpp diff --git a/bsnes/nall/stream/gzip.hpp b/higan/nall/stream/gzip.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/nall/stream/gzip.hpp rename to higan/nall/stream/gzip.hpp diff --git a/bsnes/nall/stream/http.hpp b/higan/nall/stream/http.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/nall/stream/http.hpp rename to higan/nall/stream/http.hpp diff --git a/bsnes/nall/stream/memory.hpp b/higan/nall/stream/memory.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/nall/stream/memory.hpp rename to higan/nall/stream/memory.hpp diff --git a/bsnes/nall/stream/mmap.hpp b/higan/nall/stream/mmap.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/nall/stream/mmap.hpp rename to higan/nall/stream/mmap.hpp diff --git a/bsnes/nall/stream/stream.hpp b/higan/nall/stream/stream.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/nall/stream/stream.hpp rename to higan/nall/stream/stream.hpp diff --git a/bsnes/nall/stream/vector.hpp b/higan/nall/stream/vector.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/nall/stream/vector.hpp rename to higan/nall/stream/vector.hpp diff --git a/bsnes/nall/stream/zip.hpp b/higan/nall/stream/zip.hpp old mode 100644 new mode 100755 similarity index 93% rename from bsnes/nall/stream/zip.hpp rename to higan/nall/stream/zip.hpp index 975cdeff..94aa3992 --- a/bsnes/nall/stream/zip.hpp +++ b/higan/nall/stream/zip.hpp @@ -1,7 +1,7 @@ #ifndef NALL_STREAM_ZIP_HPP #define NALL_STREAM_ZIP_HPP -#include +#include namespace nall { @@ -14,7 +14,7 @@ struct zipstream : memorystream { uint8_t *data = new uint8_t[size]; stream.read(data, size); - zip archive; + unzip archive; if(archive.open(data, size) == false) return; delete[] data; diff --git a/bsnes/nall/string.hpp b/higan/nall/string.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/nall/string.hpp rename to higan/nall/string.hpp diff --git a/bsnes/nall/string/base.hpp b/higan/nall/string/base.hpp old mode 100644 new mode 100755 similarity index 99% rename from bsnes/nall/string/base.hpp rename to higan/nall/string/base.hpp index f70c1247..174dfc25 --- a/bsnes/nall/string/base.hpp +++ b/higan/nall/string/base.hpp @@ -163,6 +163,7 @@ namespace nall { inline string realpath(const string &name); inline string userpath(); inline string configpath(); + inline string temppath(); //strm.hpp inline unsigned strmcpy(char *target, const char *source, unsigned length); diff --git a/bsnes/nall/string/bml.hpp b/higan/nall/string/bml.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/nall/string/bml.hpp rename to higan/nall/string/bml.hpp diff --git a/bsnes/nall/string/bsv.hpp b/higan/nall/string/bsv.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/nall/string/bsv.hpp rename to higan/nall/string/bsv.hpp diff --git a/bsnes/nall/string/cast.hpp b/higan/nall/string/cast.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/nall/string/cast.hpp rename to higan/nall/string/cast.hpp diff --git a/bsnes/nall/string/compare.hpp b/higan/nall/string/compare.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/nall/string/compare.hpp rename to higan/nall/string/compare.hpp diff --git a/bsnes/nall/string/convert.hpp b/higan/nall/string/convert.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/nall/string/convert.hpp rename to higan/nall/string/convert.hpp diff --git a/bsnes/nall/string/core.hpp b/higan/nall/string/core.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/nall/string/core.hpp rename to higan/nall/string/core.hpp diff --git a/bsnes/nall/string/cstring.hpp b/higan/nall/string/cstring.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/nall/string/cstring.hpp rename to higan/nall/string/cstring.hpp diff --git a/bsnes/nall/string/filename.hpp b/higan/nall/string/filename.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/nall/string/filename.hpp rename to higan/nall/string/filename.hpp diff --git a/bsnes/nall/string/math-fixed-point.hpp b/higan/nall/string/math-fixed-point.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/nall/string/math-fixed-point.hpp rename to higan/nall/string/math-fixed-point.hpp diff --git a/bsnes/nall/string/math-floating-point.hpp b/higan/nall/string/math-floating-point.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/nall/string/math-floating-point.hpp rename to higan/nall/string/math-floating-point.hpp diff --git a/bsnes/nall/string/platform.hpp b/higan/nall/string/platform.hpp old mode 100644 new mode 100755 similarity index 84% rename from bsnes/nall/string/platform.hpp rename to higan/nall/string/platform.hpp index 469d79b3..6465a32f --- a/bsnes/nall/string/platform.hpp +++ b/higan/nall/string/platform.hpp @@ -29,6 +29,7 @@ string realpath(const string &name) { char path[PATH_MAX] = ""; if(::realpath(name, path)) result = path; #endif + if(result.empty()) result = {activepath(), name}; return result; } @@ -58,6 +59,17 @@ string configpath() { #endif } +string temppath() { + #ifdef _WIN32 + wchar_t path[PATH_MAX] = L""; + GetTempPathW(PATH_MAX, path); + path.transform("\\", "/"); + return (const char*)utf8_t(path); + #else + return "/tmp/"; + #endif +} + } #endif diff --git a/bsnes/nall/string/replace.hpp b/higan/nall/string/replace.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/nall/string/replace.hpp rename to higan/nall/string/replace.hpp diff --git a/bsnes/nall/string/split.hpp b/higan/nall/string/split.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/nall/string/split.hpp rename to higan/nall/string/split.hpp diff --git a/bsnes/nall/string/static.hpp b/higan/nall/string/static.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/nall/string/static.hpp rename to higan/nall/string/static.hpp diff --git a/bsnes/nall/string/strm.hpp b/higan/nall/string/strm.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/nall/string/strm.hpp rename to higan/nall/string/strm.hpp diff --git a/bsnes/nall/string/strpos.hpp b/higan/nall/string/strpos.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/nall/string/strpos.hpp rename to higan/nall/string/strpos.hpp diff --git a/bsnes/nall/string/trim.hpp b/higan/nall/string/trim.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/nall/string/trim.hpp rename to higan/nall/string/trim.hpp diff --git a/bsnes/nall/string/utf8.hpp b/higan/nall/string/utf8.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/nall/string/utf8.hpp rename to higan/nall/string/utf8.hpp diff --git a/bsnes/nall/string/utility.hpp b/higan/nall/string/utility.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/nall/string/utility.hpp rename to higan/nall/string/utility.hpp diff --git a/bsnes/nall/string/variadic.hpp b/higan/nall/string/variadic.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/nall/string/variadic.hpp rename to higan/nall/string/variadic.hpp diff --git a/bsnes/nall/string/wildcard.hpp b/higan/nall/string/wildcard.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/nall/string/wildcard.hpp rename to higan/nall/string/wildcard.hpp diff --git a/bsnes/nall/string/wrapper.hpp b/higan/nall/string/wrapper.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/nall/string/wrapper.hpp rename to higan/nall/string/wrapper.hpp diff --git a/bsnes/nall/string/xml-legacy.hpp b/higan/nall/string/xml-legacy.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/nall/string/xml-legacy.hpp rename to higan/nall/string/xml-legacy.hpp diff --git a/bsnes/nall/string/xml.hpp b/higan/nall/string/xml.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/nall/string/xml.hpp rename to higan/nall/string/xml.hpp diff --git a/bsnes/nall/traits.hpp b/higan/nall/traits.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/nall/traits.hpp rename to higan/nall/traits.hpp diff --git a/bsnes/nall/udl.hpp b/higan/nall/udl.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/nall/udl.hpp rename to higan/nall/udl.hpp diff --git a/bsnes/nall/zip.hpp b/higan/nall/unzip.hpp old mode 100644 new mode 100755 similarity index 99% rename from bsnes/nall/zip.hpp rename to higan/nall/unzip.hpp index 779b067e..5a7935f6 --- a/bsnes/nall/zip.hpp +++ b/higan/nall/unzip.hpp @@ -8,7 +8,7 @@ namespace nall { -struct zip { +struct unzip { struct File { string name; const uint8_t *data; @@ -102,7 +102,7 @@ struct zip { if(fm.open()) fm.close(); } - ~zip() { + ~unzip() { close(); } diff --git a/bsnes/nall/ups.hpp b/higan/nall/ups.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/nall/ups.hpp rename to higan/nall/ups.hpp diff --git a/bsnes/nall/utility.hpp b/higan/nall/utility.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/nall/utility.hpp rename to higan/nall/utility.hpp diff --git a/bsnes/nall/varint.hpp b/higan/nall/varint.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/nall/varint.hpp rename to higan/nall/varint.hpp diff --git a/bsnes/nall/vector.hpp b/higan/nall/vector.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/nall/vector.hpp rename to higan/nall/vector.hpp diff --git a/bsnes/nall/windows/detour.hpp b/higan/nall/windows/detour.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/nall/windows/detour.hpp rename to higan/nall/windows/detour.hpp diff --git a/bsnes/nall/windows/guid.hpp b/higan/nall/windows/guid.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/nall/windows/guid.hpp rename to higan/nall/windows/guid.hpp diff --git a/bsnes/nall/windows/launcher.hpp b/higan/nall/windows/launcher.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/nall/windows/launcher.hpp rename to higan/nall/windows/launcher.hpp diff --git a/bsnes/nall/windows/registry.hpp b/higan/nall/windows/registry.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/nall/windows/registry.hpp rename to higan/nall/windows/registry.hpp diff --git a/bsnes/nall/windows/utf8.hpp b/higan/nall/windows/utf8.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/nall/windows/utf8.hpp rename to higan/nall/windows/utf8.hpp diff --git a/bsnes/nall/xorg/guard.hpp b/higan/nall/xorg/guard.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/nall/xorg/guard.hpp rename to higan/nall/xorg/guard.hpp diff --git a/bsnes/nall/xorg/xorg.hpp b/higan/nall/xorg/xorg.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/nall/xorg/xorg.hpp rename to higan/nall/xorg/xorg.hpp diff --git a/higan/nall/zip.hpp b/higan/nall/zip.hpp new file mode 100755 index 00000000..0a73ccdd --- /dev/null +++ b/higan/nall/zip.hpp @@ -0,0 +1,95 @@ +#ifndef NALL_ZIP_HPP +#define NALL_ZIP_HPP + +//creates uncompressed ZIP archives + +#include +#include + +namespace nall { + +struct zip { + zip(const string &filename) { + fp.open(filename, file::mode::write); + time_t currentTime = time(0); + tm *info = localtime(¤tTime); + dosTime = (info->tm_hour << 11) | (info->tm_min << 5) | (info->tm_sec >> 1); + dosDate = ((info->tm_year - 80) << 9) | ((1 + info->tm_mon) << 5) + (info->tm_mday); + } + + //append path: append("path/"); + //append file: append("path/file", data, size); + void append(string filename, const uint8_t *data = nullptr, unsigned size = 0u) { + filename.transform("\\", "/"); + uint32_t checksum = crc32_calculate(data, size); + directory.append({filename, checksum, size, fp.offset()}); + + fp.writel(0x04034b50, 4); //signature + fp.writel(0x0014, 2); //minimum version (2.0) + fp.writel(0x0000, 2); //general purpose bit flags + fp.writel(0x0000, 2); //compression method (0 = uncompressed) + fp.writel(dosTime, 2); + fp.writel(dosDate, 2); + fp.writel(checksum, 4); + fp.writel(size, 4); //compressed size + fp.writel(size, 4); //uncompressed size + fp.writel(filename.length(), 2); //file name length + fp.writel(0x0000, 2); //extra field length + fp.print(filename); //file name + + fp.write(data, size); //file data + } + + ~zip() { + //central directory + unsigned baseOffset = fp.offset(); + for(auto &entry : directory) { + fp.writel(0x02014b50, 4); //signature + fp.writel(0x0014, 2); //version made by (2.0) + fp.writel(0x0014, 2); //version needed to extract (2.0) + fp.writel(0x0000, 2); //general purpose bit flags + fp.writel(0x0000, 2); //compression method (0 = uncompressed) + fp.writel(dosTime, 2); + fp.writel(dosDate, 2); + fp.writel(entry.checksum, 4); + fp.writel(entry.size, 4); //compressed size + fp.writel(entry.size, 4); //uncompressed size + fp.writel(entry.filename.length(), 2); //file name length + fp.writel(0x0000, 2); //extra field length + fp.writel(0x0000, 2); //file comment length + fp.writel(0x0000, 2); //disk number start + fp.writel(0x0000, 2); //internal file attributes + fp.writel(0x00000000, 4); //external file attributes + fp.writel(entry.offset, 4); //relative offset of file header + fp.print(entry.filename); + } + unsigned finishOffset = fp.offset(); + + //end of central directory + fp.writel(0x06054b50, 4); //signature + fp.writel(0x0000, 2); //number of this disk + fp.writel(0x0000, 2); //disk where central directory starts + fp.writel(directory.size(), 2); //number of central directory records on this disk + fp.writel(directory.size(), 2); //total number of central directory records + fp.writel(finishOffset - baseOffset, 4); //size of central directory + fp.writel(baseOffset, 4); //offset of central directory + fp.writel(0x0000, 2); //comment length + + fp.close(); + } + +protected: + file fp; + uint16_t dosTime, dosDate; + struct entry_t { + string filename; + uint32_t checksum; + uint32_t size; + uint32_t offset; + }; + vector directory; +}; + +} + +#endif diff --git a/higan/obj/.gitignore b/higan/obj/.gitignore new file mode 100644 index 00000000..5761abcf --- /dev/null +++ b/higan/obj/.gitignore @@ -0,0 +1 @@ +*.o diff --git a/higan/out/.gitignore b/higan/out/.gitignore new file mode 100644 index 00000000..98f54497 --- /dev/null +++ b/higan/out/.gitignore @@ -0,0 +1 @@ +higan diff --git a/bsnes/phoenix/Makefile b/higan/phoenix/Makefile old mode 100644 new mode 100755 similarity index 100% rename from bsnes/phoenix/Makefile rename to higan/phoenix/Makefile diff --git a/bsnes/phoenix/core/core.cpp b/higan/phoenix/core/core.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/phoenix/core/core.cpp rename to higan/phoenix/core/core.cpp diff --git a/bsnes/phoenix/core/core.hpp b/higan/phoenix/core/core.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/phoenix/core/core.hpp rename to higan/phoenix/core/core.hpp diff --git a/bsnes/phoenix/core/keyboard.hpp b/higan/phoenix/core/keyboard.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/phoenix/core/keyboard.hpp rename to higan/phoenix/core/keyboard.hpp diff --git a/bsnes/phoenix/core/layout/fixed-layout.cpp b/higan/phoenix/core/layout/fixed-layout.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/phoenix/core/layout/fixed-layout.cpp rename to higan/phoenix/core/layout/fixed-layout.cpp diff --git a/bsnes/phoenix/core/layout/fixed-layout.hpp b/higan/phoenix/core/layout/fixed-layout.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/phoenix/core/layout/fixed-layout.hpp rename to higan/phoenix/core/layout/fixed-layout.hpp diff --git a/bsnes/phoenix/core/layout/horizontal-layout.cpp b/higan/phoenix/core/layout/horizontal-layout.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/phoenix/core/layout/horizontal-layout.cpp rename to higan/phoenix/core/layout/horizontal-layout.cpp diff --git a/bsnes/phoenix/core/layout/horizontal-layout.hpp b/higan/phoenix/core/layout/horizontal-layout.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/phoenix/core/layout/horizontal-layout.hpp rename to higan/phoenix/core/layout/horizontal-layout.hpp diff --git a/bsnes/phoenix/core/layout/vertical-layout.cpp b/higan/phoenix/core/layout/vertical-layout.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/phoenix/core/layout/vertical-layout.cpp rename to higan/phoenix/core/layout/vertical-layout.cpp diff --git a/bsnes/phoenix/core/layout/vertical-layout.hpp b/higan/phoenix/core/layout/vertical-layout.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/phoenix/core/layout/vertical-layout.hpp rename to higan/phoenix/core/layout/vertical-layout.hpp diff --git a/bsnes/phoenix/core/state.hpp b/higan/phoenix/core/state.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/phoenix/core/state.hpp rename to higan/phoenix/core/state.hpp diff --git a/bsnes/phoenix/gtk/action/action.cpp b/higan/phoenix/gtk/action/action.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/phoenix/gtk/action/action.cpp rename to higan/phoenix/gtk/action/action.cpp diff --git a/bsnes/phoenix/gtk/action/check-item.cpp b/higan/phoenix/gtk/action/check-item.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/phoenix/gtk/action/check-item.cpp rename to higan/phoenix/gtk/action/check-item.cpp diff --git a/bsnes/phoenix/gtk/action/item.cpp b/higan/phoenix/gtk/action/item.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/phoenix/gtk/action/item.cpp rename to higan/phoenix/gtk/action/item.cpp diff --git a/bsnes/phoenix/gtk/action/menu.cpp b/higan/phoenix/gtk/action/menu.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/phoenix/gtk/action/menu.cpp rename to higan/phoenix/gtk/action/menu.cpp diff --git a/bsnes/phoenix/gtk/action/radio-item.cpp b/higan/phoenix/gtk/action/radio-item.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/phoenix/gtk/action/radio-item.cpp rename to higan/phoenix/gtk/action/radio-item.cpp diff --git a/bsnes/phoenix/gtk/action/separator.cpp b/higan/phoenix/gtk/action/separator.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/phoenix/gtk/action/separator.cpp rename to higan/phoenix/gtk/action/separator.cpp diff --git a/bsnes/phoenix/gtk/desktop.cpp b/higan/phoenix/gtk/desktop.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/phoenix/gtk/desktop.cpp rename to higan/phoenix/gtk/desktop.cpp diff --git a/bsnes/phoenix/gtk/dialog-window.cpp b/higan/phoenix/gtk/dialog-window.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/phoenix/gtk/dialog-window.cpp rename to higan/phoenix/gtk/dialog-window.cpp diff --git a/bsnes/phoenix/gtk/font.cpp b/higan/phoenix/gtk/font.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/phoenix/gtk/font.cpp rename to higan/phoenix/gtk/font.cpp diff --git a/bsnes/phoenix/gtk/keyboard.cpp b/higan/phoenix/gtk/keyboard.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/phoenix/gtk/keyboard.cpp rename to higan/phoenix/gtk/keyboard.cpp diff --git a/bsnes/phoenix/gtk/message-window.cpp b/higan/phoenix/gtk/message-window.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/phoenix/gtk/message-window.cpp rename to higan/phoenix/gtk/message-window.cpp diff --git a/bsnes/phoenix/gtk/mouse.cpp b/higan/phoenix/gtk/mouse.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/phoenix/gtk/mouse.cpp rename to higan/phoenix/gtk/mouse.cpp diff --git a/bsnes/phoenix/gtk/platform.cpp b/higan/phoenix/gtk/platform.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/phoenix/gtk/platform.cpp rename to higan/phoenix/gtk/platform.cpp diff --git a/bsnes/phoenix/gtk/platform.hpp b/higan/phoenix/gtk/platform.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/phoenix/gtk/platform.hpp rename to higan/phoenix/gtk/platform.hpp diff --git a/bsnes/phoenix/gtk/settings.cpp b/higan/phoenix/gtk/settings.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/phoenix/gtk/settings.cpp rename to higan/phoenix/gtk/settings.cpp diff --git a/bsnes/phoenix/gtk/timer.cpp b/higan/phoenix/gtk/timer.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/phoenix/gtk/timer.cpp rename to higan/phoenix/gtk/timer.cpp diff --git a/bsnes/phoenix/gtk/utility.cpp b/higan/phoenix/gtk/utility.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/phoenix/gtk/utility.cpp rename to higan/phoenix/gtk/utility.cpp diff --git a/bsnes/phoenix/gtk/widget/button.cpp b/higan/phoenix/gtk/widget/button.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/phoenix/gtk/widget/button.cpp rename to higan/phoenix/gtk/widget/button.cpp diff --git a/bsnes/phoenix/gtk/widget/canvas.cpp b/higan/phoenix/gtk/widget/canvas.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/phoenix/gtk/widget/canvas.cpp rename to higan/phoenix/gtk/widget/canvas.cpp diff --git a/bsnes/phoenix/gtk/widget/check-box.cpp b/higan/phoenix/gtk/widget/check-box.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/phoenix/gtk/widget/check-box.cpp rename to higan/phoenix/gtk/widget/check-box.cpp diff --git a/bsnes/phoenix/gtk/widget/combo-box.cpp b/higan/phoenix/gtk/widget/combo-box.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/phoenix/gtk/widget/combo-box.cpp rename to higan/phoenix/gtk/widget/combo-box.cpp diff --git a/bsnes/phoenix/gtk/widget/hex-edit.cpp b/higan/phoenix/gtk/widget/hex-edit.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/phoenix/gtk/widget/hex-edit.cpp rename to higan/phoenix/gtk/widget/hex-edit.cpp diff --git a/bsnes/phoenix/gtk/widget/horizontal-scroll-bar.cpp b/higan/phoenix/gtk/widget/horizontal-scroll-bar.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/phoenix/gtk/widget/horizontal-scroll-bar.cpp rename to higan/phoenix/gtk/widget/horizontal-scroll-bar.cpp diff --git a/bsnes/phoenix/gtk/widget/horizontal-slider.cpp b/higan/phoenix/gtk/widget/horizontal-slider.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/phoenix/gtk/widget/horizontal-slider.cpp rename to higan/phoenix/gtk/widget/horizontal-slider.cpp diff --git a/bsnes/phoenix/gtk/widget/label.cpp b/higan/phoenix/gtk/widget/label.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/phoenix/gtk/widget/label.cpp rename to higan/phoenix/gtk/widget/label.cpp diff --git a/bsnes/phoenix/gtk/widget/line-edit.cpp b/higan/phoenix/gtk/widget/line-edit.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/phoenix/gtk/widget/line-edit.cpp rename to higan/phoenix/gtk/widget/line-edit.cpp diff --git a/bsnes/phoenix/gtk/widget/list-view.cpp b/higan/phoenix/gtk/widget/list-view.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/phoenix/gtk/widget/list-view.cpp rename to higan/phoenix/gtk/widget/list-view.cpp diff --git a/bsnes/phoenix/gtk/widget/progress-bar.cpp b/higan/phoenix/gtk/widget/progress-bar.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/phoenix/gtk/widget/progress-bar.cpp rename to higan/phoenix/gtk/widget/progress-bar.cpp diff --git a/bsnes/phoenix/gtk/widget/radio-box.cpp b/higan/phoenix/gtk/widget/radio-box.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/phoenix/gtk/widget/radio-box.cpp rename to higan/phoenix/gtk/widget/radio-box.cpp diff --git a/bsnes/phoenix/gtk/widget/text-edit.cpp b/higan/phoenix/gtk/widget/text-edit.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/phoenix/gtk/widget/text-edit.cpp rename to higan/phoenix/gtk/widget/text-edit.cpp diff --git a/bsnes/phoenix/gtk/widget/vertical-scroll-bar.cpp b/higan/phoenix/gtk/widget/vertical-scroll-bar.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/phoenix/gtk/widget/vertical-scroll-bar.cpp rename to higan/phoenix/gtk/widget/vertical-scroll-bar.cpp diff --git a/bsnes/phoenix/gtk/widget/vertical-slider.cpp b/higan/phoenix/gtk/widget/vertical-slider.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/phoenix/gtk/widget/vertical-slider.cpp rename to higan/phoenix/gtk/widget/vertical-slider.cpp diff --git a/bsnes/phoenix/gtk/widget/viewport.cpp b/higan/phoenix/gtk/widget/viewport.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/phoenix/gtk/widget/viewport.cpp rename to higan/phoenix/gtk/widget/viewport.cpp diff --git a/bsnes/phoenix/gtk/widget/widget.cpp b/higan/phoenix/gtk/widget/widget.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/phoenix/gtk/widget/widget.cpp rename to higan/phoenix/gtk/widget/widget.cpp diff --git a/bsnes/phoenix/gtk/window.cpp b/higan/phoenix/gtk/window.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/phoenix/gtk/window.cpp rename to higan/phoenix/gtk/window.cpp diff --git a/bsnes/phoenix/phoenix.cpp b/higan/phoenix/phoenix.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/phoenix/phoenix.cpp rename to higan/phoenix/phoenix.cpp diff --git a/bsnes/phoenix/phoenix.hpp b/higan/phoenix/phoenix.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/phoenix/phoenix.hpp rename to higan/phoenix/phoenix.hpp diff --git a/bsnes/phoenix/qt/action/action.cpp b/higan/phoenix/qt/action/action.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/phoenix/qt/action/action.cpp rename to higan/phoenix/qt/action/action.cpp diff --git a/bsnes/phoenix/qt/action/check-item.cpp b/higan/phoenix/qt/action/check-item.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/phoenix/qt/action/check-item.cpp rename to higan/phoenix/qt/action/check-item.cpp diff --git a/bsnes/phoenix/qt/action/item.cpp b/higan/phoenix/qt/action/item.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/phoenix/qt/action/item.cpp rename to higan/phoenix/qt/action/item.cpp diff --git a/bsnes/phoenix/qt/action/menu.cpp b/higan/phoenix/qt/action/menu.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/phoenix/qt/action/menu.cpp rename to higan/phoenix/qt/action/menu.cpp diff --git a/bsnes/phoenix/qt/action/radio-item.cpp b/higan/phoenix/qt/action/radio-item.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/phoenix/qt/action/radio-item.cpp rename to higan/phoenix/qt/action/radio-item.cpp diff --git a/bsnes/phoenix/qt/action/separator.cpp b/higan/phoenix/qt/action/separator.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/phoenix/qt/action/separator.cpp rename to higan/phoenix/qt/action/separator.cpp diff --git a/bsnes/phoenix/qt/desktop.cpp b/higan/phoenix/qt/desktop.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/phoenix/qt/desktop.cpp rename to higan/phoenix/qt/desktop.cpp diff --git a/bsnes/phoenix/qt/dialog-window.cpp b/higan/phoenix/qt/dialog-window.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/phoenix/qt/dialog-window.cpp rename to higan/phoenix/qt/dialog-window.cpp diff --git a/bsnes/phoenix/qt/font.cpp b/higan/phoenix/qt/font.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/phoenix/qt/font.cpp rename to higan/phoenix/qt/font.cpp diff --git a/bsnes/phoenix/qt/keyboard.cpp b/higan/phoenix/qt/keyboard.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/phoenix/qt/keyboard.cpp rename to higan/phoenix/qt/keyboard.cpp diff --git a/bsnes/phoenix/qt/message-window.cpp b/higan/phoenix/qt/message-window.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/phoenix/qt/message-window.cpp rename to higan/phoenix/qt/message-window.cpp diff --git a/bsnes/phoenix/qt/mouse.cpp b/higan/phoenix/qt/mouse.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/phoenix/qt/mouse.cpp rename to higan/phoenix/qt/mouse.cpp diff --git a/bsnes/phoenix/qt/platform.cpp b/higan/phoenix/qt/platform.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/phoenix/qt/platform.cpp rename to higan/phoenix/qt/platform.cpp diff --git a/bsnes/phoenix/qt/platform.moc b/higan/phoenix/qt/platform.moc old mode 100644 new mode 100755 similarity index 100% rename from bsnes/phoenix/qt/platform.moc rename to higan/phoenix/qt/platform.moc diff --git a/bsnes/phoenix/qt/platform.moc.hpp b/higan/phoenix/qt/platform.moc.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/phoenix/qt/platform.moc.hpp rename to higan/phoenix/qt/platform.moc.hpp diff --git a/bsnes/phoenix/qt/settings.cpp b/higan/phoenix/qt/settings.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/phoenix/qt/settings.cpp rename to higan/phoenix/qt/settings.cpp diff --git a/bsnes/phoenix/qt/timer.cpp b/higan/phoenix/qt/timer.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/phoenix/qt/timer.cpp rename to higan/phoenix/qt/timer.cpp diff --git a/bsnes/phoenix/qt/utility.cpp b/higan/phoenix/qt/utility.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/phoenix/qt/utility.cpp rename to higan/phoenix/qt/utility.cpp diff --git a/bsnes/phoenix/qt/widget/button.cpp b/higan/phoenix/qt/widget/button.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/phoenix/qt/widget/button.cpp rename to higan/phoenix/qt/widget/button.cpp diff --git a/bsnes/phoenix/qt/widget/canvas.cpp b/higan/phoenix/qt/widget/canvas.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/phoenix/qt/widget/canvas.cpp rename to higan/phoenix/qt/widget/canvas.cpp diff --git a/bsnes/phoenix/qt/widget/check-box.cpp b/higan/phoenix/qt/widget/check-box.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/phoenix/qt/widget/check-box.cpp rename to higan/phoenix/qt/widget/check-box.cpp diff --git a/bsnes/phoenix/qt/widget/combo-box.cpp b/higan/phoenix/qt/widget/combo-box.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/phoenix/qt/widget/combo-box.cpp rename to higan/phoenix/qt/widget/combo-box.cpp diff --git a/bsnes/phoenix/qt/widget/hex-edit.cpp b/higan/phoenix/qt/widget/hex-edit.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/phoenix/qt/widget/hex-edit.cpp rename to higan/phoenix/qt/widget/hex-edit.cpp diff --git a/bsnes/phoenix/qt/widget/horizontal-scroll-bar.cpp b/higan/phoenix/qt/widget/horizontal-scroll-bar.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/phoenix/qt/widget/horizontal-scroll-bar.cpp rename to higan/phoenix/qt/widget/horizontal-scroll-bar.cpp diff --git a/bsnes/phoenix/qt/widget/horizontal-slider.cpp b/higan/phoenix/qt/widget/horizontal-slider.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/phoenix/qt/widget/horizontal-slider.cpp rename to higan/phoenix/qt/widget/horizontal-slider.cpp diff --git a/bsnes/phoenix/qt/widget/label.cpp b/higan/phoenix/qt/widget/label.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/phoenix/qt/widget/label.cpp rename to higan/phoenix/qt/widget/label.cpp diff --git a/bsnes/phoenix/qt/widget/line-edit.cpp b/higan/phoenix/qt/widget/line-edit.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/phoenix/qt/widget/line-edit.cpp rename to higan/phoenix/qt/widget/line-edit.cpp diff --git a/bsnes/phoenix/qt/widget/list-view.cpp b/higan/phoenix/qt/widget/list-view.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/phoenix/qt/widget/list-view.cpp rename to higan/phoenix/qt/widget/list-view.cpp diff --git a/bsnes/phoenix/qt/widget/progress-bar.cpp b/higan/phoenix/qt/widget/progress-bar.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/phoenix/qt/widget/progress-bar.cpp rename to higan/phoenix/qt/widget/progress-bar.cpp diff --git a/bsnes/phoenix/qt/widget/radio-box.cpp b/higan/phoenix/qt/widget/radio-box.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/phoenix/qt/widget/radio-box.cpp rename to higan/phoenix/qt/widget/radio-box.cpp diff --git a/bsnes/phoenix/qt/widget/text-edit.cpp b/higan/phoenix/qt/widget/text-edit.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/phoenix/qt/widget/text-edit.cpp rename to higan/phoenix/qt/widget/text-edit.cpp diff --git a/bsnes/phoenix/qt/widget/vertical-scroll-bar.cpp b/higan/phoenix/qt/widget/vertical-scroll-bar.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/phoenix/qt/widget/vertical-scroll-bar.cpp rename to higan/phoenix/qt/widget/vertical-scroll-bar.cpp diff --git a/bsnes/phoenix/qt/widget/vertical-slider.cpp b/higan/phoenix/qt/widget/vertical-slider.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/phoenix/qt/widget/vertical-slider.cpp rename to higan/phoenix/qt/widget/vertical-slider.cpp diff --git a/bsnes/phoenix/qt/widget/viewport.cpp b/higan/phoenix/qt/widget/viewport.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/phoenix/qt/widget/viewport.cpp rename to higan/phoenix/qt/widget/viewport.cpp diff --git a/bsnes/phoenix/qt/widget/widget.cpp b/higan/phoenix/qt/widget/widget.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/phoenix/qt/widget/widget.cpp rename to higan/phoenix/qt/widget/widget.cpp diff --git a/bsnes/phoenix/qt/window.cpp b/higan/phoenix/qt/window.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/phoenix/qt/window.cpp rename to higan/phoenix/qt/window.cpp diff --git a/bsnes/phoenix/reference/action/action.cpp b/higan/phoenix/reference/action/action.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/phoenix/reference/action/action.cpp rename to higan/phoenix/reference/action/action.cpp diff --git a/bsnes/phoenix/reference/action/check-item.cpp b/higan/phoenix/reference/action/check-item.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/phoenix/reference/action/check-item.cpp rename to higan/phoenix/reference/action/check-item.cpp diff --git a/bsnes/phoenix/reference/action/item.cpp b/higan/phoenix/reference/action/item.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/phoenix/reference/action/item.cpp rename to higan/phoenix/reference/action/item.cpp diff --git a/bsnes/phoenix/reference/action/menu.cpp b/higan/phoenix/reference/action/menu.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/phoenix/reference/action/menu.cpp rename to higan/phoenix/reference/action/menu.cpp diff --git a/bsnes/phoenix/reference/action/radio-item.cpp b/higan/phoenix/reference/action/radio-item.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/phoenix/reference/action/radio-item.cpp rename to higan/phoenix/reference/action/radio-item.cpp diff --git a/bsnes/phoenix/reference/action/separator.cpp b/higan/phoenix/reference/action/separator.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/phoenix/reference/action/separator.cpp rename to higan/phoenix/reference/action/separator.cpp diff --git a/bsnes/phoenix/reference/desktop.cpp b/higan/phoenix/reference/desktop.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/phoenix/reference/desktop.cpp rename to higan/phoenix/reference/desktop.cpp diff --git a/bsnes/phoenix/reference/dialog-window.cpp b/higan/phoenix/reference/dialog-window.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/phoenix/reference/dialog-window.cpp rename to higan/phoenix/reference/dialog-window.cpp diff --git a/bsnes/phoenix/reference/font.cpp b/higan/phoenix/reference/font.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/phoenix/reference/font.cpp rename to higan/phoenix/reference/font.cpp diff --git a/bsnes/phoenix/reference/keyboard.cpp b/higan/phoenix/reference/keyboard.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/phoenix/reference/keyboard.cpp rename to higan/phoenix/reference/keyboard.cpp diff --git a/bsnes/phoenix/reference/message-window.cpp b/higan/phoenix/reference/message-window.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/phoenix/reference/message-window.cpp rename to higan/phoenix/reference/message-window.cpp diff --git a/bsnes/phoenix/reference/mouse.cpp b/higan/phoenix/reference/mouse.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/phoenix/reference/mouse.cpp rename to higan/phoenix/reference/mouse.cpp diff --git a/bsnes/phoenix/reference/platform.cpp b/higan/phoenix/reference/platform.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/phoenix/reference/platform.cpp rename to higan/phoenix/reference/platform.cpp diff --git a/bsnes/phoenix/reference/platform.hpp b/higan/phoenix/reference/platform.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/phoenix/reference/platform.hpp rename to higan/phoenix/reference/platform.hpp diff --git a/bsnes/phoenix/reference/timer.cpp b/higan/phoenix/reference/timer.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/phoenix/reference/timer.cpp rename to higan/phoenix/reference/timer.cpp diff --git a/bsnes/phoenix/reference/widget/button.cpp b/higan/phoenix/reference/widget/button.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/phoenix/reference/widget/button.cpp rename to higan/phoenix/reference/widget/button.cpp diff --git a/bsnes/phoenix/reference/widget/canvas.cpp b/higan/phoenix/reference/widget/canvas.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/phoenix/reference/widget/canvas.cpp rename to higan/phoenix/reference/widget/canvas.cpp diff --git a/bsnes/phoenix/reference/widget/check-box.cpp b/higan/phoenix/reference/widget/check-box.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/phoenix/reference/widget/check-box.cpp rename to higan/phoenix/reference/widget/check-box.cpp diff --git a/bsnes/phoenix/reference/widget/combo-box.cpp b/higan/phoenix/reference/widget/combo-box.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/phoenix/reference/widget/combo-box.cpp rename to higan/phoenix/reference/widget/combo-box.cpp diff --git a/bsnes/phoenix/reference/widget/hex-edit.cpp b/higan/phoenix/reference/widget/hex-edit.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/phoenix/reference/widget/hex-edit.cpp rename to higan/phoenix/reference/widget/hex-edit.cpp diff --git a/bsnes/phoenix/reference/widget/horizontal-scroll-bar.cpp b/higan/phoenix/reference/widget/horizontal-scroll-bar.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/phoenix/reference/widget/horizontal-scroll-bar.cpp rename to higan/phoenix/reference/widget/horizontal-scroll-bar.cpp diff --git a/bsnes/phoenix/reference/widget/horizontal-slider.cpp b/higan/phoenix/reference/widget/horizontal-slider.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/phoenix/reference/widget/horizontal-slider.cpp rename to higan/phoenix/reference/widget/horizontal-slider.cpp diff --git a/bsnes/phoenix/reference/widget/label.cpp b/higan/phoenix/reference/widget/label.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/phoenix/reference/widget/label.cpp rename to higan/phoenix/reference/widget/label.cpp diff --git a/bsnes/phoenix/reference/widget/line-edit.cpp b/higan/phoenix/reference/widget/line-edit.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/phoenix/reference/widget/line-edit.cpp rename to higan/phoenix/reference/widget/line-edit.cpp diff --git a/bsnes/phoenix/reference/widget/list-view.cpp b/higan/phoenix/reference/widget/list-view.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/phoenix/reference/widget/list-view.cpp rename to higan/phoenix/reference/widget/list-view.cpp diff --git a/bsnes/phoenix/reference/widget/progress-bar.cpp b/higan/phoenix/reference/widget/progress-bar.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/phoenix/reference/widget/progress-bar.cpp rename to higan/phoenix/reference/widget/progress-bar.cpp diff --git a/bsnes/phoenix/reference/widget/radio-box.cpp b/higan/phoenix/reference/widget/radio-box.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/phoenix/reference/widget/radio-box.cpp rename to higan/phoenix/reference/widget/radio-box.cpp diff --git a/bsnes/phoenix/reference/widget/text-edit.cpp b/higan/phoenix/reference/widget/text-edit.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/phoenix/reference/widget/text-edit.cpp rename to higan/phoenix/reference/widget/text-edit.cpp diff --git a/bsnes/phoenix/reference/widget/vertical-scroll-bar.cpp b/higan/phoenix/reference/widget/vertical-scroll-bar.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/phoenix/reference/widget/vertical-scroll-bar.cpp rename to higan/phoenix/reference/widget/vertical-scroll-bar.cpp diff --git a/bsnes/phoenix/reference/widget/vertical-slider.cpp b/higan/phoenix/reference/widget/vertical-slider.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/phoenix/reference/widget/vertical-slider.cpp rename to higan/phoenix/reference/widget/vertical-slider.cpp diff --git a/bsnes/phoenix/reference/widget/viewport.cpp b/higan/phoenix/reference/widget/viewport.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/phoenix/reference/widget/viewport.cpp rename to higan/phoenix/reference/widget/viewport.cpp diff --git a/bsnes/phoenix/reference/widget/widget.cpp b/higan/phoenix/reference/widget/widget.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/phoenix/reference/widget/widget.cpp rename to higan/phoenix/reference/widget/widget.cpp diff --git a/bsnes/phoenix/reference/window.cpp b/higan/phoenix/reference/window.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/phoenix/reference/window.cpp rename to higan/phoenix/reference/window.cpp diff --git a/bsnes/phoenix/sync.sh b/higan/phoenix/sync.sh old mode 100644 new mode 100755 similarity index 100% rename from bsnes/phoenix/sync.sh rename to higan/phoenix/sync.sh diff --git a/bsnes/phoenix/windows/action/action.cpp b/higan/phoenix/windows/action/action.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/phoenix/windows/action/action.cpp rename to higan/phoenix/windows/action/action.cpp diff --git a/bsnes/phoenix/windows/action/check-item.cpp b/higan/phoenix/windows/action/check-item.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/phoenix/windows/action/check-item.cpp rename to higan/phoenix/windows/action/check-item.cpp diff --git a/bsnes/phoenix/windows/action/item.cpp b/higan/phoenix/windows/action/item.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/phoenix/windows/action/item.cpp rename to higan/phoenix/windows/action/item.cpp diff --git a/bsnes/phoenix/windows/action/menu.cpp b/higan/phoenix/windows/action/menu.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/phoenix/windows/action/menu.cpp rename to higan/phoenix/windows/action/menu.cpp diff --git a/bsnes/phoenix/windows/action/radio-item.cpp b/higan/phoenix/windows/action/radio-item.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/phoenix/windows/action/radio-item.cpp rename to higan/phoenix/windows/action/radio-item.cpp diff --git a/bsnes/phoenix/windows/action/separator.cpp b/higan/phoenix/windows/action/separator.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/phoenix/windows/action/separator.cpp rename to higan/phoenix/windows/action/separator.cpp diff --git a/bsnes/phoenix/windows/desktop.cpp b/higan/phoenix/windows/desktop.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/phoenix/windows/desktop.cpp rename to higan/phoenix/windows/desktop.cpp diff --git a/bsnes/phoenix/windows/dialog-window.cpp b/higan/phoenix/windows/dialog-window.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/phoenix/windows/dialog-window.cpp rename to higan/phoenix/windows/dialog-window.cpp diff --git a/bsnes/phoenix/windows/font.cpp b/higan/phoenix/windows/font.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/phoenix/windows/font.cpp rename to higan/phoenix/windows/font.cpp diff --git a/bsnes/phoenix/windows/keyboard.cpp b/higan/phoenix/windows/keyboard.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/phoenix/windows/keyboard.cpp rename to higan/phoenix/windows/keyboard.cpp diff --git a/bsnes/phoenix/windows/message-window.cpp b/higan/phoenix/windows/message-window.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/phoenix/windows/message-window.cpp rename to higan/phoenix/windows/message-window.cpp diff --git a/bsnes/phoenix/windows/mouse.cpp b/higan/phoenix/windows/mouse.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/phoenix/windows/mouse.cpp rename to higan/phoenix/windows/mouse.cpp diff --git a/bsnes/phoenix/windows/object.cpp b/higan/phoenix/windows/object.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/phoenix/windows/object.cpp rename to higan/phoenix/windows/object.cpp diff --git a/bsnes/phoenix/windows/phoenix.Manifest b/higan/phoenix/windows/phoenix.Manifest old mode 100644 new mode 100755 similarity index 100% rename from bsnes/phoenix/windows/phoenix.Manifest rename to higan/phoenix/windows/phoenix.Manifest diff --git a/bsnes/phoenix/windows/phoenix.rc b/higan/phoenix/windows/phoenix.rc old mode 100644 new mode 100755 similarity index 100% rename from bsnes/phoenix/windows/phoenix.rc rename to higan/phoenix/windows/phoenix.rc diff --git a/bsnes/phoenix/windows/platform.cpp b/higan/phoenix/windows/platform.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/phoenix/windows/platform.cpp rename to higan/phoenix/windows/platform.cpp diff --git a/bsnes/phoenix/windows/platform.hpp b/higan/phoenix/windows/platform.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/phoenix/windows/platform.hpp rename to higan/phoenix/windows/platform.hpp diff --git a/bsnes/phoenix/windows/settings.cpp b/higan/phoenix/windows/settings.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/phoenix/windows/settings.cpp rename to higan/phoenix/windows/settings.cpp diff --git a/bsnes/phoenix/windows/timer.cpp b/higan/phoenix/windows/timer.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/phoenix/windows/timer.cpp rename to higan/phoenix/windows/timer.cpp diff --git a/bsnes/phoenix/windows/utility.cpp b/higan/phoenix/windows/utility.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/phoenix/windows/utility.cpp rename to higan/phoenix/windows/utility.cpp diff --git a/bsnes/phoenix/windows/widget/button.cpp b/higan/phoenix/windows/widget/button.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/phoenix/windows/widget/button.cpp rename to higan/phoenix/windows/widget/button.cpp diff --git a/bsnes/phoenix/windows/widget/canvas.cpp b/higan/phoenix/windows/widget/canvas.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/phoenix/windows/widget/canvas.cpp rename to higan/phoenix/windows/widget/canvas.cpp diff --git a/bsnes/phoenix/windows/widget/check-box.cpp b/higan/phoenix/windows/widget/check-box.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/phoenix/windows/widget/check-box.cpp rename to higan/phoenix/windows/widget/check-box.cpp diff --git a/bsnes/phoenix/windows/widget/combo-box.cpp b/higan/phoenix/windows/widget/combo-box.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/phoenix/windows/widget/combo-box.cpp rename to higan/phoenix/windows/widget/combo-box.cpp diff --git a/bsnes/phoenix/windows/widget/hex-edit.cpp b/higan/phoenix/windows/widget/hex-edit.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/phoenix/windows/widget/hex-edit.cpp rename to higan/phoenix/windows/widget/hex-edit.cpp diff --git a/bsnes/phoenix/windows/widget/horizontal-scroll-bar.cpp b/higan/phoenix/windows/widget/horizontal-scroll-bar.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/phoenix/windows/widget/horizontal-scroll-bar.cpp rename to higan/phoenix/windows/widget/horizontal-scroll-bar.cpp diff --git a/bsnes/phoenix/windows/widget/horizontal-slider.cpp b/higan/phoenix/windows/widget/horizontal-slider.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/phoenix/windows/widget/horizontal-slider.cpp rename to higan/phoenix/windows/widget/horizontal-slider.cpp diff --git a/bsnes/phoenix/windows/widget/label.cpp b/higan/phoenix/windows/widget/label.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/phoenix/windows/widget/label.cpp rename to higan/phoenix/windows/widget/label.cpp diff --git a/bsnes/phoenix/windows/widget/line-edit.cpp b/higan/phoenix/windows/widget/line-edit.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/phoenix/windows/widget/line-edit.cpp rename to higan/phoenix/windows/widget/line-edit.cpp diff --git a/bsnes/phoenix/windows/widget/list-view.cpp b/higan/phoenix/windows/widget/list-view.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/phoenix/windows/widget/list-view.cpp rename to higan/phoenix/windows/widget/list-view.cpp diff --git a/bsnes/phoenix/windows/widget/progress-bar.cpp b/higan/phoenix/windows/widget/progress-bar.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/phoenix/windows/widget/progress-bar.cpp rename to higan/phoenix/windows/widget/progress-bar.cpp diff --git a/bsnes/phoenix/windows/widget/radio-box.cpp b/higan/phoenix/windows/widget/radio-box.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/phoenix/windows/widget/radio-box.cpp rename to higan/phoenix/windows/widget/radio-box.cpp diff --git a/bsnes/phoenix/windows/widget/text-edit.cpp b/higan/phoenix/windows/widget/text-edit.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/phoenix/windows/widget/text-edit.cpp rename to higan/phoenix/windows/widget/text-edit.cpp diff --git a/bsnes/phoenix/windows/widget/vertical-scroll-bar.cpp b/higan/phoenix/windows/widget/vertical-scroll-bar.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/phoenix/windows/widget/vertical-scroll-bar.cpp rename to higan/phoenix/windows/widget/vertical-scroll-bar.cpp diff --git a/bsnes/phoenix/windows/widget/vertical-slider.cpp b/higan/phoenix/windows/widget/vertical-slider.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/phoenix/windows/widget/vertical-slider.cpp rename to higan/phoenix/windows/widget/vertical-slider.cpp diff --git a/bsnes/phoenix/windows/widget/viewport.cpp b/higan/phoenix/windows/widget/viewport.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/phoenix/windows/widget/viewport.cpp rename to higan/phoenix/windows/widget/viewport.cpp diff --git a/bsnes/phoenix/windows/widget/widget.cpp b/higan/phoenix/windows/widget/widget.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/phoenix/windows/widget/widget.cpp rename to higan/phoenix/windows/widget/widget.cpp diff --git a/bsnes/phoenix/windows/window.cpp b/higan/phoenix/windows/window.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/phoenix/windows/window.cpp rename to higan/phoenix/windows/window.cpp diff --git a/bsnes/processor/Makefile b/higan/processor/Makefile old mode 100644 new mode 100755 similarity index 100% rename from bsnes/processor/Makefile rename to higan/processor/Makefile diff --git a/bsnes/processor/arm/algorithms.cpp b/higan/processor/arm/algorithms.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/processor/arm/algorithms.cpp rename to higan/processor/arm/algorithms.cpp diff --git a/bsnes/processor/arm/arm.cpp b/higan/processor/arm/arm.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/processor/arm/arm.cpp rename to higan/processor/arm/arm.cpp diff --git a/bsnes/processor/arm/arm.hpp b/higan/processor/arm/arm.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/processor/arm/arm.hpp rename to higan/processor/arm/arm.hpp diff --git a/bsnes/processor/arm/disassembler.cpp b/higan/processor/arm/disassembler.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/processor/arm/disassembler.cpp rename to higan/processor/arm/disassembler.cpp diff --git a/bsnes/processor/arm/disassembler.hpp b/higan/processor/arm/disassembler.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/processor/arm/disassembler.hpp rename to higan/processor/arm/disassembler.hpp diff --git a/bsnes/processor/arm/instructions-arm.cpp b/higan/processor/arm/instructions-arm.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/processor/arm/instructions-arm.cpp rename to higan/processor/arm/instructions-arm.cpp diff --git a/bsnes/processor/arm/instructions-arm.hpp b/higan/processor/arm/instructions-arm.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/processor/arm/instructions-arm.hpp rename to higan/processor/arm/instructions-arm.hpp diff --git a/bsnes/processor/arm/instructions-thumb.cpp b/higan/processor/arm/instructions-thumb.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/processor/arm/instructions-thumb.cpp rename to higan/processor/arm/instructions-thumb.cpp diff --git a/bsnes/processor/arm/instructions-thumb.hpp b/higan/processor/arm/instructions-thumb.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/processor/arm/instructions-thumb.hpp rename to higan/processor/arm/instructions-thumb.hpp diff --git a/bsnes/processor/arm/registers.cpp b/higan/processor/arm/registers.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/processor/arm/registers.cpp rename to higan/processor/arm/registers.cpp diff --git a/bsnes/processor/arm/registers.hpp b/higan/processor/arm/registers.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/processor/arm/registers.hpp rename to higan/processor/arm/registers.hpp diff --git a/bsnes/processor/arm/serialization.cpp b/higan/processor/arm/serialization.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/processor/arm/serialization.cpp rename to higan/processor/arm/serialization.cpp diff --git a/bsnes/processor/gsu/gsu.cpp b/higan/processor/gsu/gsu.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/processor/gsu/gsu.cpp rename to higan/processor/gsu/gsu.cpp diff --git a/bsnes/processor/gsu/gsu.hpp b/higan/processor/gsu/gsu.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/processor/gsu/gsu.hpp rename to higan/processor/gsu/gsu.hpp diff --git a/bsnes/processor/gsu/instructions.cpp b/higan/processor/gsu/instructions.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/processor/gsu/instructions.cpp rename to higan/processor/gsu/instructions.cpp diff --git a/bsnes/processor/gsu/registers.hpp b/higan/processor/gsu/registers.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/processor/gsu/registers.hpp rename to higan/processor/gsu/registers.hpp diff --git a/bsnes/processor/gsu/serialization.cpp b/higan/processor/gsu/serialization.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/processor/gsu/serialization.cpp rename to higan/processor/gsu/serialization.cpp diff --git a/bsnes/processor/gsu/table.cpp b/higan/processor/gsu/table.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/processor/gsu/table.cpp rename to higan/processor/gsu/table.cpp diff --git a/bsnes/processor/hg51b/hg51b.cpp b/higan/processor/hg51b/hg51b.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/processor/hg51b/hg51b.cpp rename to higan/processor/hg51b/hg51b.cpp diff --git a/bsnes/processor/hg51b/hg51b.hpp b/higan/processor/hg51b/hg51b.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/processor/hg51b/hg51b.hpp rename to higan/processor/hg51b/hg51b.hpp diff --git a/bsnes/processor/hg51b/instructions.cpp b/higan/processor/hg51b/instructions.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/processor/hg51b/instructions.cpp rename to higan/processor/hg51b/instructions.cpp diff --git a/bsnes/processor/hg51b/registers.cpp b/higan/processor/hg51b/registers.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/processor/hg51b/registers.cpp rename to higan/processor/hg51b/registers.cpp diff --git a/bsnes/processor/hg51b/registers.hpp b/higan/processor/hg51b/registers.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/processor/hg51b/registers.hpp rename to higan/processor/hg51b/registers.hpp diff --git a/bsnes/processor/hg51b/serialization.cpp b/higan/processor/hg51b/serialization.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/processor/hg51b/serialization.cpp rename to higan/processor/hg51b/serialization.cpp diff --git a/bsnes/processor/lr35902/disassembler.cpp b/higan/processor/lr35902/disassembler.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/processor/lr35902/disassembler.cpp rename to higan/processor/lr35902/disassembler.cpp diff --git a/bsnes/processor/lr35902/instructions.cpp b/higan/processor/lr35902/instructions.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/processor/lr35902/instructions.cpp rename to higan/processor/lr35902/instructions.cpp diff --git a/bsnes/processor/lr35902/lr35902.cpp b/higan/processor/lr35902/lr35902.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/processor/lr35902/lr35902.cpp rename to higan/processor/lr35902/lr35902.cpp diff --git a/bsnes/processor/lr35902/lr35902.hpp b/higan/processor/lr35902/lr35902.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/processor/lr35902/lr35902.hpp rename to higan/processor/lr35902/lr35902.hpp diff --git a/bsnes/processor/lr35902/registers.hpp b/higan/processor/lr35902/registers.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/processor/lr35902/registers.hpp rename to higan/processor/lr35902/registers.hpp diff --git a/bsnes/processor/lr35902/serialization.cpp b/higan/processor/lr35902/serialization.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/processor/lr35902/serialization.cpp rename to higan/processor/lr35902/serialization.cpp diff --git a/bsnes/processor/processor.hpp b/higan/processor/processor.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/processor/processor.hpp rename to higan/processor/processor.hpp diff --git a/bsnes/processor/r6502/disassembler.cpp b/higan/processor/r6502/disassembler.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/processor/r6502/disassembler.cpp rename to higan/processor/r6502/disassembler.cpp diff --git a/bsnes/processor/r6502/instructions.cpp b/higan/processor/r6502/instructions.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/processor/r6502/instructions.cpp rename to higan/processor/r6502/instructions.cpp diff --git a/bsnes/processor/r6502/memory.cpp b/higan/processor/r6502/memory.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/processor/r6502/memory.cpp rename to higan/processor/r6502/memory.cpp diff --git a/bsnes/processor/r6502/r6502.cpp b/higan/processor/r6502/r6502.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/processor/r6502/r6502.cpp rename to higan/processor/r6502/r6502.cpp diff --git a/bsnes/processor/r6502/r6502.hpp b/higan/processor/r6502/r6502.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/processor/r6502/r6502.hpp rename to higan/processor/r6502/r6502.hpp diff --git a/bsnes/processor/r6502/registers.hpp b/higan/processor/r6502/registers.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/processor/r6502/registers.hpp rename to higan/processor/r6502/registers.hpp diff --git a/bsnes/processor/r6502/serialization.cpp b/higan/processor/r6502/serialization.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/processor/r6502/serialization.cpp rename to higan/processor/r6502/serialization.cpp diff --git a/bsnes/processor/r65816/algorithms.cpp b/higan/processor/r65816/algorithms.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/processor/r65816/algorithms.cpp rename to higan/processor/r65816/algorithms.cpp diff --git a/bsnes/processor/r65816/disassembler.cpp b/higan/processor/r65816/disassembler.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/processor/r65816/disassembler.cpp rename to higan/processor/r65816/disassembler.cpp diff --git a/bsnes/processor/r65816/disassembler.hpp b/higan/processor/r65816/disassembler.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/processor/r65816/disassembler.hpp rename to higan/processor/r65816/disassembler.hpp diff --git a/bsnes/processor/r65816/memory.hpp b/higan/processor/r65816/memory.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/processor/r65816/memory.hpp rename to higan/processor/r65816/memory.hpp diff --git a/bsnes/processor/r65816/opcode_misc.cpp b/higan/processor/r65816/opcode_misc.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/processor/r65816/opcode_misc.cpp rename to higan/processor/r65816/opcode_misc.cpp diff --git a/bsnes/processor/r65816/opcode_pc.cpp b/higan/processor/r65816/opcode_pc.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/processor/r65816/opcode_pc.cpp rename to higan/processor/r65816/opcode_pc.cpp diff --git a/bsnes/processor/r65816/opcode_read.cpp b/higan/processor/r65816/opcode_read.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/processor/r65816/opcode_read.cpp rename to higan/processor/r65816/opcode_read.cpp diff --git a/bsnes/processor/r65816/opcode_rmw.cpp b/higan/processor/r65816/opcode_rmw.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/processor/r65816/opcode_rmw.cpp rename to higan/processor/r65816/opcode_rmw.cpp diff --git a/bsnes/processor/r65816/opcode_write.cpp b/higan/processor/r65816/opcode_write.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/processor/r65816/opcode_write.cpp rename to higan/processor/r65816/opcode_write.cpp diff --git a/bsnes/processor/r65816/r65816.cpp b/higan/processor/r65816/r65816.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/processor/r65816/r65816.cpp rename to higan/processor/r65816/r65816.cpp diff --git a/bsnes/processor/r65816/r65816.hpp b/higan/processor/r65816/r65816.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/processor/r65816/r65816.hpp rename to higan/processor/r65816/r65816.hpp diff --git a/bsnes/processor/r65816/registers.hpp b/higan/processor/r65816/registers.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/processor/r65816/registers.hpp rename to higan/processor/r65816/registers.hpp diff --git a/bsnes/processor/r65816/serialization.cpp b/higan/processor/r65816/serialization.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/processor/r65816/serialization.cpp rename to higan/processor/r65816/serialization.cpp diff --git a/bsnes/processor/r65816/table.cpp b/higan/processor/r65816/table.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/processor/r65816/table.cpp rename to higan/processor/r65816/table.cpp diff --git a/bsnes/processor/spc700/algorithms.cpp b/higan/processor/spc700/algorithms.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/processor/spc700/algorithms.cpp rename to higan/processor/spc700/algorithms.cpp diff --git a/bsnes/processor/spc700/disassembler.cpp b/higan/processor/spc700/disassembler.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/processor/spc700/disassembler.cpp rename to higan/processor/spc700/disassembler.cpp diff --git a/bsnes/processor/spc700/instructions.cpp b/higan/processor/spc700/instructions.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/processor/spc700/instructions.cpp rename to higan/processor/spc700/instructions.cpp diff --git a/bsnes/processor/spc700/memory.hpp b/higan/processor/spc700/memory.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/processor/spc700/memory.hpp rename to higan/processor/spc700/memory.hpp diff --git a/bsnes/processor/spc700/registers.hpp b/higan/processor/spc700/registers.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/processor/spc700/registers.hpp rename to higan/processor/spc700/registers.hpp diff --git a/bsnes/processor/spc700/serialization.cpp b/higan/processor/spc700/serialization.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/processor/spc700/serialization.cpp rename to higan/processor/spc700/serialization.cpp diff --git a/bsnes/processor/spc700/spc700.cpp b/higan/processor/spc700/spc700.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/processor/spc700/spc700.cpp rename to higan/processor/spc700/spc700.cpp diff --git a/bsnes/processor/spc700/spc700.hpp b/higan/processor/spc700/spc700.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/processor/spc700/spc700.hpp rename to higan/processor/spc700/spc700.hpp diff --git a/bsnes/processor/upd96050/disassembler.cpp b/higan/processor/upd96050/disassembler.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/processor/upd96050/disassembler.cpp rename to higan/processor/upd96050/disassembler.cpp diff --git a/bsnes/processor/upd96050/instructions.cpp b/higan/processor/upd96050/instructions.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/processor/upd96050/instructions.cpp rename to higan/processor/upd96050/instructions.cpp diff --git a/bsnes/processor/upd96050/memory.cpp b/higan/processor/upd96050/memory.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/processor/upd96050/memory.cpp rename to higan/processor/upd96050/memory.cpp diff --git a/bsnes/processor/upd96050/registers.hpp b/higan/processor/upd96050/registers.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/processor/upd96050/registers.hpp rename to higan/processor/upd96050/registers.hpp diff --git a/bsnes/processor/upd96050/serialization.cpp b/higan/processor/upd96050/serialization.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/processor/upd96050/serialization.cpp rename to higan/processor/upd96050/serialization.cpp diff --git a/bsnes/processor/upd96050/upd96050.cpp b/higan/processor/upd96050/upd96050.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/processor/upd96050/upd96050.cpp rename to higan/processor/upd96050/upd96050.cpp diff --git a/bsnes/processor/upd96050/upd96050.hpp b/higan/processor/upd96050/upd96050.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/processor/upd96050/upd96050.hpp rename to higan/processor/upd96050/upd96050.hpp diff --git a/bsnes/profile/BS-X Satellaview.sfc/manifest.xml b/higan/profile/BS-X Satellaview.sfc/manifest.xml old mode 100644 new mode 100755 similarity index 100% rename from bsnes/profile/BS-X Satellaview.sfc/manifest.xml rename to higan/profile/BS-X Satellaview.sfc/manifest.xml diff --git a/bsnes/profile/Famicom.sys/manifest.xml b/higan/profile/Famicom.sys/manifest.xml old mode 100644 new mode 100755 similarity index 100% rename from bsnes/profile/Famicom.sys/manifest.xml rename to higan/profile/Famicom.sys/manifest.xml diff --git a/bsnes/profile/Game Boy Advance.sys/manifest.xml b/higan/profile/Game Boy Advance.sys/manifest.xml old mode 100644 new mode 100755 similarity index 100% rename from bsnes/profile/Game Boy Advance.sys/manifest.xml rename to higan/profile/Game Boy Advance.sys/manifest.xml diff --git a/bsnes/profile/Game Boy Color.sys/boot.rom b/higan/profile/Game Boy Color.sys/boot.rom old mode 100644 new mode 100755 similarity index 100% rename from bsnes/profile/Game Boy Color.sys/boot.rom rename to higan/profile/Game Boy Color.sys/boot.rom diff --git a/bsnes/profile/Game Boy Color.sys/manifest.xml b/higan/profile/Game Boy Color.sys/manifest.xml old mode 100644 new mode 100755 similarity index 100% rename from bsnes/profile/Game Boy Color.sys/manifest.xml rename to higan/profile/Game Boy Color.sys/manifest.xml diff --git a/bsnes/profile/Game Boy.sys/boot.rom b/higan/profile/Game Boy.sys/boot.rom old mode 100644 new mode 100755 similarity index 100% rename from bsnes/profile/Game Boy.sys/boot.rom rename to higan/profile/Game Boy.sys/boot.rom diff --git a/bsnes/profile/Game Boy.sys/manifest.xml b/higan/profile/Game Boy.sys/manifest.xml old mode 100644 new mode 100755 similarity index 100% rename from bsnes/profile/Game Boy.sys/manifest.xml rename to higan/profile/Game Boy.sys/manifest.xml diff --git a/bsnes/profile/Sufami Turbo.sfc/manifest.xml b/higan/profile/Sufami Turbo.sfc/manifest.xml old mode 100644 new mode 100755 similarity index 100% rename from bsnes/profile/Sufami Turbo.sfc/manifest.xml rename to higan/profile/Sufami Turbo.sfc/manifest.xml diff --git a/bsnes/profile/Super Famicom.sys/manifest.xml b/higan/profile/Super Famicom.sys/manifest.xml old mode 100644 new mode 100755 similarity index 100% rename from bsnes/profile/Super Famicom.sys/manifest.xml rename to higan/profile/Super Famicom.sys/manifest.xml diff --git a/bsnes/profile/Super Famicom.sys/spc700.rom b/higan/profile/Super Famicom.sys/spc700.rom old mode 100644 new mode 100755 similarity index 100% rename from bsnes/profile/Super Famicom.sys/spc700.rom rename to higan/profile/Super Famicom.sys/spc700.rom diff --git a/bsnes/profile/Super Game Boy.sfc/boot.rom b/higan/profile/Super Game Boy.sfc/boot.rom old mode 100644 new mode 100755 similarity index 100% rename from bsnes/profile/Super Game Boy.sfc/boot.rom rename to higan/profile/Super Game Boy.sfc/boot.rom diff --git a/bsnes/profile/Super Game Boy.sfc/manifest.xml b/higan/profile/Super Game Boy.sfc/manifest.xml old mode 100644 new mode 100755 similarity index 100% rename from bsnes/profile/Super Game Boy.sfc/manifest.xml rename to higan/profile/Super Game Boy.sfc/manifest.xml diff --git a/bsnes/ruby/Makefile b/higan/ruby/Makefile old mode 100644 new mode 100755 similarity index 100% rename from bsnes/ruby/Makefile rename to higan/ruby/Makefile diff --git a/bsnes/ruby/audio.hpp b/higan/ruby/audio.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/ruby/audio.hpp rename to higan/ruby/audio.hpp diff --git a/bsnes/ruby/audio/alsa.cpp b/higan/ruby/audio/alsa.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/ruby/audio/alsa.cpp rename to higan/ruby/audio/alsa.cpp diff --git a/bsnes/ruby/audio/ao.cpp b/higan/ruby/audio/ao.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/ruby/audio/ao.cpp rename to higan/ruby/audio/ao.cpp diff --git a/bsnes/ruby/audio/directsound.cpp b/higan/ruby/audio/directsound.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/ruby/audio/directsound.cpp rename to higan/ruby/audio/directsound.cpp diff --git a/bsnes/ruby/audio/openal.cpp b/higan/ruby/audio/openal.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/ruby/audio/openal.cpp rename to higan/ruby/audio/openal.cpp diff --git a/bsnes/ruby/audio/oss.cpp b/higan/ruby/audio/oss.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/ruby/audio/oss.cpp rename to higan/ruby/audio/oss.cpp diff --git a/bsnes/ruby/audio/pulseaudio.cpp b/higan/ruby/audio/pulseaudio.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/ruby/audio/pulseaudio.cpp rename to higan/ruby/audio/pulseaudio.cpp diff --git a/bsnes/ruby/audio/pulseaudiosimple.cpp b/higan/ruby/audio/pulseaudiosimple.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/ruby/audio/pulseaudiosimple.cpp rename to higan/ruby/audio/pulseaudiosimple.cpp diff --git a/bsnes/ruby/audio/xaudio2.cpp b/higan/ruby/audio/xaudio2.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/ruby/audio/xaudio2.cpp rename to higan/ruby/audio/xaudio2.cpp diff --git a/bsnes/ruby/audio/xaudio2.hpp b/higan/ruby/audio/xaudio2.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/ruby/audio/xaudio2.hpp rename to higan/ruby/audio/xaudio2.hpp diff --git a/bsnes/ruby/input.hpp b/higan/ruby/input.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/ruby/input.hpp rename to higan/ruby/input.hpp diff --git a/bsnes/ruby/input/carbon.cpp b/higan/ruby/input/carbon.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/ruby/input/carbon.cpp rename to higan/ruby/input/carbon.cpp diff --git a/bsnes/ruby/input/directinput.cpp b/higan/ruby/input/directinput.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/ruby/input/directinput.cpp rename to higan/ruby/input/directinput.cpp diff --git a/bsnes/ruby/input/rawinput.cpp b/higan/ruby/input/rawinput.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/ruby/input/rawinput.cpp rename to higan/ruby/input/rawinput.cpp diff --git a/bsnes/ruby/input/sdl.cpp b/higan/ruby/input/sdl.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/ruby/input/sdl.cpp rename to higan/ruby/input/sdl.cpp diff --git a/bsnes/ruby/input/x.cpp b/higan/ruby/input/x.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/ruby/input/x.cpp rename to higan/ruby/input/x.cpp diff --git a/bsnes/ruby/input/xlibkeys.hpp b/higan/ruby/input/xlibkeys.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/ruby/input/xlibkeys.hpp rename to higan/ruby/input/xlibkeys.hpp diff --git a/bsnes/ruby/ruby.cpp b/higan/ruby/ruby.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/ruby/ruby.cpp rename to higan/ruby/ruby.cpp diff --git a/bsnes/ruby/ruby.hpp b/higan/ruby/ruby.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/ruby/ruby.hpp rename to higan/ruby/ruby.hpp diff --git a/bsnes/ruby/ruby_impl.cpp b/higan/ruby/ruby_impl.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/ruby/ruby_impl.cpp rename to higan/ruby/ruby_impl.cpp diff --git a/bsnes/ruby/video.hpp b/higan/ruby/video.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/ruby/video.hpp rename to higan/ruby/video.hpp diff --git a/bsnes/ruby/video/direct3d.cpp b/higan/ruby/video/direct3d.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/ruby/video/direct3d.cpp rename to higan/ruby/video/direct3d.cpp diff --git a/bsnes/ruby/video/directdraw.cpp b/higan/ruby/video/directdraw.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/ruby/video/directdraw.cpp rename to higan/ruby/video/directdraw.cpp diff --git a/bsnes/ruby/video/gdi.cpp b/higan/ruby/video/gdi.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/ruby/video/gdi.cpp rename to higan/ruby/video/gdi.cpp diff --git a/bsnes/ruby/video/glx.cpp b/higan/ruby/video/glx.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/ruby/video/glx.cpp rename to higan/ruby/video/glx.cpp diff --git a/bsnes/ruby/video/opengl.hpp b/higan/ruby/video/opengl.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/ruby/video/opengl.hpp rename to higan/ruby/video/opengl.hpp diff --git a/bsnes/ruby/video/qtopengl.cpp b/higan/ruby/video/qtopengl.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/ruby/video/qtopengl.cpp rename to higan/ruby/video/qtopengl.cpp diff --git a/bsnes/ruby/video/qtraster.cpp b/higan/ruby/video/qtraster.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/ruby/video/qtraster.cpp rename to higan/ruby/video/qtraster.cpp diff --git a/bsnes/ruby/video/sdl.cpp b/higan/ruby/video/sdl.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/ruby/video/sdl.cpp rename to higan/ruby/video/sdl.cpp diff --git a/bsnes/ruby/video/wgl.cpp b/higan/ruby/video/wgl.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/ruby/video/wgl.cpp rename to higan/ruby/video/wgl.cpp diff --git a/bsnes/ruby/video/xshm.cpp b/higan/ruby/video/xshm.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/ruby/video/xshm.cpp rename to higan/ruby/video/xshm.cpp diff --git a/bsnes/ruby/video/xv.cpp b/higan/ruby/video/xv.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/ruby/video/xv.cpp rename to higan/ruby/video/xv.cpp diff --git a/bsnes/sfc/Makefile b/higan/sfc/Makefile old mode 100644 new mode 100755 similarity index 100% rename from bsnes/sfc/Makefile rename to higan/sfc/Makefile diff --git a/bsnes/sfc/alt/cpu/cpu.cpp b/higan/sfc/alt/cpu/cpu.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/sfc/alt/cpu/cpu.cpp rename to higan/sfc/alt/cpu/cpu.cpp diff --git a/bsnes/sfc/alt/cpu/cpu.hpp b/higan/sfc/alt/cpu/cpu.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/sfc/alt/cpu/cpu.hpp rename to higan/sfc/alt/cpu/cpu.hpp diff --git a/bsnes/sfc/alt/cpu/dma.cpp b/higan/sfc/alt/cpu/dma.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/sfc/alt/cpu/dma.cpp rename to higan/sfc/alt/cpu/dma.cpp diff --git a/bsnes/sfc/alt/cpu/memory.cpp b/higan/sfc/alt/cpu/memory.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/sfc/alt/cpu/memory.cpp rename to higan/sfc/alt/cpu/memory.cpp diff --git a/bsnes/sfc/alt/cpu/mmio.cpp b/higan/sfc/alt/cpu/mmio.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/sfc/alt/cpu/mmio.cpp rename to higan/sfc/alt/cpu/mmio.cpp diff --git a/bsnes/sfc/alt/cpu/serialization.cpp b/higan/sfc/alt/cpu/serialization.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/sfc/alt/cpu/serialization.cpp rename to higan/sfc/alt/cpu/serialization.cpp diff --git a/bsnes/sfc/alt/cpu/timing.cpp b/higan/sfc/alt/cpu/timing.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/sfc/alt/cpu/timing.cpp rename to higan/sfc/alt/cpu/timing.cpp diff --git a/bsnes/sfc/alt/dsp/SPC_DSP.cpp b/higan/sfc/alt/dsp/SPC_DSP.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/sfc/alt/dsp/SPC_DSP.cpp rename to higan/sfc/alt/dsp/SPC_DSP.cpp diff --git a/bsnes/sfc/alt/dsp/SPC_DSP.h b/higan/sfc/alt/dsp/SPC_DSP.h old mode 100644 new mode 100755 similarity index 100% rename from bsnes/sfc/alt/dsp/SPC_DSP.h rename to higan/sfc/alt/dsp/SPC_DSP.h diff --git a/bsnes/sfc/alt/dsp/blargg_common.h b/higan/sfc/alt/dsp/blargg_common.h old mode 100644 new mode 100755 similarity index 100% rename from bsnes/sfc/alt/dsp/blargg_common.h rename to higan/sfc/alt/dsp/blargg_common.h diff --git a/bsnes/sfc/alt/dsp/blargg_config.h b/higan/sfc/alt/dsp/blargg_config.h old mode 100644 new mode 100755 similarity index 100% rename from bsnes/sfc/alt/dsp/blargg_config.h rename to higan/sfc/alt/dsp/blargg_config.h diff --git a/bsnes/sfc/alt/dsp/blargg_endian.h b/higan/sfc/alt/dsp/blargg_endian.h old mode 100644 new mode 100755 similarity index 100% rename from bsnes/sfc/alt/dsp/blargg_endian.h rename to higan/sfc/alt/dsp/blargg_endian.h diff --git a/bsnes/sfc/alt/dsp/blargg_source.h b/higan/sfc/alt/dsp/blargg_source.h old mode 100644 new mode 100755 similarity index 100% rename from bsnes/sfc/alt/dsp/blargg_source.h rename to higan/sfc/alt/dsp/blargg_source.h diff --git a/bsnes/sfc/alt/dsp/dsp.cpp b/higan/sfc/alt/dsp/dsp.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/sfc/alt/dsp/dsp.cpp rename to higan/sfc/alt/dsp/dsp.cpp diff --git a/bsnes/sfc/alt/dsp/dsp.hpp b/higan/sfc/alt/dsp/dsp.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/sfc/alt/dsp/dsp.hpp rename to higan/sfc/alt/dsp/dsp.hpp diff --git a/bsnes/sfc/alt/dsp/serialization.cpp b/higan/sfc/alt/dsp/serialization.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/sfc/alt/dsp/serialization.cpp rename to higan/sfc/alt/dsp/serialization.cpp diff --git a/bsnes/sfc/alt/ppu-compatibility/memory/memory.cpp b/higan/sfc/alt/ppu-compatibility/memory/memory.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/sfc/alt/ppu-compatibility/memory/memory.cpp rename to higan/sfc/alt/ppu-compatibility/memory/memory.cpp diff --git a/bsnes/sfc/alt/ppu-compatibility/memory/memory.hpp b/higan/sfc/alt/ppu-compatibility/memory/memory.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/sfc/alt/ppu-compatibility/memory/memory.hpp rename to higan/sfc/alt/ppu-compatibility/memory/memory.hpp diff --git a/bsnes/sfc/alt/ppu-compatibility/mmio/mmio.cpp b/higan/sfc/alt/ppu-compatibility/mmio/mmio.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/sfc/alt/ppu-compatibility/mmio/mmio.cpp rename to higan/sfc/alt/ppu-compatibility/mmio/mmio.cpp diff --git a/bsnes/sfc/alt/ppu-compatibility/mmio/mmio.hpp b/higan/sfc/alt/ppu-compatibility/mmio/mmio.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/sfc/alt/ppu-compatibility/mmio/mmio.hpp rename to higan/sfc/alt/ppu-compatibility/mmio/mmio.hpp diff --git a/bsnes/sfc/alt/ppu-compatibility/ppu.cpp b/higan/sfc/alt/ppu-compatibility/ppu.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/sfc/alt/ppu-compatibility/ppu.cpp rename to higan/sfc/alt/ppu-compatibility/ppu.cpp diff --git a/bsnes/sfc/alt/ppu-compatibility/ppu.hpp b/higan/sfc/alt/ppu-compatibility/ppu.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/sfc/alt/ppu-compatibility/ppu.hpp rename to higan/sfc/alt/ppu-compatibility/ppu.hpp diff --git a/bsnes/sfc/alt/ppu-compatibility/render/addsub.cpp b/higan/sfc/alt/ppu-compatibility/render/addsub.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/sfc/alt/ppu-compatibility/render/addsub.cpp rename to higan/sfc/alt/ppu-compatibility/render/addsub.cpp diff --git a/bsnes/sfc/alt/ppu-compatibility/render/bg.cpp b/higan/sfc/alt/ppu-compatibility/render/bg.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/sfc/alt/ppu-compatibility/render/bg.cpp rename to higan/sfc/alt/ppu-compatibility/render/bg.cpp diff --git a/bsnes/sfc/alt/ppu-compatibility/render/cache.cpp b/higan/sfc/alt/ppu-compatibility/render/cache.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/sfc/alt/ppu-compatibility/render/cache.cpp rename to higan/sfc/alt/ppu-compatibility/render/cache.cpp diff --git a/bsnes/sfc/alt/ppu-compatibility/render/line.cpp b/higan/sfc/alt/ppu-compatibility/render/line.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/sfc/alt/ppu-compatibility/render/line.cpp rename to higan/sfc/alt/ppu-compatibility/render/line.cpp diff --git a/bsnes/sfc/alt/ppu-compatibility/render/mode7.cpp b/higan/sfc/alt/ppu-compatibility/render/mode7.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/sfc/alt/ppu-compatibility/render/mode7.cpp rename to higan/sfc/alt/ppu-compatibility/render/mode7.cpp diff --git a/bsnes/sfc/alt/ppu-compatibility/render/oam.cpp b/higan/sfc/alt/ppu-compatibility/render/oam.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/sfc/alt/ppu-compatibility/render/oam.cpp rename to higan/sfc/alt/ppu-compatibility/render/oam.cpp diff --git a/bsnes/sfc/alt/ppu-compatibility/render/render.cpp b/higan/sfc/alt/ppu-compatibility/render/render.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/sfc/alt/ppu-compatibility/render/render.cpp rename to higan/sfc/alt/ppu-compatibility/render/render.cpp diff --git a/bsnes/sfc/alt/ppu-compatibility/render/render.hpp b/higan/sfc/alt/ppu-compatibility/render/render.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/sfc/alt/ppu-compatibility/render/render.hpp rename to higan/sfc/alt/ppu-compatibility/render/render.hpp diff --git a/bsnes/sfc/alt/ppu-compatibility/render/windows.cpp b/higan/sfc/alt/ppu-compatibility/render/windows.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/sfc/alt/ppu-compatibility/render/windows.cpp rename to higan/sfc/alt/ppu-compatibility/render/windows.cpp diff --git a/bsnes/sfc/alt/ppu-compatibility/serialization.cpp b/higan/sfc/alt/ppu-compatibility/serialization.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/sfc/alt/ppu-compatibility/serialization.cpp rename to higan/sfc/alt/ppu-compatibility/serialization.cpp diff --git a/bsnes/sfc/alt/ppu-performance/background/background.cpp b/higan/sfc/alt/ppu-performance/background/background.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/sfc/alt/ppu-performance/background/background.cpp rename to higan/sfc/alt/ppu-performance/background/background.cpp diff --git a/bsnes/sfc/alt/ppu-performance/background/background.hpp b/higan/sfc/alt/ppu-performance/background/background.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/sfc/alt/ppu-performance/background/background.hpp rename to higan/sfc/alt/ppu-performance/background/background.hpp diff --git a/bsnes/sfc/alt/ppu-performance/background/mode7.cpp b/higan/sfc/alt/ppu-performance/background/mode7.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/sfc/alt/ppu-performance/background/mode7.cpp rename to higan/sfc/alt/ppu-performance/background/mode7.cpp diff --git a/bsnes/sfc/alt/ppu-performance/cache/cache.cpp b/higan/sfc/alt/ppu-performance/cache/cache.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/sfc/alt/ppu-performance/cache/cache.cpp rename to higan/sfc/alt/ppu-performance/cache/cache.cpp diff --git a/bsnes/sfc/alt/ppu-performance/cache/cache.hpp b/higan/sfc/alt/ppu-performance/cache/cache.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/sfc/alt/ppu-performance/cache/cache.hpp rename to higan/sfc/alt/ppu-performance/cache/cache.hpp diff --git a/bsnes/sfc/alt/ppu-performance/mmio/mmio.cpp b/higan/sfc/alt/ppu-performance/mmio/mmio.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/sfc/alt/ppu-performance/mmio/mmio.cpp rename to higan/sfc/alt/ppu-performance/mmio/mmio.cpp diff --git a/bsnes/sfc/alt/ppu-performance/mmio/mmio.hpp b/higan/sfc/alt/ppu-performance/mmio/mmio.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/sfc/alt/ppu-performance/mmio/mmio.hpp rename to higan/sfc/alt/ppu-performance/mmio/mmio.hpp diff --git a/bsnes/sfc/alt/ppu-performance/ppu.cpp b/higan/sfc/alt/ppu-performance/ppu.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/sfc/alt/ppu-performance/ppu.cpp rename to higan/sfc/alt/ppu-performance/ppu.cpp diff --git a/bsnes/sfc/alt/ppu-performance/ppu.hpp b/higan/sfc/alt/ppu-performance/ppu.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/sfc/alt/ppu-performance/ppu.hpp rename to higan/sfc/alt/ppu-performance/ppu.hpp diff --git a/bsnes/sfc/alt/ppu-performance/screen/screen.cpp b/higan/sfc/alt/ppu-performance/screen/screen.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/sfc/alt/ppu-performance/screen/screen.cpp rename to higan/sfc/alt/ppu-performance/screen/screen.cpp diff --git a/bsnes/sfc/alt/ppu-performance/screen/screen.hpp b/higan/sfc/alt/ppu-performance/screen/screen.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/sfc/alt/ppu-performance/screen/screen.hpp rename to higan/sfc/alt/ppu-performance/screen/screen.hpp diff --git a/bsnes/sfc/alt/ppu-performance/serialization.cpp b/higan/sfc/alt/ppu-performance/serialization.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/sfc/alt/ppu-performance/serialization.cpp rename to higan/sfc/alt/ppu-performance/serialization.cpp diff --git a/bsnes/sfc/alt/ppu-performance/sprite/sprite.cpp b/higan/sfc/alt/ppu-performance/sprite/sprite.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/sfc/alt/ppu-performance/sprite/sprite.cpp rename to higan/sfc/alt/ppu-performance/sprite/sprite.cpp diff --git a/bsnes/sfc/alt/ppu-performance/sprite/sprite.hpp b/higan/sfc/alt/ppu-performance/sprite/sprite.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/sfc/alt/ppu-performance/sprite/sprite.hpp rename to higan/sfc/alt/ppu-performance/sprite/sprite.hpp diff --git a/bsnes/sfc/alt/ppu-performance/window/window.cpp b/higan/sfc/alt/ppu-performance/window/window.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/sfc/alt/ppu-performance/window/window.cpp rename to higan/sfc/alt/ppu-performance/window/window.cpp diff --git a/bsnes/sfc/alt/ppu-performance/window/window.hpp b/higan/sfc/alt/ppu-performance/window/window.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/sfc/alt/ppu-performance/window/window.hpp rename to higan/sfc/alt/ppu-performance/window/window.hpp diff --git a/bsnes/sfc/alt/smp/algorithms.cpp b/higan/sfc/alt/smp/algorithms.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/sfc/alt/smp/algorithms.cpp rename to higan/sfc/alt/smp/algorithms.cpp diff --git a/bsnes/sfc/alt/smp/core.cpp b/higan/sfc/alt/smp/core.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/sfc/alt/smp/core.cpp rename to higan/sfc/alt/smp/core.cpp diff --git a/bsnes/sfc/alt/smp/core/cc.sh b/higan/sfc/alt/smp/core/cc.sh old mode 100644 new mode 100755 similarity index 100% rename from bsnes/sfc/alt/smp/core/cc.sh rename to higan/sfc/alt/smp/core/cc.sh diff --git a/bsnes/sfc/alt/smp/core/generate.cpp b/higan/sfc/alt/smp/core/generate.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/sfc/alt/smp/core/generate.cpp rename to higan/sfc/alt/smp/core/generate.cpp diff --git a/bsnes/sfc/alt/smp/core/op_misc.b b/higan/sfc/alt/smp/core/op_misc.b old mode 100644 new mode 100755 similarity index 100% rename from bsnes/sfc/alt/smp/core/op_misc.b rename to higan/sfc/alt/smp/core/op_misc.b diff --git a/bsnes/sfc/alt/smp/core/op_misc.cpp b/higan/sfc/alt/smp/core/op_misc.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/sfc/alt/smp/core/op_misc.cpp rename to higan/sfc/alt/smp/core/op_misc.cpp diff --git a/bsnes/sfc/alt/smp/core/op_mov.b b/higan/sfc/alt/smp/core/op_mov.b old mode 100644 new mode 100755 similarity index 100% rename from bsnes/sfc/alt/smp/core/op_mov.b rename to higan/sfc/alt/smp/core/op_mov.b diff --git a/bsnes/sfc/alt/smp/core/op_mov.cpp b/higan/sfc/alt/smp/core/op_mov.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/sfc/alt/smp/core/op_mov.cpp rename to higan/sfc/alt/smp/core/op_mov.cpp diff --git a/bsnes/sfc/alt/smp/core/op_pc.b b/higan/sfc/alt/smp/core/op_pc.b old mode 100644 new mode 100755 similarity index 100% rename from bsnes/sfc/alt/smp/core/op_pc.b rename to higan/sfc/alt/smp/core/op_pc.b diff --git a/bsnes/sfc/alt/smp/core/op_pc.cpp b/higan/sfc/alt/smp/core/op_pc.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/sfc/alt/smp/core/op_pc.cpp rename to higan/sfc/alt/smp/core/op_pc.cpp diff --git a/bsnes/sfc/alt/smp/core/op_read.b b/higan/sfc/alt/smp/core/op_read.b old mode 100644 new mode 100755 similarity index 100% rename from bsnes/sfc/alt/smp/core/op_read.b rename to higan/sfc/alt/smp/core/op_read.b diff --git a/bsnes/sfc/alt/smp/core/op_read.cpp b/higan/sfc/alt/smp/core/op_read.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/sfc/alt/smp/core/op_read.cpp rename to higan/sfc/alt/smp/core/op_read.cpp diff --git a/bsnes/sfc/alt/smp/core/op_rmw.b b/higan/sfc/alt/smp/core/op_rmw.b old mode 100644 new mode 100755 similarity index 100% rename from bsnes/sfc/alt/smp/core/op_rmw.b rename to higan/sfc/alt/smp/core/op_rmw.b diff --git a/bsnes/sfc/alt/smp/core/op_rmw.cpp b/higan/sfc/alt/smp/core/op_rmw.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/sfc/alt/smp/core/op_rmw.cpp rename to higan/sfc/alt/smp/core/op_rmw.cpp diff --git a/bsnes/sfc/alt/smp/core/opcycle_misc.cpp b/higan/sfc/alt/smp/core/opcycle_misc.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/sfc/alt/smp/core/opcycle_misc.cpp rename to higan/sfc/alt/smp/core/opcycle_misc.cpp diff --git a/bsnes/sfc/alt/smp/core/opcycle_mov.cpp b/higan/sfc/alt/smp/core/opcycle_mov.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/sfc/alt/smp/core/opcycle_mov.cpp rename to higan/sfc/alt/smp/core/opcycle_mov.cpp diff --git a/bsnes/sfc/alt/smp/core/opcycle_pc.cpp b/higan/sfc/alt/smp/core/opcycle_pc.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/sfc/alt/smp/core/opcycle_pc.cpp rename to higan/sfc/alt/smp/core/opcycle_pc.cpp diff --git a/bsnes/sfc/alt/smp/core/opcycle_read.cpp b/higan/sfc/alt/smp/core/opcycle_read.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/sfc/alt/smp/core/opcycle_read.cpp rename to higan/sfc/alt/smp/core/opcycle_read.cpp diff --git a/bsnes/sfc/alt/smp/core/opcycle_rmw.cpp b/higan/sfc/alt/smp/core/opcycle_rmw.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/sfc/alt/smp/core/opcycle_rmw.cpp rename to higan/sfc/alt/smp/core/opcycle_rmw.cpp diff --git a/bsnes/sfc/alt/smp/disassembler.cpp b/higan/sfc/alt/smp/disassembler.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/sfc/alt/smp/disassembler.cpp rename to higan/sfc/alt/smp/disassembler.cpp diff --git a/bsnes/sfc/alt/smp/memory.cpp b/higan/sfc/alt/smp/memory.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/sfc/alt/smp/memory.cpp rename to higan/sfc/alt/smp/memory.cpp diff --git a/bsnes/sfc/alt/smp/smp.cpp b/higan/sfc/alt/smp/smp.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/sfc/alt/smp/smp.cpp rename to higan/sfc/alt/smp/smp.cpp diff --git a/bsnes/sfc/alt/smp/smp.hpp b/higan/sfc/alt/smp/smp.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/sfc/alt/smp/smp.hpp rename to higan/sfc/alt/smp/smp.hpp diff --git a/bsnes/sfc/alt/smp/timing.cpp b/higan/sfc/alt/smp/timing.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/sfc/alt/smp/timing.cpp rename to higan/sfc/alt/smp/timing.cpp diff --git a/bsnes/sfc/cartridge/cartridge.cpp b/higan/sfc/cartridge/cartridge.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/sfc/cartridge/cartridge.cpp rename to higan/sfc/cartridge/cartridge.cpp diff --git a/bsnes/sfc/cartridge/cartridge.hpp b/higan/sfc/cartridge/cartridge.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/sfc/cartridge/cartridge.hpp rename to higan/sfc/cartridge/cartridge.hpp diff --git a/bsnes/sfc/cartridge/markup.cpp b/higan/sfc/cartridge/markup.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/sfc/cartridge/markup.cpp rename to higan/sfc/cartridge/markup.cpp diff --git a/bsnes/sfc/cartridge/serialization.cpp b/higan/sfc/cartridge/serialization.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/sfc/cartridge/serialization.cpp rename to higan/sfc/cartridge/serialization.cpp diff --git a/bsnes/sfc/cheat/cheat.cpp b/higan/sfc/cheat/cheat.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/sfc/cheat/cheat.cpp rename to higan/sfc/cheat/cheat.cpp diff --git a/bsnes/sfc/cheat/cheat.hpp b/higan/sfc/cheat/cheat.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/sfc/cheat/cheat.hpp rename to higan/sfc/cheat/cheat.hpp diff --git a/bsnes/sfc/chip/armdsp/armdsp.cpp b/higan/sfc/chip/armdsp/armdsp.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/sfc/chip/armdsp/armdsp.cpp rename to higan/sfc/chip/armdsp/armdsp.cpp diff --git a/bsnes/sfc/chip/armdsp/armdsp.hpp b/higan/sfc/chip/armdsp/armdsp.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/sfc/chip/armdsp/armdsp.hpp rename to higan/sfc/chip/armdsp/armdsp.hpp diff --git a/bsnes/sfc/chip/armdsp/memory.cpp b/higan/sfc/chip/armdsp/memory.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/sfc/chip/armdsp/memory.cpp rename to higan/sfc/chip/armdsp/memory.cpp diff --git a/bsnes/sfc/chip/armdsp/registers.hpp b/higan/sfc/chip/armdsp/registers.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/sfc/chip/armdsp/registers.hpp rename to higan/sfc/chip/armdsp/registers.hpp diff --git a/bsnes/sfc/chip/armdsp/serialization.cpp b/higan/sfc/chip/armdsp/serialization.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/sfc/chip/armdsp/serialization.cpp rename to higan/sfc/chip/armdsp/serialization.cpp diff --git a/bsnes/sfc/chip/bsx/bsx.cpp b/higan/sfc/chip/bsx/bsx.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/sfc/chip/bsx/bsx.cpp rename to higan/sfc/chip/bsx/bsx.cpp diff --git a/bsnes/sfc/chip/bsx/bsx.hpp b/higan/sfc/chip/bsx/bsx.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/sfc/chip/bsx/bsx.hpp rename to higan/sfc/chip/bsx/bsx.hpp diff --git a/bsnes/sfc/chip/bsx/cartridge/cartridge.cpp b/higan/sfc/chip/bsx/cartridge/cartridge.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/sfc/chip/bsx/cartridge/cartridge.cpp rename to higan/sfc/chip/bsx/cartridge/cartridge.cpp diff --git a/bsnes/sfc/chip/bsx/cartridge/cartridge.hpp b/higan/sfc/chip/bsx/cartridge/cartridge.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/sfc/chip/bsx/cartridge/cartridge.hpp rename to higan/sfc/chip/bsx/cartridge/cartridge.hpp diff --git a/bsnes/sfc/chip/bsx/cartridge/serialization.cpp b/higan/sfc/chip/bsx/cartridge/serialization.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/sfc/chip/bsx/cartridge/serialization.cpp rename to higan/sfc/chip/bsx/cartridge/serialization.cpp diff --git a/bsnes/sfc/chip/bsx/flash/flash.cpp b/higan/sfc/chip/bsx/flash/flash.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/sfc/chip/bsx/flash/flash.cpp rename to higan/sfc/chip/bsx/flash/flash.cpp diff --git a/bsnes/sfc/chip/bsx/flash/flash.hpp b/higan/sfc/chip/bsx/flash/flash.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/sfc/chip/bsx/flash/flash.hpp rename to higan/sfc/chip/bsx/flash/flash.hpp diff --git a/bsnes/sfc/chip/bsx/satellaview/satellaview.cpp b/higan/sfc/chip/bsx/satellaview/satellaview.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/sfc/chip/bsx/satellaview/satellaview.cpp rename to higan/sfc/chip/bsx/satellaview/satellaview.cpp diff --git a/bsnes/sfc/chip/bsx/satellaview/satellaview.hpp b/higan/sfc/chip/bsx/satellaview/satellaview.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/sfc/chip/bsx/satellaview/satellaview.hpp rename to higan/sfc/chip/bsx/satellaview/satellaview.hpp diff --git a/bsnes/sfc/chip/chip.hpp b/higan/sfc/chip/chip.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/sfc/chip/chip.hpp rename to higan/sfc/chip/chip.hpp diff --git a/bsnes/sfc/chip/epsonrtc/epsonrtc.cpp b/higan/sfc/chip/epsonrtc/epsonrtc.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/sfc/chip/epsonrtc/epsonrtc.cpp rename to higan/sfc/chip/epsonrtc/epsonrtc.cpp diff --git a/bsnes/sfc/chip/epsonrtc/epsonrtc.hpp b/higan/sfc/chip/epsonrtc/epsonrtc.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/sfc/chip/epsonrtc/epsonrtc.hpp rename to higan/sfc/chip/epsonrtc/epsonrtc.hpp diff --git a/bsnes/sfc/chip/epsonrtc/memory.cpp b/higan/sfc/chip/epsonrtc/memory.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/sfc/chip/epsonrtc/memory.cpp rename to higan/sfc/chip/epsonrtc/memory.cpp diff --git a/bsnes/sfc/chip/epsonrtc/serialization.cpp b/higan/sfc/chip/epsonrtc/serialization.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/sfc/chip/epsonrtc/serialization.cpp rename to higan/sfc/chip/epsonrtc/serialization.cpp diff --git a/bsnes/sfc/chip/epsonrtc/time.cpp b/higan/sfc/chip/epsonrtc/time.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/sfc/chip/epsonrtc/time.cpp rename to higan/sfc/chip/epsonrtc/time.cpp diff --git a/bsnes/sfc/chip/hitachidsp/hitachidsp.cpp b/higan/sfc/chip/hitachidsp/hitachidsp.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/sfc/chip/hitachidsp/hitachidsp.cpp rename to higan/sfc/chip/hitachidsp/hitachidsp.cpp diff --git a/bsnes/sfc/chip/hitachidsp/hitachidsp.hpp b/higan/sfc/chip/hitachidsp/hitachidsp.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/sfc/chip/hitachidsp/hitachidsp.hpp rename to higan/sfc/chip/hitachidsp/hitachidsp.hpp diff --git a/bsnes/sfc/chip/hitachidsp/memory.cpp b/higan/sfc/chip/hitachidsp/memory.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/sfc/chip/hitachidsp/memory.cpp rename to higan/sfc/chip/hitachidsp/memory.cpp diff --git a/bsnes/sfc/chip/hitachidsp/mmio.hpp b/higan/sfc/chip/hitachidsp/mmio.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/sfc/chip/hitachidsp/mmio.hpp rename to higan/sfc/chip/hitachidsp/mmio.hpp diff --git a/bsnes/sfc/chip/hitachidsp/serialization.cpp b/higan/sfc/chip/hitachidsp/serialization.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/sfc/chip/hitachidsp/serialization.cpp rename to higan/sfc/chip/hitachidsp/serialization.cpp diff --git a/bsnes/sfc/chip/icd2/icd2.cpp b/higan/sfc/chip/icd2/icd2.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/sfc/chip/icd2/icd2.cpp rename to higan/sfc/chip/icd2/icd2.cpp diff --git a/bsnes/sfc/chip/icd2/icd2.hpp b/higan/sfc/chip/icd2/icd2.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/sfc/chip/icd2/icd2.hpp rename to higan/sfc/chip/icd2/icd2.hpp diff --git a/bsnes/sfc/chip/icd2/interface/interface.cpp b/higan/sfc/chip/icd2/interface/interface.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/sfc/chip/icd2/interface/interface.cpp rename to higan/sfc/chip/icd2/interface/interface.cpp diff --git a/bsnes/sfc/chip/icd2/interface/interface.hpp b/higan/sfc/chip/icd2/interface/interface.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/sfc/chip/icd2/interface/interface.hpp rename to higan/sfc/chip/icd2/interface/interface.hpp diff --git a/bsnes/sfc/chip/icd2/mmio/mmio.cpp b/higan/sfc/chip/icd2/mmio/mmio.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/sfc/chip/icd2/mmio/mmio.cpp rename to higan/sfc/chip/icd2/mmio/mmio.cpp diff --git a/bsnes/sfc/chip/icd2/mmio/mmio.hpp b/higan/sfc/chip/icd2/mmio/mmio.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/sfc/chip/icd2/mmio/mmio.hpp rename to higan/sfc/chip/icd2/mmio/mmio.hpp diff --git a/bsnes/sfc/chip/icd2/serialization.cpp b/higan/sfc/chip/icd2/serialization.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/sfc/chip/icd2/serialization.cpp rename to higan/sfc/chip/icd2/serialization.cpp diff --git a/bsnes/sfc/chip/msu1/msu1.cpp b/higan/sfc/chip/msu1/msu1.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/sfc/chip/msu1/msu1.cpp rename to higan/sfc/chip/msu1/msu1.cpp diff --git a/bsnes/sfc/chip/msu1/msu1.hpp b/higan/sfc/chip/msu1/msu1.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/sfc/chip/msu1/msu1.hpp rename to higan/sfc/chip/msu1/msu1.hpp diff --git a/bsnes/sfc/chip/msu1/serialization.cpp b/higan/sfc/chip/msu1/serialization.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/sfc/chip/msu1/serialization.cpp rename to higan/sfc/chip/msu1/serialization.cpp diff --git a/bsnes/sfc/chip/necdsp/necdsp.cpp b/higan/sfc/chip/necdsp/necdsp.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/sfc/chip/necdsp/necdsp.cpp rename to higan/sfc/chip/necdsp/necdsp.cpp diff --git a/bsnes/sfc/chip/necdsp/necdsp.hpp b/higan/sfc/chip/necdsp/necdsp.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/sfc/chip/necdsp/necdsp.hpp rename to higan/sfc/chip/necdsp/necdsp.hpp diff --git a/bsnes/sfc/chip/necdsp/serialization.cpp b/higan/sfc/chip/necdsp/serialization.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/sfc/chip/necdsp/serialization.cpp rename to higan/sfc/chip/necdsp/serialization.cpp diff --git a/bsnes/sfc/chip/nss/nss.cpp b/higan/sfc/chip/nss/nss.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/sfc/chip/nss/nss.cpp rename to higan/sfc/chip/nss/nss.cpp diff --git a/bsnes/sfc/chip/nss/nss.hpp b/higan/sfc/chip/nss/nss.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/sfc/chip/nss/nss.hpp rename to higan/sfc/chip/nss/nss.hpp diff --git a/bsnes/sfc/chip/obc1/obc1.cpp b/higan/sfc/chip/obc1/obc1.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/sfc/chip/obc1/obc1.cpp rename to higan/sfc/chip/obc1/obc1.cpp diff --git a/bsnes/sfc/chip/obc1/obc1.hpp b/higan/sfc/chip/obc1/obc1.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/sfc/chip/obc1/obc1.hpp rename to higan/sfc/chip/obc1/obc1.hpp diff --git a/bsnes/sfc/chip/obc1/serialization.cpp b/higan/sfc/chip/obc1/serialization.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/sfc/chip/obc1/serialization.cpp rename to higan/sfc/chip/obc1/serialization.cpp diff --git a/bsnes/sfc/chip/sa1/bus/bus.cpp b/higan/sfc/chip/sa1/bus/bus.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/sfc/chip/sa1/bus/bus.cpp rename to higan/sfc/chip/sa1/bus/bus.cpp diff --git a/bsnes/sfc/chip/sa1/bus/bus.hpp b/higan/sfc/chip/sa1/bus/bus.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/sfc/chip/sa1/bus/bus.hpp rename to higan/sfc/chip/sa1/bus/bus.hpp diff --git a/bsnes/sfc/chip/sa1/dma/dma.cpp b/higan/sfc/chip/sa1/dma/dma.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/sfc/chip/sa1/dma/dma.cpp rename to higan/sfc/chip/sa1/dma/dma.cpp diff --git a/bsnes/sfc/chip/sa1/dma/dma.hpp b/higan/sfc/chip/sa1/dma/dma.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/sfc/chip/sa1/dma/dma.hpp rename to higan/sfc/chip/sa1/dma/dma.hpp diff --git a/bsnes/sfc/chip/sa1/memory/memory.cpp b/higan/sfc/chip/sa1/memory/memory.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/sfc/chip/sa1/memory/memory.cpp rename to higan/sfc/chip/sa1/memory/memory.cpp diff --git a/bsnes/sfc/chip/sa1/memory/memory.hpp b/higan/sfc/chip/sa1/memory/memory.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/sfc/chip/sa1/memory/memory.hpp rename to higan/sfc/chip/sa1/memory/memory.hpp diff --git a/bsnes/sfc/chip/sa1/mmio/mmio.cpp b/higan/sfc/chip/sa1/mmio/mmio.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/sfc/chip/sa1/mmio/mmio.cpp rename to higan/sfc/chip/sa1/mmio/mmio.cpp diff --git a/bsnes/sfc/chip/sa1/mmio/mmio.hpp b/higan/sfc/chip/sa1/mmio/mmio.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/sfc/chip/sa1/mmio/mmio.hpp rename to higan/sfc/chip/sa1/mmio/mmio.hpp diff --git a/bsnes/sfc/chip/sa1/sa1.cpp b/higan/sfc/chip/sa1/sa1.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/sfc/chip/sa1/sa1.cpp rename to higan/sfc/chip/sa1/sa1.cpp diff --git a/bsnes/sfc/chip/sa1/sa1.hpp b/higan/sfc/chip/sa1/sa1.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/sfc/chip/sa1/sa1.hpp rename to higan/sfc/chip/sa1/sa1.hpp diff --git a/bsnes/sfc/chip/sa1/serialization.cpp b/higan/sfc/chip/sa1/serialization.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/sfc/chip/sa1/serialization.cpp rename to higan/sfc/chip/sa1/serialization.cpp diff --git a/bsnes/sfc/chip/sdd1/decomp.cpp b/higan/sfc/chip/sdd1/decomp.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/sfc/chip/sdd1/decomp.cpp rename to higan/sfc/chip/sdd1/decomp.cpp diff --git a/bsnes/sfc/chip/sdd1/decomp.hpp b/higan/sfc/chip/sdd1/decomp.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/sfc/chip/sdd1/decomp.hpp rename to higan/sfc/chip/sdd1/decomp.hpp diff --git a/bsnes/sfc/chip/sdd1/sdd1.cpp b/higan/sfc/chip/sdd1/sdd1.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/sfc/chip/sdd1/sdd1.cpp rename to higan/sfc/chip/sdd1/sdd1.cpp diff --git a/bsnes/sfc/chip/sdd1/sdd1.hpp b/higan/sfc/chip/sdd1/sdd1.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/sfc/chip/sdd1/sdd1.hpp rename to higan/sfc/chip/sdd1/sdd1.hpp diff --git a/bsnes/sfc/chip/sdd1/serialization.cpp b/higan/sfc/chip/sdd1/serialization.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/sfc/chip/sdd1/serialization.cpp rename to higan/sfc/chip/sdd1/serialization.cpp diff --git a/bsnes/sfc/chip/sharprtc/memory.cpp b/higan/sfc/chip/sharprtc/memory.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/sfc/chip/sharprtc/memory.cpp rename to higan/sfc/chip/sharprtc/memory.cpp diff --git a/bsnes/sfc/chip/sharprtc/serialization.cpp b/higan/sfc/chip/sharprtc/serialization.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/sfc/chip/sharprtc/serialization.cpp rename to higan/sfc/chip/sharprtc/serialization.cpp diff --git a/bsnes/sfc/chip/sharprtc/sharprtc.cpp b/higan/sfc/chip/sharprtc/sharprtc.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/sfc/chip/sharprtc/sharprtc.cpp rename to higan/sfc/chip/sharprtc/sharprtc.cpp diff --git a/bsnes/sfc/chip/sharprtc/sharprtc.hpp b/higan/sfc/chip/sharprtc/sharprtc.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/sfc/chip/sharprtc/sharprtc.hpp rename to higan/sfc/chip/sharprtc/sharprtc.hpp diff --git a/bsnes/sfc/chip/sharprtc/time.cpp b/higan/sfc/chip/sharprtc/time.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/sfc/chip/sharprtc/time.cpp rename to higan/sfc/chip/sharprtc/time.cpp diff --git a/bsnes/sfc/chip/spc7110/alu.cpp b/higan/sfc/chip/spc7110/alu.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/sfc/chip/spc7110/alu.cpp rename to higan/sfc/chip/spc7110/alu.cpp diff --git a/bsnes/sfc/chip/spc7110/data.cpp b/higan/sfc/chip/spc7110/data.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/sfc/chip/spc7110/data.cpp rename to higan/sfc/chip/spc7110/data.cpp diff --git a/bsnes/sfc/chip/spc7110/dcu.cpp b/higan/sfc/chip/spc7110/dcu.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/sfc/chip/spc7110/dcu.cpp rename to higan/sfc/chip/spc7110/dcu.cpp diff --git a/bsnes/sfc/chip/spc7110/decompressor.cpp b/higan/sfc/chip/spc7110/decompressor.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/sfc/chip/spc7110/decompressor.cpp rename to higan/sfc/chip/spc7110/decompressor.cpp diff --git a/bsnes/sfc/chip/spc7110/serialization.cpp b/higan/sfc/chip/spc7110/serialization.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/sfc/chip/spc7110/serialization.cpp rename to higan/sfc/chip/spc7110/serialization.cpp diff --git a/bsnes/sfc/chip/spc7110/spc7110.cpp b/higan/sfc/chip/spc7110/spc7110.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/sfc/chip/spc7110/spc7110.cpp rename to higan/sfc/chip/spc7110/spc7110.cpp diff --git a/bsnes/sfc/chip/spc7110/spc7110.hpp b/higan/sfc/chip/spc7110/spc7110.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/sfc/chip/spc7110/spc7110.hpp rename to higan/sfc/chip/spc7110/spc7110.hpp diff --git a/bsnes/sfc/chip/sufamiturbo/serialization.cpp b/higan/sfc/chip/sufamiturbo/serialization.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/sfc/chip/sufamiturbo/serialization.cpp rename to higan/sfc/chip/sufamiturbo/serialization.cpp diff --git a/bsnes/sfc/chip/sufamiturbo/sufamiturbo.cpp b/higan/sfc/chip/sufamiturbo/sufamiturbo.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/sfc/chip/sufamiturbo/sufamiturbo.cpp rename to higan/sfc/chip/sufamiturbo/sufamiturbo.cpp diff --git a/bsnes/sfc/chip/sufamiturbo/sufamiturbo.hpp b/higan/sfc/chip/sufamiturbo/sufamiturbo.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/sfc/chip/sufamiturbo/sufamiturbo.hpp rename to higan/sfc/chip/sufamiturbo/sufamiturbo.hpp diff --git a/bsnes/sfc/chip/superfx/bus/bus.cpp b/higan/sfc/chip/superfx/bus/bus.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/sfc/chip/superfx/bus/bus.cpp rename to higan/sfc/chip/superfx/bus/bus.cpp diff --git a/bsnes/sfc/chip/superfx/bus/bus.hpp b/higan/sfc/chip/superfx/bus/bus.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/sfc/chip/superfx/bus/bus.hpp rename to higan/sfc/chip/superfx/bus/bus.hpp diff --git a/bsnes/sfc/chip/superfx/core/core.cpp b/higan/sfc/chip/superfx/core/core.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/sfc/chip/superfx/core/core.cpp rename to higan/sfc/chip/superfx/core/core.cpp diff --git a/bsnes/sfc/chip/superfx/core/core.hpp b/higan/sfc/chip/superfx/core/core.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/sfc/chip/superfx/core/core.hpp rename to higan/sfc/chip/superfx/core/core.hpp diff --git a/bsnes/sfc/chip/superfx/disasm/disasm.cpp b/higan/sfc/chip/superfx/disasm/disasm.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/sfc/chip/superfx/disasm/disasm.cpp rename to higan/sfc/chip/superfx/disasm/disasm.cpp diff --git a/bsnes/sfc/chip/superfx/disasm/disasm.hpp b/higan/sfc/chip/superfx/disasm/disasm.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/sfc/chip/superfx/disasm/disasm.hpp rename to higan/sfc/chip/superfx/disasm/disasm.hpp diff --git a/bsnes/sfc/chip/superfx/memory/memory.cpp b/higan/sfc/chip/superfx/memory/memory.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/sfc/chip/superfx/memory/memory.cpp rename to higan/sfc/chip/superfx/memory/memory.cpp diff --git a/bsnes/sfc/chip/superfx/memory/memory.hpp b/higan/sfc/chip/superfx/memory/memory.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/sfc/chip/superfx/memory/memory.hpp rename to higan/sfc/chip/superfx/memory/memory.hpp diff --git a/bsnes/sfc/chip/superfx/mmio/mmio.cpp b/higan/sfc/chip/superfx/mmio/mmio.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/sfc/chip/superfx/mmio/mmio.cpp rename to higan/sfc/chip/superfx/mmio/mmio.cpp diff --git a/bsnes/sfc/chip/superfx/mmio/mmio.hpp b/higan/sfc/chip/superfx/mmio/mmio.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/sfc/chip/superfx/mmio/mmio.hpp rename to higan/sfc/chip/superfx/mmio/mmio.hpp diff --git a/bsnes/sfc/chip/superfx/serialization.cpp b/higan/sfc/chip/superfx/serialization.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/sfc/chip/superfx/serialization.cpp rename to higan/sfc/chip/superfx/serialization.cpp diff --git a/bsnes/sfc/chip/superfx/superfx.cpp b/higan/sfc/chip/superfx/superfx.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/sfc/chip/superfx/superfx.cpp rename to higan/sfc/chip/superfx/superfx.cpp diff --git a/bsnes/sfc/chip/superfx/superfx.hpp b/higan/sfc/chip/superfx/superfx.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/sfc/chip/superfx/superfx.hpp rename to higan/sfc/chip/superfx/superfx.hpp diff --git a/bsnes/sfc/chip/superfx/timing/timing.cpp b/higan/sfc/chip/superfx/timing/timing.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/sfc/chip/superfx/timing/timing.cpp rename to higan/sfc/chip/superfx/timing/timing.cpp diff --git a/bsnes/sfc/chip/superfx/timing/timing.hpp b/higan/sfc/chip/superfx/timing/timing.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/sfc/chip/superfx/timing/timing.hpp rename to higan/sfc/chip/superfx/timing/timing.hpp diff --git a/bsnes/sfc/config/config.cpp b/higan/sfc/config/config.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/sfc/config/config.cpp rename to higan/sfc/config/config.cpp diff --git a/bsnes/sfc/config/config.hpp b/higan/sfc/config/config.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/sfc/config/config.hpp rename to higan/sfc/config/config.hpp diff --git a/bsnes/sfc/controller/controller.cpp b/higan/sfc/controller/controller.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/sfc/controller/controller.cpp rename to higan/sfc/controller/controller.cpp diff --git a/bsnes/sfc/controller/controller.hpp b/higan/sfc/controller/controller.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/sfc/controller/controller.hpp rename to higan/sfc/controller/controller.hpp diff --git a/bsnes/sfc/controller/gamepad/gamepad.cpp b/higan/sfc/controller/gamepad/gamepad.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/sfc/controller/gamepad/gamepad.cpp rename to higan/sfc/controller/gamepad/gamepad.cpp diff --git a/bsnes/sfc/controller/gamepad/gamepad.hpp b/higan/sfc/controller/gamepad/gamepad.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/sfc/controller/gamepad/gamepad.hpp rename to higan/sfc/controller/gamepad/gamepad.hpp diff --git a/bsnes/sfc/controller/justifier/justifier.cpp b/higan/sfc/controller/justifier/justifier.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/sfc/controller/justifier/justifier.cpp rename to higan/sfc/controller/justifier/justifier.cpp diff --git a/bsnes/sfc/controller/justifier/justifier.hpp b/higan/sfc/controller/justifier/justifier.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/sfc/controller/justifier/justifier.hpp rename to higan/sfc/controller/justifier/justifier.hpp diff --git a/bsnes/sfc/controller/mouse/mouse.cpp b/higan/sfc/controller/mouse/mouse.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/sfc/controller/mouse/mouse.cpp rename to higan/sfc/controller/mouse/mouse.cpp diff --git a/bsnes/sfc/controller/mouse/mouse.hpp b/higan/sfc/controller/mouse/mouse.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/sfc/controller/mouse/mouse.hpp rename to higan/sfc/controller/mouse/mouse.hpp diff --git a/bsnes/sfc/controller/multitap/multitap.cpp b/higan/sfc/controller/multitap/multitap.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/sfc/controller/multitap/multitap.cpp rename to higan/sfc/controller/multitap/multitap.cpp diff --git a/bsnes/sfc/controller/multitap/multitap.hpp b/higan/sfc/controller/multitap/multitap.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/sfc/controller/multitap/multitap.hpp rename to higan/sfc/controller/multitap/multitap.hpp diff --git a/bsnes/sfc/controller/superscope/superscope.cpp b/higan/sfc/controller/superscope/superscope.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/sfc/controller/superscope/superscope.cpp rename to higan/sfc/controller/superscope/superscope.cpp diff --git a/bsnes/sfc/controller/superscope/superscope.hpp b/higan/sfc/controller/superscope/superscope.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/sfc/controller/superscope/superscope.hpp rename to higan/sfc/controller/superscope/superscope.hpp diff --git a/bsnes/sfc/controller/usart/usart.cpp b/higan/sfc/controller/usart/usart.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/sfc/controller/usart/usart.cpp rename to higan/sfc/controller/usart/usart.cpp diff --git a/bsnes/sfc/controller/usart/usart.hpp b/higan/sfc/controller/usart/usart.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/sfc/controller/usart/usart.hpp rename to higan/sfc/controller/usart/usart.hpp diff --git a/bsnes/sfc/cpu/cpu.cpp b/higan/sfc/cpu/cpu.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/sfc/cpu/cpu.cpp rename to higan/sfc/cpu/cpu.cpp diff --git a/bsnes/sfc/cpu/cpu.hpp b/higan/sfc/cpu/cpu.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/sfc/cpu/cpu.hpp rename to higan/sfc/cpu/cpu.hpp diff --git a/bsnes/sfc/cpu/dma/dma.cpp b/higan/sfc/cpu/dma/dma.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/sfc/cpu/dma/dma.cpp rename to higan/sfc/cpu/dma/dma.cpp diff --git a/bsnes/sfc/cpu/dma/dma.hpp b/higan/sfc/cpu/dma/dma.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/sfc/cpu/dma/dma.hpp rename to higan/sfc/cpu/dma/dma.hpp diff --git a/bsnes/sfc/cpu/memory/memory.cpp b/higan/sfc/cpu/memory/memory.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/sfc/cpu/memory/memory.cpp rename to higan/sfc/cpu/memory/memory.cpp diff --git a/bsnes/sfc/cpu/memory/memory.hpp b/higan/sfc/cpu/memory/memory.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/sfc/cpu/memory/memory.hpp rename to higan/sfc/cpu/memory/memory.hpp diff --git a/bsnes/sfc/cpu/mmio/mmio.cpp b/higan/sfc/cpu/mmio/mmio.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/sfc/cpu/mmio/mmio.cpp rename to higan/sfc/cpu/mmio/mmio.cpp diff --git a/bsnes/sfc/cpu/mmio/mmio.hpp b/higan/sfc/cpu/mmio/mmio.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/sfc/cpu/mmio/mmio.hpp rename to higan/sfc/cpu/mmio/mmio.hpp diff --git a/bsnes/sfc/cpu/serialization.cpp b/higan/sfc/cpu/serialization.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/sfc/cpu/serialization.cpp rename to higan/sfc/cpu/serialization.cpp diff --git a/bsnes/sfc/cpu/timing/irq.cpp b/higan/sfc/cpu/timing/irq.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/sfc/cpu/timing/irq.cpp rename to higan/sfc/cpu/timing/irq.cpp diff --git a/bsnes/sfc/cpu/timing/joypad.cpp b/higan/sfc/cpu/timing/joypad.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/sfc/cpu/timing/joypad.cpp rename to higan/sfc/cpu/timing/joypad.cpp diff --git a/bsnes/sfc/cpu/timing/timing.cpp b/higan/sfc/cpu/timing/timing.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/sfc/cpu/timing/timing.cpp rename to higan/sfc/cpu/timing/timing.cpp diff --git a/bsnes/sfc/cpu/timing/timing.hpp b/higan/sfc/cpu/timing/timing.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/sfc/cpu/timing/timing.hpp rename to higan/sfc/cpu/timing/timing.hpp diff --git a/bsnes/sfc/dsp/brr.cpp b/higan/sfc/dsp/brr.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/sfc/dsp/brr.cpp rename to higan/sfc/dsp/brr.cpp diff --git a/bsnes/sfc/dsp/counter.cpp b/higan/sfc/dsp/counter.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/sfc/dsp/counter.cpp rename to higan/sfc/dsp/counter.cpp diff --git a/bsnes/sfc/dsp/dsp.cpp b/higan/sfc/dsp/dsp.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/sfc/dsp/dsp.cpp rename to higan/sfc/dsp/dsp.cpp diff --git a/bsnes/sfc/dsp/dsp.hpp b/higan/sfc/dsp/dsp.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/sfc/dsp/dsp.hpp rename to higan/sfc/dsp/dsp.hpp diff --git a/bsnes/sfc/dsp/echo.cpp b/higan/sfc/dsp/echo.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/sfc/dsp/echo.cpp rename to higan/sfc/dsp/echo.cpp diff --git a/bsnes/sfc/dsp/envelope.cpp b/higan/sfc/dsp/envelope.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/sfc/dsp/envelope.cpp rename to higan/sfc/dsp/envelope.cpp diff --git a/bsnes/sfc/dsp/gaussian.cpp b/higan/sfc/dsp/gaussian.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/sfc/dsp/gaussian.cpp rename to higan/sfc/dsp/gaussian.cpp diff --git a/bsnes/sfc/dsp/misc.cpp b/higan/sfc/dsp/misc.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/sfc/dsp/misc.cpp rename to higan/sfc/dsp/misc.cpp diff --git a/bsnes/sfc/dsp/moduloarray.hpp b/higan/sfc/dsp/moduloarray.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/sfc/dsp/moduloarray.hpp rename to higan/sfc/dsp/moduloarray.hpp diff --git a/bsnes/sfc/dsp/serialization.cpp b/higan/sfc/dsp/serialization.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/sfc/dsp/serialization.cpp rename to higan/sfc/dsp/serialization.cpp diff --git a/bsnes/sfc/dsp/voice.cpp b/higan/sfc/dsp/voice.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/sfc/dsp/voice.cpp rename to higan/sfc/dsp/voice.cpp diff --git a/bsnes/sfc/interface/interface.cpp b/higan/sfc/interface/interface.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/sfc/interface/interface.cpp rename to higan/sfc/interface/interface.cpp diff --git a/bsnes/sfc/interface/interface.hpp b/higan/sfc/interface/interface.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/sfc/interface/interface.hpp rename to higan/sfc/interface/interface.hpp diff --git a/bsnes/sfc/memory/memory-inline.hpp b/higan/sfc/memory/memory-inline.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/sfc/memory/memory-inline.hpp rename to higan/sfc/memory/memory-inline.hpp diff --git a/bsnes/sfc/memory/memory.cpp b/higan/sfc/memory/memory.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/sfc/memory/memory.cpp rename to higan/sfc/memory/memory.cpp diff --git a/bsnes/sfc/memory/memory.hpp b/higan/sfc/memory/memory.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/sfc/memory/memory.hpp rename to higan/sfc/memory/memory.hpp diff --git a/bsnes/sfc/ppu/background/background.cpp b/higan/sfc/ppu/background/background.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/sfc/ppu/background/background.cpp rename to higan/sfc/ppu/background/background.cpp diff --git a/bsnes/sfc/ppu/background/background.hpp b/higan/sfc/ppu/background/background.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/sfc/ppu/background/background.hpp rename to higan/sfc/ppu/background/background.hpp diff --git a/bsnes/sfc/ppu/background/mode7.cpp b/higan/sfc/ppu/background/mode7.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/sfc/ppu/background/mode7.cpp rename to higan/sfc/ppu/background/mode7.cpp diff --git a/bsnes/sfc/ppu/counter/counter-inline.hpp b/higan/sfc/ppu/counter/counter-inline.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/sfc/ppu/counter/counter-inline.hpp rename to higan/sfc/ppu/counter/counter-inline.hpp diff --git a/bsnes/sfc/ppu/counter/counter.hpp b/higan/sfc/ppu/counter/counter.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/sfc/ppu/counter/counter.hpp rename to higan/sfc/ppu/counter/counter.hpp diff --git a/bsnes/sfc/ppu/mmio/mmio.cpp b/higan/sfc/ppu/mmio/mmio.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/sfc/ppu/mmio/mmio.cpp rename to higan/sfc/ppu/mmio/mmio.cpp diff --git a/bsnes/sfc/ppu/mmio/mmio.hpp b/higan/sfc/ppu/mmio/mmio.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/sfc/ppu/mmio/mmio.hpp rename to higan/sfc/ppu/mmio/mmio.hpp diff --git a/bsnes/sfc/ppu/ppu.cpp b/higan/sfc/ppu/ppu.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/sfc/ppu/ppu.cpp rename to higan/sfc/ppu/ppu.cpp diff --git a/bsnes/sfc/ppu/ppu.hpp b/higan/sfc/ppu/ppu.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/sfc/ppu/ppu.hpp rename to higan/sfc/ppu/ppu.hpp diff --git a/bsnes/sfc/ppu/screen/screen.cpp b/higan/sfc/ppu/screen/screen.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/sfc/ppu/screen/screen.cpp rename to higan/sfc/ppu/screen/screen.cpp diff --git a/bsnes/sfc/ppu/screen/screen.hpp b/higan/sfc/ppu/screen/screen.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/sfc/ppu/screen/screen.hpp rename to higan/sfc/ppu/screen/screen.hpp diff --git a/bsnes/sfc/ppu/serialization.cpp b/higan/sfc/ppu/serialization.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/sfc/ppu/serialization.cpp rename to higan/sfc/ppu/serialization.cpp diff --git a/bsnes/sfc/ppu/sprite/list.cpp b/higan/sfc/ppu/sprite/list.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/sfc/ppu/sprite/list.cpp rename to higan/sfc/ppu/sprite/list.cpp diff --git a/bsnes/sfc/ppu/sprite/sprite.cpp b/higan/sfc/ppu/sprite/sprite.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/sfc/ppu/sprite/sprite.cpp rename to higan/sfc/ppu/sprite/sprite.cpp diff --git a/bsnes/sfc/ppu/sprite/sprite.hpp b/higan/sfc/ppu/sprite/sprite.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/sfc/ppu/sprite/sprite.hpp rename to higan/sfc/ppu/sprite/sprite.hpp diff --git a/bsnes/sfc/ppu/window/window.cpp b/higan/sfc/ppu/window/window.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/sfc/ppu/window/window.cpp rename to higan/sfc/ppu/window/window.cpp diff --git a/bsnes/sfc/ppu/window/window.hpp b/higan/sfc/ppu/window/window.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/sfc/ppu/window/window.hpp rename to higan/sfc/ppu/window/window.hpp diff --git a/bsnes/sfc/profile-accuracy.hpp b/higan/sfc/profile-accuracy.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/sfc/profile-accuracy.hpp rename to higan/sfc/profile-accuracy.hpp diff --git a/bsnes/sfc/profile-compatibility.hpp b/higan/sfc/profile-compatibility.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/sfc/profile-compatibility.hpp rename to higan/sfc/profile-compatibility.hpp diff --git a/bsnes/sfc/profile-performance.hpp b/higan/sfc/profile-performance.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/sfc/profile-performance.hpp rename to higan/sfc/profile-performance.hpp diff --git a/bsnes/sfc/random/random.cpp b/higan/sfc/random/random.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/sfc/random/random.cpp rename to higan/sfc/random/random.cpp diff --git a/bsnes/sfc/random/random.hpp b/higan/sfc/random/random.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/sfc/random/random.hpp rename to higan/sfc/random/random.hpp diff --git a/bsnes/sfc/scheduler/scheduler.cpp b/higan/sfc/scheduler/scheduler.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/sfc/scheduler/scheduler.cpp rename to higan/sfc/scheduler/scheduler.cpp diff --git a/bsnes/sfc/scheduler/scheduler.hpp b/higan/sfc/scheduler/scheduler.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/sfc/scheduler/scheduler.hpp rename to higan/sfc/scheduler/scheduler.hpp diff --git a/bsnes/sfc/sfc.hpp b/higan/sfc/sfc.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/sfc/sfc.hpp rename to higan/sfc/sfc.hpp diff --git a/bsnes/sfc/smp/memory.cpp b/higan/sfc/smp/memory.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/sfc/smp/memory.cpp rename to higan/sfc/smp/memory.cpp diff --git a/bsnes/sfc/smp/serialization.cpp b/higan/sfc/smp/serialization.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/sfc/smp/serialization.cpp rename to higan/sfc/smp/serialization.cpp diff --git a/bsnes/sfc/smp/smp.cpp b/higan/sfc/smp/smp.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/sfc/smp/smp.cpp rename to higan/sfc/smp/smp.cpp diff --git a/bsnes/sfc/smp/smp.hpp b/higan/sfc/smp/smp.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/sfc/smp/smp.hpp rename to higan/sfc/smp/smp.hpp diff --git a/bsnes/sfc/smp/timing.cpp b/higan/sfc/smp/timing.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/sfc/smp/timing.cpp rename to higan/sfc/smp/timing.cpp diff --git a/bsnes/sfc/system/audio.cpp b/higan/sfc/system/audio.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/sfc/system/audio.cpp rename to higan/sfc/system/audio.cpp diff --git a/bsnes/sfc/system/audio.hpp b/higan/sfc/system/audio.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/sfc/system/audio.hpp rename to higan/sfc/system/audio.hpp diff --git a/bsnes/sfc/system/input.cpp b/higan/sfc/system/input.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/sfc/system/input.cpp rename to higan/sfc/system/input.cpp diff --git a/bsnes/sfc/system/input.hpp b/higan/sfc/system/input.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/sfc/system/input.hpp rename to higan/sfc/system/input.hpp diff --git a/bsnes/sfc/system/serialization.cpp b/higan/sfc/system/serialization.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/sfc/system/serialization.cpp rename to higan/sfc/system/serialization.cpp diff --git a/bsnes/sfc/system/system.cpp b/higan/sfc/system/system.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/sfc/system/system.cpp rename to higan/sfc/system/system.cpp diff --git a/bsnes/sfc/system/system.hpp b/higan/sfc/system/system.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/sfc/system/system.hpp rename to higan/sfc/system/system.hpp diff --git a/bsnes/sfc/system/video.cpp b/higan/sfc/system/video.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/sfc/system/video.cpp rename to higan/sfc/system/video.cpp diff --git a/bsnes/sfc/system/video.hpp b/higan/sfc/system/video.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/sfc/system/video.hpp rename to higan/sfc/system/video.hpp diff --git a/bsnes/target-ethos/Makefile b/higan/target-ethos/Makefile old mode 100644 new mode 100755 similarity index 98% rename from bsnes/target-ethos/Makefile rename to higan/target-ethos/Makefile index a42fcac5..b1b190ed --- a/bsnes/target-ethos/Makefile +++ b/higan/target-ethos/Makefile @@ -5,8 +5,8 @@ include fc/Makefile include sfc/Makefile include gb/Makefile include gba/Makefile -include nds/Makefile -name := bsnes +# include nds/Makefile +name := higan ui_objects := ui-ethos ui-configuration ui-interface ui-utility ui_objects += ui-input ui-window ui-general ui-settings ui-tools diff --git a/bsnes/target-ethos/bootstrap.cpp b/higan/target-ethos/bootstrap.cpp old mode 100644 new mode 100755 similarity index 84% rename from bsnes/target-ethos/bootstrap.cpp rename to higan/target-ethos/bootstrap.cpp index 93b2f1d8..4be57460 --- a/bsnes/target-ethos/bootstrap.cpp +++ b/higan/target-ethos/bootstrap.cpp @@ -2,7 +2,7 @@ #include #include #include -#include +//#include void Application::bootstrap() { interface = new Interface; @@ -11,7 +11,7 @@ void Application::bootstrap() { emulator.append(new SuperFamicom::Interface); emulator.append(new GameBoy::Interface); emulator.append(new GameBoyAdvance::Interface); - emulator.append(new NintendoDS::Interface); +//emulator.append(new NintendoDS::Interface); for(auto &system : emulator) system->bind = interface; } diff --git a/bsnes/target-ethos/configuration/configuration.cpp b/higan/target-ethos/configuration/configuration.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/target-ethos/configuration/configuration.cpp rename to higan/target-ethos/configuration/configuration.cpp diff --git a/bsnes/target-ethos/configuration/configuration.hpp b/higan/target-ethos/configuration/configuration.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/target-ethos/configuration/configuration.hpp rename to higan/target-ethos/configuration/configuration.hpp diff --git a/bsnes/target-ethos/ethos.cpp b/higan/target-ethos/ethos.cpp old mode 100644 new mode 100755 similarity index 93% rename from bsnes/target-ethos/ethos.cpp rename to higan/target-ethos/ethos.cpp index c0996637..f171e32d --- a/bsnes/target-ethos/ethos.cpp +++ b/higan/target-ethos/ethos.cpp @@ -59,7 +59,7 @@ Application::Application(int argc, char **argv) { autopause = false; basepath = dir(realpath(argv[0])); - userpath = {nall::configpath(), "bsnes/"}; + userpath = {nall::configpath(), "higan/"}; directory::create(userpath); bootstrap(); @@ -142,12 +142,6 @@ int main(int argc, char **argv) { utf8_args(argc, argv); #endif - //convert file to game folder; purify will then invoke bsnes with game folder - if(argc == 2 && !directory::exists(argv[1]) && file::exists(argv[1])) { - invoke("purify", argv[1]); - return 0; - } - new Application(argc, argv); delete application; return 0; diff --git a/bsnes/target-ethos/ethos.hpp b/higan/target-ethos/ethos.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/target-ethos/ethos.hpp rename to higan/target-ethos/ethos.hpp diff --git a/bsnes/target-ethos/general/browser.cpp b/higan/target-ethos/general/browser.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/target-ethos/general/browser.cpp rename to higan/target-ethos/general/browser.cpp diff --git a/bsnes/target-ethos/general/browser.hpp b/higan/target-ethos/general/browser.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/target-ethos/general/browser.hpp rename to higan/target-ethos/general/browser.hpp diff --git a/bsnes/target-ethos/general/dip-switches.cpp b/higan/target-ethos/general/dip-switches.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/target-ethos/general/dip-switches.cpp rename to higan/target-ethos/general/dip-switches.cpp diff --git a/bsnes/target-ethos/general/dip-switches.hpp b/higan/target-ethos/general/dip-switches.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/target-ethos/general/dip-switches.hpp rename to higan/target-ethos/general/dip-switches.hpp diff --git a/bsnes/target-ethos/general/general.cpp b/higan/target-ethos/general/general.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/target-ethos/general/general.cpp rename to higan/target-ethos/general/general.cpp diff --git a/bsnes/target-ethos/general/general.hpp b/higan/target-ethos/general/general.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/target-ethos/general/general.hpp rename to higan/target-ethos/general/general.hpp diff --git a/bsnes/target-ethos/general/presentation.cpp b/higan/target-ethos/general/presentation.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/target-ethos/general/presentation.cpp rename to higan/target-ethos/general/presentation.cpp diff --git a/bsnes/target-ethos/general/presentation.hpp b/higan/target-ethos/general/presentation.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/target-ethos/general/presentation.hpp rename to higan/target-ethos/general/presentation.hpp diff --git a/bsnes/target-ethos/input/hotkeys.cpp b/higan/target-ethos/input/hotkeys.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/target-ethos/input/hotkeys.cpp rename to higan/target-ethos/input/hotkeys.cpp diff --git a/bsnes/target-ethos/input/input.cpp b/higan/target-ethos/input/input.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/target-ethos/input/input.cpp rename to higan/target-ethos/input/input.cpp diff --git a/bsnes/target-ethos/input/input.hpp b/higan/target-ethos/input/input.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/target-ethos/input/input.hpp rename to higan/target-ethos/input/input.hpp diff --git a/bsnes/target-ethos/interface/interface.cpp b/higan/target-ethos/interface/interface.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/target-ethos/interface/interface.cpp rename to higan/target-ethos/interface/interface.cpp diff --git a/bsnes/target-ethos/interface/interface.hpp b/higan/target-ethos/interface/interface.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/target-ethos/interface/interface.hpp rename to higan/target-ethos/interface/interface.hpp diff --git a/bsnes/target-ethos/resource.rc b/higan/target-ethos/resource.rc old mode 100644 new mode 100755 similarity index 100% rename from bsnes/target-ethos/resource.rc rename to higan/target-ethos/resource.rc diff --git a/bsnes/target-ethos/resource/folder.png b/higan/target-ethos/resource/folder.png old mode 100644 new mode 100755 similarity index 100% rename from bsnes/target-ethos/resource/folder.png rename to higan/target-ethos/resource/folder.png diff --git a/bsnes/target-ethos/resource/game.png b/higan/target-ethos/resource/game.png old mode 100644 new mode 100755 similarity index 100% rename from bsnes/target-ethos/resource/game.png rename to higan/target-ethos/resource/game.png diff --git a/bsnes/target-ethos/resource/home.png b/higan/target-ethos/resource/home.png old mode 100644 new mode 100755 similarity index 100% rename from bsnes/target-ethos/resource/home.png rename to higan/target-ethos/resource/home.png diff --git a/bsnes/target-ethos/resource/resource.cpp b/higan/target-ethos/resource/resource.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/target-ethos/resource/resource.cpp rename to higan/target-ethos/resource/resource.cpp diff --git a/bsnes/target-ethos/resource/resource.hpp b/higan/target-ethos/resource/resource.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/target-ethos/resource/resource.hpp rename to higan/target-ethos/resource/resource.hpp diff --git a/bsnes/target-ethos/resource/resource.xml b/higan/target-ethos/resource/resource.xml old mode 100644 new mode 100755 similarity index 100% rename from bsnes/target-ethos/resource/resource.xml rename to higan/target-ethos/resource/resource.xml diff --git a/bsnes/target-ethos/resource/up.png b/higan/target-ethos/resource/up.png old mode 100644 new mode 100755 similarity index 100% rename from bsnes/target-ethos/resource/up.png rename to higan/target-ethos/resource/up.png diff --git a/bsnes/target-ethos/settings/audio.cpp b/higan/target-ethos/settings/audio.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/target-ethos/settings/audio.cpp rename to higan/target-ethos/settings/audio.cpp diff --git a/bsnes/target-ethos/settings/audio.hpp b/higan/target-ethos/settings/audio.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/target-ethos/settings/audio.hpp rename to higan/target-ethos/settings/audio.hpp diff --git a/bsnes/target-ethos/settings/driver.cpp b/higan/target-ethos/settings/driver.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/target-ethos/settings/driver.cpp rename to higan/target-ethos/settings/driver.cpp diff --git a/bsnes/target-ethos/settings/driver.hpp b/higan/target-ethos/settings/driver.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/target-ethos/settings/driver.hpp rename to higan/target-ethos/settings/driver.hpp diff --git a/bsnes/target-ethos/settings/hotkey.cpp b/higan/target-ethos/settings/hotkey.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/target-ethos/settings/hotkey.cpp rename to higan/target-ethos/settings/hotkey.cpp diff --git a/bsnes/target-ethos/settings/hotkey.hpp b/higan/target-ethos/settings/hotkey.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/target-ethos/settings/hotkey.hpp rename to higan/target-ethos/settings/hotkey.hpp diff --git a/bsnes/target-ethos/settings/input.cpp b/higan/target-ethos/settings/input.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/target-ethos/settings/input.cpp rename to higan/target-ethos/settings/input.cpp diff --git a/bsnes/target-ethos/settings/input.hpp b/higan/target-ethos/settings/input.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/target-ethos/settings/input.hpp rename to higan/target-ethos/settings/input.hpp diff --git a/bsnes/target-ethos/settings/settings.cpp b/higan/target-ethos/settings/settings.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/target-ethos/settings/settings.cpp rename to higan/target-ethos/settings/settings.cpp diff --git a/bsnes/target-ethos/settings/settings.hpp b/higan/target-ethos/settings/settings.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/target-ethos/settings/settings.hpp rename to higan/target-ethos/settings/settings.hpp diff --git a/bsnes/target-ethos/settings/timing.cpp b/higan/target-ethos/settings/timing.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/target-ethos/settings/timing.cpp rename to higan/target-ethos/settings/timing.cpp diff --git a/bsnes/target-ethos/settings/timing.hpp b/higan/target-ethos/settings/timing.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/target-ethos/settings/timing.hpp rename to higan/target-ethos/settings/timing.hpp diff --git a/bsnes/target-ethos/settings/video.cpp b/higan/target-ethos/settings/video.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/target-ethos/settings/video.cpp rename to higan/target-ethos/settings/video.cpp diff --git a/bsnes/target-ethos/settings/video.hpp b/higan/target-ethos/settings/video.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/target-ethos/settings/video.hpp rename to higan/target-ethos/settings/video.hpp diff --git a/bsnes/target-ethos/tools/cheat-database.cpp b/higan/target-ethos/tools/cheat-database.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/target-ethos/tools/cheat-database.cpp rename to higan/target-ethos/tools/cheat-database.cpp diff --git a/bsnes/target-ethos/tools/cheat-database.hpp b/higan/target-ethos/tools/cheat-database.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/target-ethos/tools/cheat-database.hpp rename to higan/target-ethos/tools/cheat-database.hpp diff --git a/bsnes/target-ethos/tools/cheat-editor.cpp b/higan/target-ethos/tools/cheat-editor.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/target-ethos/tools/cheat-editor.cpp rename to higan/target-ethos/tools/cheat-editor.cpp diff --git a/bsnes/target-ethos/tools/cheat-editor.hpp b/higan/target-ethos/tools/cheat-editor.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/target-ethos/tools/cheat-editor.hpp rename to higan/target-ethos/tools/cheat-editor.hpp diff --git a/bsnes/target-ethos/tools/state-manager.cpp b/higan/target-ethos/tools/state-manager.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/target-ethos/tools/state-manager.cpp rename to higan/target-ethos/tools/state-manager.cpp diff --git a/bsnes/target-ethos/tools/state-manager.hpp b/higan/target-ethos/tools/state-manager.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/target-ethos/tools/state-manager.hpp rename to higan/target-ethos/tools/state-manager.hpp diff --git a/bsnes/target-ethos/tools/tools.cpp b/higan/target-ethos/tools/tools.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/target-ethos/tools/tools.cpp rename to higan/target-ethos/tools/tools.cpp diff --git a/bsnes/target-ethos/tools/tools.hpp b/higan/target-ethos/tools/tools.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/target-ethos/tools/tools.hpp rename to higan/target-ethos/tools/tools.hpp diff --git a/bsnes/target-ethos/utility/utility.cpp b/higan/target-ethos/utility/utility.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/target-ethos/utility/utility.cpp rename to higan/target-ethos/utility/utility.cpp diff --git a/bsnes/target-ethos/utility/utility.hpp b/higan/target-ethos/utility/utility.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/target-ethos/utility/utility.hpp rename to higan/target-ethos/utility/utility.hpp diff --git a/bsnes/target-ethos/window/window.cpp b/higan/target-ethos/window/window.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/target-ethos/window/window.cpp rename to higan/target-ethos/window/window.cpp diff --git a/bsnes/target-ethos/window/window.hpp b/higan/target-ethos/window/window.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/target-ethos/window/window.hpp rename to higan/target-ethos/window/window.hpp diff --git a/bsnes/target-laevateinn/Makefile b/higan/target-laevateinn/Makefile old mode 100644 new mode 100755 similarity index 100% rename from bsnes/target-laevateinn/Makefile rename to higan/target-laevateinn/Makefile diff --git a/bsnes/target-laevateinn/base.hpp b/higan/target-laevateinn/base.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/target-laevateinn/base.hpp rename to higan/target-laevateinn/base.hpp diff --git a/bsnes/target-laevateinn/breakpoint/breakpoint.cpp b/higan/target-laevateinn/breakpoint/breakpoint.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/target-laevateinn/breakpoint/breakpoint.cpp rename to higan/target-laevateinn/breakpoint/breakpoint.cpp diff --git a/bsnes/target-laevateinn/breakpoint/breakpoint.hpp b/higan/target-laevateinn/breakpoint/breakpoint.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/target-laevateinn/breakpoint/breakpoint.hpp rename to higan/target-laevateinn/breakpoint/breakpoint.hpp diff --git a/bsnes/target-laevateinn/console/about.cpp b/higan/target-laevateinn/console/about.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/target-laevateinn/console/about.cpp rename to higan/target-laevateinn/console/about.cpp diff --git a/bsnes/target-laevateinn/console/console.cpp b/higan/target-laevateinn/console/console.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/target-laevateinn/console/console.cpp rename to higan/target-laevateinn/console/console.cpp diff --git a/bsnes/target-laevateinn/console/console.hpp b/higan/target-laevateinn/console/console.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/target-laevateinn/console/console.hpp rename to higan/target-laevateinn/console/console.hpp diff --git a/bsnes/target-laevateinn/cpu/cpu.cpp b/higan/target-laevateinn/cpu/cpu.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/target-laevateinn/cpu/cpu.cpp rename to higan/target-laevateinn/cpu/cpu.cpp diff --git a/bsnes/target-laevateinn/cpu/cpu.hpp b/higan/target-laevateinn/cpu/cpu.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/target-laevateinn/cpu/cpu.hpp rename to higan/target-laevateinn/cpu/cpu.hpp diff --git a/bsnes/target-laevateinn/cpu/registers.cpp b/higan/target-laevateinn/cpu/registers.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/target-laevateinn/cpu/registers.cpp rename to higan/target-laevateinn/cpu/registers.cpp diff --git a/bsnes/target-laevateinn/debugger/debugger.cpp b/higan/target-laevateinn/debugger/debugger.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/target-laevateinn/debugger/debugger.cpp rename to higan/target-laevateinn/debugger/debugger.cpp diff --git a/bsnes/target-laevateinn/debugger/debugger.hpp b/higan/target-laevateinn/debugger/debugger.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/target-laevateinn/debugger/debugger.hpp rename to higan/target-laevateinn/debugger/debugger.hpp diff --git a/bsnes/target-laevateinn/debugger/hook.cpp b/higan/target-laevateinn/debugger/hook.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/target-laevateinn/debugger/hook.cpp rename to higan/target-laevateinn/debugger/hook.cpp diff --git a/bsnes/target-laevateinn/debugger/usage.cpp b/higan/target-laevateinn/debugger/usage.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/target-laevateinn/debugger/usage.cpp rename to higan/target-laevateinn/debugger/usage.cpp diff --git a/bsnes/target-laevateinn/interface/interface.cpp b/higan/target-laevateinn/interface/interface.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/target-laevateinn/interface/interface.cpp rename to higan/target-laevateinn/interface/interface.cpp diff --git a/bsnes/target-laevateinn/interface/interface.hpp b/higan/target-laevateinn/interface/interface.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/target-laevateinn/interface/interface.hpp rename to higan/target-laevateinn/interface/interface.hpp diff --git a/bsnes/target-laevateinn/main.cpp b/higan/target-laevateinn/main.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/target-laevateinn/main.cpp rename to higan/target-laevateinn/main.cpp diff --git a/bsnes/target-laevateinn/memory/memory.cpp b/higan/target-laevateinn/memory/memory.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/target-laevateinn/memory/memory.cpp rename to higan/target-laevateinn/memory/memory.cpp diff --git a/bsnes/target-laevateinn/memory/memory.hpp b/higan/target-laevateinn/memory/memory.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/target-laevateinn/memory/memory.hpp rename to higan/target-laevateinn/memory/memory.hpp diff --git a/bsnes/target-laevateinn/properties/properties.cpp b/higan/target-laevateinn/properties/properties.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/target-laevateinn/properties/properties.cpp rename to higan/target-laevateinn/properties/properties.cpp diff --git a/bsnes/target-laevateinn/properties/properties.hpp b/higan/target-laevateinn/properties/properties.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/target-laevateinn/properties/properties.hpp rename to higan/target-laevateinn/properties/properties.hpp diff --git a/bsnes/target-laevateinn/resource.rc b/higan/target-laevateinn/resource.rc old mode 100644 new mode 100755 similarity index 100% rename from bsnes/target-laevateinn/resource.rc rename to higan/target-laevateinn/resource.rc diff --git a/bsnes/target-laevateinn/settings/settings.cpp b/higan/target-laevateinn/settings/settings.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/target-laevateinn/settings/settings.cpp rename to higan/target-laevateinn/settings/settings.cpp diff --git a/bsnes/target-laevateinn/settings/settings.hpp b/higan/target-laevateinn/settings/settings.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/target-laevateinn/settings/settings.hpp rename to higan/target-laevateinn/settings/settings.hpp diff --git a/bsnes/target-laevateinn/smp/registers.cpp b/higan/target-laevateinn/smp/registers.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/target-laevateinn/smp/registers.cpp rename to higan/target-laevateinn/smp/registers.cpp diff --git a/bsnes/target-laevateinn/smp/smp.cpp b/higan/target-laevateinn/smp/smp.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/target-laevateinn/smp/smp.cpp rename to higan/target-laevateinn/smp/smp.cpp diff --git a/bsnes/target-laevateinn/smp/smp.hpp b/higan/target-laevateinn/smp/smp.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/target-laevateinn/smp/smp.hpp rename to higan/target-laevateinn/smp/smp.hpp diff --git a/bsnes/target-laevateinn/tracer/tracer.cpp b/higan/target-laevateinn/tracer/tracer.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/target-laevateinn/tracer/tracer.cpp rename to higan/target-laevateinn/tracer/tracer.cpp diff --git a/bsnes/target-laevateinn/tracer/tracer.hpp b/higan/target-laevateinn/tracer/tracer.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/target-laevateinn/tracer/tracer.hpp rename to higan/target-laevateinn/tracer/tracer.hpp diff --git a/bsnes/target-laevateinn/video/video.cpp b/higan/target-laevateinn/video/video.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/target-laevateinn/video/video.cpp rename to higan/target-laevateinn/video/video.cpp diff --git a/bsnes/target-laevateinn/video/video.hpp b/higan/target-laevateinn/video/video.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/target-laevateinn/video/video.hpp rename to higan/target-laevateinn/video/video.hpp diff --git a/bsnes/target-laevateinn/vram/vram.cpp b/higan/target-laevateinn/vram/vram.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/target-laevateinn/vram/vram.cpp rename to higan/target-laevateinn/vram/vram.cpp diff --git a/bsnes/target-laevateinn/vram/vram.hpp b/higan/target-laevateinn/vram/vram.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/target-laevateinn/vram/vram.hpp rename to higan/target-laevateinn/vram/vram.hpp diff --git a/bsnes/target-laevateinn/window/window.cpp b/higan/target-laevateinn/window/window.cpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/target-laevateinn/window/window.cpp rename to higan/target-laevateinn/window/window.cpp diff --git a/bsnes/target-laevateinn/window/window.hpp b/higan/target-laevateinn/window/window.hpp old mode 100644 new mode 100755 similarity index 100% rename from bsnes/target-laevateinn/window/window.hpp rename to higan/target-laevateinn/window/window.hpp