mirror of https://github.com/bsnes-emu/bsnes.git
Update to v072r11 release.
A number of changes in this release were contributed by Cydrak in the WIP thread, who described his changes from r09/r10 thusly: - Call cpu.synchronize_coprocessor() on external R/W to avoid missing data - Sign-extend K, L before multiplying - Load IDB before ALU. Supports the MOV A, d; XOR A, A idiom which is all over the place - Use 16-bit types in flag checks (notably Z) - Flags mostly unified; hopefully at least OV0 and SGN work - Carry-in comes from the *other* accumulator's flags, this is used for long arithmetic - CMP is ~q (see the many CMP A; INC A where values get negated) - SHR1 is arithmetic shift and retains the sign bit (Mario Kart sprites and physics are broken without it) - SHL1 has carry-in per the datasheet, it doesn't seem to be used though - XCHG probably byteswaps, but it's not used either - Reversed DR external R/W order again, big-endian seems to break it byuu described the remaining changes: You do not need the XML files anymore, bsnes will automatically choose the new uPD module, and look for dsp1b.bin. If you make your own XML file, you can force the old HLE mode, or use a differently-named PROM. If and when we get the DSP-2,3,4 modules, bsnes v072.11 and above should already be able to run them, assuming no more emulation core bugs.
This commit is contained in:
parent
05526571e7
commit
9762a092d2
|
@ -408,7 +408,7 @@ SNESCartridge::SNESCartridge(const uint8_t *data, unsigned size) {
|
|||
}
|
||||
|
||||
if(has_dsp1) {
|
||||
xml << " <necdsp program='DSP-1B'>\n";
|
||||
xml << " <upd77c25 program='dsp1b.bin'>\n";
|
||||
if(dsp1_mapper == DSP1LoROM1MB) {
|
||||
xml << " <dr>\n";
|
||||
xml << " <map address='20-3f:8000-bfff'/>\n";
|
||||
|
@ -437,7 +437,7 @@ SNESCartridge::SNESCartridge(const uint8_t *data, unsigned size) {
|
|||
xml << " <map address='80-9f:7000-7fff'/>\n";
|
||||
xml << " </sr>\n";
|
||||
}
|
||||
xml << " </necdsp>\n";
|
||||
xml << " </upd77c25>\n";
|
||||
}
|
||||
|
||||
if(has_dsp2) {
|
||||
|
|
|
@ -232,9 +232,16 @@ void Cartridge::xml_parse_upd77c25(xml_element &root) {
|
|||
|
||||
foreach(attr, root.attribute) {
|
||||
if(attr.name == "program") {
|
||||
upd77c25.program = attr.content;
|
||||
} else if(attr.name == "data") {
|
||||
upd77c25.data = attr.content;
|
||||
file fp;
|
||||
if(fp.open(string(dir(basename()), attr.content), file::mode::read)) {
|
||||
for(unsigned n = 0; n < 2048; n++) {
|
||||
upd77c25.programROM[n] = fp.readm(3);
|
||||
fp.read();
|
||||
}
|
||||
for(unsigned n = 0; n < 1024; n++) {
|
||||
upd77c25.dataROM[n] = fp.readm(2);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,52 @@
|
|||
#ifdef UPD77C25_CPP
|
||||
|
||||
void UPD77C25::serialize(serializer &s) {
|
||||
s.array(dataRAM);
|
||||
|
||||
s.integer(regs.pc);
|
||||
for(unsigned n = 0; n < 4; n++) s.integer(regs.stack[n]);
|
||||
s.integer(regs.rp);
|
||||
s.integer(regs.dp);
|
||||
s.integer(regs.k);
|
||||
s.integer(regs.l);
|
||||
s.integer(regs.m);
|
||||
s.integer(regs.n);
|
||||
s.integer(regs.a);
|
||||
s.integer(regs.b);
|
||||
|
||||
s.integer(regs.flaga.s1);
|
||||
s.integer(regs.flaga.s0);
|
||||
s.integer(regs.flaga.c);
|
||||
s.integer(regs.flaga.z);
|
||||
s.integer(regs.flaga.ov1);
|
||||
s.integer(regs.flaga.ov0);
|
||||
|
||||
s.integer(regs.flagb.s1);
|
||||
s.integer(regs.flagb.s0);
|
||||
s.integer(regs.flagb.c);
|
||||
s.integer(regs.flagb.z);
|
||||
s.integer(regs.flagb.ov1);
|
||||
s.integer(regs.flagb.ov0);
|
||||
|
||||
s.integer(regs.tr);
|
||||
s.integer(regs.trb);
|
||||
|
||||
s.integer(regs.sr.rqm);
|
||||
s.integer(regs.sr.usf1);
|
||||
s.integer(regs.sr.usf0);
|
||||
s.integer(regs.sr.drs);
|
||||
s.integer(regs.sr.dma);
|
||||
s.integer(regs.sr.drc);
|
||||
s.integer(regs.sr.soc);
|
||||
s.integer(regs.sr.sic);
|
||||
s.integer(regs.sr.ei);
|
||||
s.integer(regs.sr.p1);
|
||||
s.integer(regs.sr.p0);
|
||||
|
||||
s.integer(regs.dr);
|
||||
s.integer(regs.siack);
|
||||
s.integer(regs.soack);
|
||||
s.integer(regs.idb);
|
||||
}
|
||||
|
||||
#endif
|
|
@ -7,6 +7,7 @@
|
|||
#define UPD77C25_CPP
|
||||
namespace SNES {
|
||||
|
||||
#include "serialization.cpp"
|
||||
#include "disassembler.cpp"
|
||||
|
||||
UPD77C25 upd77c25;
|
||||
|
@ -17,7 +18,9 @@ void UPD77C25::Enter() { upd77c25.enter(); }
|
|||
|
||||
void UPD77C25::enter() {
|
||||
while(true) {
|
||||
//print(disassemble(regs.pc), "\n");
|
||||
if(scheduler.sync == Scheduler::SynchronizeMode::All) {
|
||||
scheduler.exit(Scheduler::ExitReason::SynchronizeEvent);
|
||||
}
|
||||
|
||||
uint24 opcode = programROM[regs.pc++];
|
||||
switch(opcode >> 22) {
|
||||
|
@ -27,7 +30,7 @@ void UPD77C25::enter() {
|
|||
case 3: exec_ld(opcode); break;
|
||||
}
|
||||
|
||||
uint31 result = regs.k * regs.l; //sign + 30-bit result
|
||||
int32 result = (int32)regs.k * regs.l; //sign + 30-bit result
|
||||
regs.m = result >> 15; //store sign + top 15-bits
|
||||
regs.n = result << 1; //store low 15-bits + zero
|
||||
|
||||
|
@ -46,195 +49,6 @@ void UPD77C25::exec_op(uint24 opcode) {
|
|||
uint4 src = opcode >> 4; //move source
|
||||
uint4 dst = opcode >> 0; //move destination
|
||||
|
||||
unsigned p, q, r;
|
||||
Flag flag;
|
||||
|
||||
switch(pselect) {
|
||||
case 0: p = dataRAM[regs.dp]; break;
|
||||
case 1: p = regs.idb; break;
|
||||
case 2: p = regs.m; break;
|
||||
case 3: p = regs.n; break;
|
||||
}
|
||||
|
||||
switch(asl) {
|
||||
case 0: q = regs.a; flag = regs.flaga; break;
|
||||
case 1: q = regs.b; flag = regs.flagb; break;
|
||||
}
|
||||
|
||||
switch(alu) {
|
||||
case 0: { //NOP
|
||||
break;
|
||||
}
|
||||
|
||||
case 1: { //OR
|
||||
r = q | p;
|
||||
flag.s0 = r & 0x8000;
|
||||
flag.c = 0;
|
||||
flag.z = !r;
|
||||
flag.ov0 = 0;
|
||||
flag.ov1 = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
case 2: { //AND
|
||||
r = q & p;
|
||||
flag.s0 = r & 0x8000;
|
||||
flag.c = 0;
|
||||
flag.z = !r;
|
||||
flag.ov0 = 0;
|
||||
flag.ov1 = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
case 3: { //XOR
|
||||
r = q ^ p;
|
||||
flag.s0 = r & 0x8000;
|
||||
flag.c = 0;
|
||||
flag.z = !r;
|
||||
flag.ov0 = 0;
|
||||
flag.ov1 = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
case 4: { //SUB
|
||||
r = q - p;
|
||||
bool pov = (((p | q) & 0x8000) == 0x0000) && ((r & 0x8000) == 0x8000);
|
||||
bool nov = (((p & q) & 0x8000) == 0x8000) && ((r & 0x8000) == 0x0000);
|
||||
flag.s0 = r & 0x8000;
|
||||
flag.s1 = pov;
|
||||
flag.c = r > 0xffff;
|
||||
flag.z = !r;
|
||||
flag.ov0 = pov | nov;
|
||||
flag.ov1 ^= flag.ov0;
|
||||
break;
|
||||
}
|
||||
|
||||
case 5: { //ADD
|
||||
r = q + p;
|
||||
bool pov = (((p | q) & 0x8000) == 0x0000) && ((r & 0x8000) == 0x8000);
|
||||
bool nov = (((p & q) & 0x8000) == 0x8000) && ((r & 0x8000) == 0x0000);
|
||||
flag.s0 = r & 0x8000;
|
||||
flag.s1 = pov;
|
||||
flag.c = r > 0xffff;
|
||||
flag.z = !r;
|
||||
flag.ov0 = pov | nov;
|
||||
flag.ov1 ^= flag.ov0;
|
||||
break;
|
||||
}
|
||||
|
||||
case 6: { //SBB
|
||||
r = q - p - flag.c;
|
||||
bool pov = (((p | q) & 0x8000) == 0x0000) && ((r & 0x8000) == 0x8000);
|
||||
bool nov = (((p & q) & 0x8000) == 0x8000) && ((r & 0x8000) == 0x0000);
|
||||
flag.s0 = r & 0x8000;
|
||||
flag.s1 = pov;
|
||||
flag.c = r > 0xffff;
|
||||
flag.z = !r;
|
||||
flag.ov0 = pov | nov;
|
||||
flag.ov1 ^= flag.ov0;
|
||||
break;
|
||||
}
|
||||
|
||||
case 7: { //ADC
|
||||
r = q + p + flag.c;
|
||||
bool pov = (((p | q) & 0x8000) == 0x0000) && ((r & 0x8000) == 0x8000);
|
||||
bool nov = (((p & q) & 0x8000) == 0x8000) && ((r & 0x8000) == 0x0000);
|
||||
flag.s0 = r & 0x8000;
|
||||
flag.s1 = pov;
|
||||
flag.c = r > 0xffff;
|
||||
flag.z = !r;
|
||||
flag.ov0 = pov | nov;
|
||||
flag.ov1 ^= flag.ov0;
|
||||
break;
|
||||
}
|
||||
|
||||
case 8: { //DEC
|
||||
r = q - 1;
|
||||
bool pov = (((p | q) & 0x8000) == 0x0000) && ((r & 0x8000) == 0x8000);
|
||||
bool nov = (((p & q) & 0x8000) == 0x8000) && ((r & 0x8000) == 0x0000);
|
||||
flag.s0 = r & 0x8000;
|
||||
flag.s1 = pov;
|
||||
flag.c = r > 0xffff;
|
||||
flag.z = !r;
|
||||
flag.ov0 = pov | nov;
|
||||
flag.ov1 ^= flag.ov0;
|
||||
break;
|
||||
}
|
||||
|
||||
case 9: { //INC
|
||||
r = q + 1;
|
||||
bool pov = (((p | q) & 0x8000) == 0x0000) && ((r & 0x8000) == 0x8000);
|
||||
bool nov = (((p & q) & 0x8000) == 0x8000) && ((r & 0x8000) == 0x0000);
|
||||
flag.s0 = r & 0x8000;
|
||||
flag.s1 = pov;
|
||||
flag.c = r > 0xffff;
|
||||
flag.z = !r;
|
||||
flag.ov0 = pov | nov;
|
||||
flag.ov1 ^= flag.ov0;
|
||||
break;
|
||||
}
|
||||
|
||||
case 10: { //CMP (complement)
|
||||
r = ~q;
|
||||
flag.s0 = r & 0x8000;
|
||||
flag.c = 0;
|
||||
flag.z = !r;
|
||||
flag.ov0 = 0;
|
||||
flag.ov1 = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
case 11: { //SHR1
|
||||
r = q >> 1;
|
||||
flag.s0 = r & 0x8000;
|
||||
flag.c = q & 1;
|
||||
flag.z = !r;
|
||||
flag.ov0 = 0;
|
||||
flag.ov1 = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
case 12: { //SHL1
|
||||
r = q << 1;
|
||||
flag.s0 = r & 0x8000;
|
||||
flag.c = r & 0x8000;
|
||||
flag.z = !r;
|
||||
flag.ov0 = 0;
|
||||
flag.ov1 = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
case 13: { //SHL2
|
||||
r = q << 2;
|
||||
flag.s0 = r & 0x8000;
|
||||
flag.c = 0;
|
||||
flag.z = !r;
|
||||
flag.ov0 = 0;
|
||||
flag.ov1 = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
case 14: { //SHL4
|
||||
r = q << 4;
|
||||
flag.s0 = r & 0x8000;
|
||||
flag.c = 0;
|
||||
flag.z = !r;
|
||||
flag.ov0 = 0;
|
||||
flag.ov1 = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
case 15: { //XCHG
|
||||
r = (q << 8) | (q >> 8);
|
||||
flag.s0 = r & 0x8000;
|
||||
flag.c = 0;
|
||||
flag.z = !r;
|
||||
flag.ov0 = 0;
|
||||
flag.ov1 = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
switch(src) {
|
||||
case 0: regs.idb = regs.trb; break;
|
||||
case 1: regs.idb = regs.a; break;
|
||||
|
@ -243,7 +57,7 @@ void UPD77C25::exec_op(uint24 opcode) {
|
|||
case 4: regs.idb = regs.dp; break;
|
||||
case 5: regs.idb = regs.rp; break;
|
||||
case 6: regs.idb = dataROM[regs.rp]; break;
|
||||
case 7: regs.idb = regs.flaga.s1 ? 0x7fff : 0x8000; break;
|
||||
case 7: regs.idb = 0x8000 - regs.flaga.s1; break;
|
||||
case 8: regs.idb = regs.dr; regs.sr.rqm = 1; break;
|
||||
case 9: regs.idb = regs.dr; break;
|
||||
case 10: regs.idb = regs.sr; break;
|
||||
|
@ -252,36 +66,92 @@ void UPD77C25::exec_op(uint24 opcode) {
|
|||
case 13: regs.idb = regs.k; break;
|
||||
case 14: regs.idb = regs.l; break;
|
||||
case 15: regs.idb = dataRAM[regs.dp]; break;
|
||||
default: print("OP: unhandled src case ", strhex<2>(src), "\n"); break;
|
||||
}
|
||||
|
||||
switch(asl) {
|
||||
case 0: regs.a = r; regs.flaga = flag; break;
|
||||
case 1: regs.b = r; regs.flagb = flag; break;
|
||||
if(alu) {
|
||||
uint16 p, q, r;
|
||||
Flag flag;
|
||||
bool c;
|
||||
|
||||
switch(pselect) {
|
||||
case 0: p = dataRAM[regs.dp]; break;
|
||||
case 1: p = regs.idb; break;
|
||||
case 2: p = regs.m; break;
|
||||
case 3: p = regs.n; break;
|
||||
}
|
||||
|
||||
switch(asl) {
|
||||
case 0: q = regs.a; flag = regs.flaga; c = regs.flagb.c; break;
|
||||
case 1: q = regs.b; flag = regs.flagb; c = regs.flaga.c; break;
|
||||
}
|
||||
|
||||
switch(alu) {
|
||||
case 1: r = q | p; break; //OR
|
||||
case 2: r = q & p; break; //AND
|
||||
case 3: r = q ^ p; break; //XOR
|
||||
case 4: r = q - p; break; //SUB
|
||||
case 5: r = q + p; break; //ADD
|
||||
case 6: r = q - p - c; break; //SBB
|
||||
case 7: r = q + p + c; break; //ADC
|
||||
case 8: r = q - 1; p = 1; break; //DEC
|
||||
case 9: r = q + 1; p = 1; break; //INC
|
||||
case 10: r = ~q; break; //CMP
|
||||
case 11: r = (q >> 1) | (q & 0x8000); break; //SHR1 (ASR)
|
||||
case 12: r = (q << 1) | c; break; //SHL1 (ROL)
|
||||
case 13: r = (q << 2); break; //SHL2
|
||||
case 14: r = (q << 4); break; //SHL4
|
||||
case 15: r = (q << 8) | (q >> 8); break; //XCHG
|
||||
}
|
||||
|
||||
flag.s0 = (r & 0x8000);
|
||||
flag.z = (r == 0);
|
||||
|
||||
switch(alu) {
|
||||
case 1: case 2: case 3: case 10: case 13: case 14: case 15: {
|
||||
flag.c = 0;
|
||||
flag.ov0 = 0;
|
||||
flag.ov1 = 0;
|
||||
break;
|
||||
}
|
||||
case 4: case 5: case 6: case 7: case 8: case 9: {
|
||||
if(alu & 1) {
|
||||
//addition
|
||||
flag.ov0 = (q ^ r) & ~(q ^ p) & 0x8000;
|
||||
flag.c = (r < q);
|
||||
} else {
|
||||
//subtraction
|
||||
flag.ov0 = (q ^ r) & (q ^ p) & 0x8000;
|
||||
flag.c = (r > q);
|
||||
}
|
||||
if(flag.ov0) {
|
||||
flag.s1 = flag.ov1 ^ !(r & 0x8000);
|
||||
flag.ov1 = !flag.ov1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 11: {
|
||||
flag.c = q & 1;
|
||||
flag.ov0 = 0;
|
||||
flag.ov1 = 0;
|
||||
break;
|
||||
}
|
||||
case 12: {
|
||||
flag.c = q >> 15;
|
||||
flag.ov0 = 0;
|
||||
flag.ov1 = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
switch(asl) {
|
||||
case 0: regs.a = r; regs.flaga = flag; break;
|
||||
case 1: regs.b = r; regs.flagb = flag; break;
|
||||
}
|
||||
}
|
||||
|
||||
switch(dst) {
|
||||
case 0: break;
|
||||
case 1: regs.a = regs.idb; break;
|
||||
case 2: regs.b = regs.idb; break;
|
||||
case 3: regs.tr = regs.idb; break;
|
||||
case 4: regs.dp = regs.idb; break;
|
||||
case 5: regs.rp = regs.idb; break;
|
||||
case 6: regs.dr = regs.idb; regs.sr.rqm = 1; break;
|
||||
case 7: regs.sr = (regs.sr & 0x9000) | (regs.idb & ~0x9000); break;
|
||||
//case 8: regs.sol = regs.idb; break;
|
||||
//case 9: regs.som = regs.idb; break;
|
||||
case 10: regs.k = regs.idb; break;
|
||||
case 11: regs.k = regs.idb; regs.l = dataROM[regs.rp]; break;
|
||||
case 12: regs.k = dataRAM[regs.dp | 0x40]; regs.l = regs.idb; break;
|
||||
case 13: regs.l = regs.idb; break;
|
||||
case 14: regs.trb = regs.idb; break;
|
||||
case 15: dataRAM[regs.dp] = regs.idb; break;
|
||||
default: print("OP: unhandled dst case ", strhex<2>(dst), "\n"); break;
|
||||
}
|
||||
exec_ld((regs.idb << 6) + dst);
|
||||
|
||||
switch(dpl) {
|
||||
case 0: break; //DPNOP
|
||||
case 1: regs.dp = (regs.dp & 0xf0) + ((regs.dp + 1) & 0x0f); break; //DPINC
|
||||
case 2: regs.dp = (regs.dp & 0xf0) + ((regs.dp - 1) & 0x0f); break; //DPDEC
|
||||
case 3: regs.dp = (regs.dp & 0xf0); break; //DPCLR
|
||||
|
@ -289,10 +159,7 @@ void UPD77C25::exec_op(uint24 opcode) {
|
|||
|
||||
regs.dp ^= dphm << 4;
|
||||
|
||||
switch(rpdcr) {
|
||||
case 0: break; //RPNOP
|
||||
case 1: regs.rp--; break; //RPDEC
|
||||
}
|
||||
if(rpdcr) regs.rp--;
|
||||
}
|
||||
|
||||
void UPD77C25::exec_rt(uint24 opcode) {
|
||||
|
@ -357,6 +224,8 @@ void UPD77C25::exec_ld(uint24 opcode) {
|
|||
uint16 id = opcode >> 6; //immediate data
|
||||
uint4 dst = opcode >> 0; //destination
|
||||
|
||||
regs.idb = id;
|
||||
|
||||
switch(dst) {
|
||||
case 0: break;
|
||||
case 1: regs.a = id; break;
|
||||
|
@ -365,16 +234,15 @@ void UPD77C25::exec_ld(uint24 opcode) {
|
|||
case 4: regs.dp = id; break;
|
||||
case 5: regs.rp = id; break;
|
||||
case 6: regs.dr = id; regs.sr.rqm = 1; break;
|
||||
case 7: regs.sr = (regs.sr & 0x9000) | (id & ~0x9000); break;
|
||||
case 7: regs.sr = (regs.sr & 0x907c) | (id & ~0x907c); break;
|
||||
//case 8: regs.sol = id; break;
|
||||
//case 9: regs.som = id; break;
|
||||
case 10: regs.k = id; break;
|
||||
case 11: regs.k = regs.idb; regs.l = dataROM[regs.rp]; break;
|
||||
case 12: regs.k = dataRAM[regs.dp | 0x40]; regs.l = regs.idb; break;
|
||||
case 11: regs.k = id; regs.l = dataROM[regs.rp]; break;
|
||||
case 12: regs.l = id; regs.k = dataRAM[regs.dp | 0x40]; break;
|
||||
case 13: regs.l = id; break;
|
||||
case 14: regs.trb = id; break;
|
||||
case 15: dataRAM[regs.dp] = id; break;
|
||||
default: print("LD: unhandled dst case ", strhex<2>(dst), "\n"); break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -394,42 +262,44 @@ void UPD77C25::stack_pull() {
|
|||
}
|
||||
|
||||
uint8 UPD77C25::read(bool mode) {
|
||||
if(mode == 0) return (unsigned)regs.sr >> 8;
|
||||
cpu.synchronize_coprocessor();
|
||||
if(mode == 0) return regs.sr >> 8;
|
||||
|
||||
if(regs.sr.drc == 0) {
|
||||
//16-bit
|
||||
if(regs.sr.drs == 0) {
|
||||
regs.sr.drs = 1;
|
||||
return regs.dr >> 8;
|
||||
return regs.dr >> 0;
|
||||
} else {
|
||||
regs.sr.rqm = 0;
|
||||
regs.sr.drs = 0;
|
||||
return regs.dr >> 0;
|
||||
return regs.dr >> 8;
|
||||
}
|
||||
} else {
|
||||
//8-bit
|
||||
regs.sr.rqm = 0;
|
||||
return regs.dr;
|
||||
return regs.dr >> 0;
|
||||
}
|
||||
}
|
||||
|
||||
void UPD77C25::write(bool mode, uint8 data) {
|
||||
cpu.synchronize_coprocessor();
|
||||
if(mode == 0) return;
|
||||
|
||||
if(regs.sr.drc == 0) {
|
||||
//16-bit
|
||||
if(regs.sr.drs == 0) {
|
||||
regs.sr.drs = 1;
|
||||
regs.dr = (data << 8) | (regs.dr & 0x00ff);
|
||||
regs.dr = (regs.dr & 0xff00) | (data << 0);
|
||||
} else {
|
||||
regs.sr.rqm = 0;
|
||||
regs.sr.drs = 0;
|
||||
regs.dr = (regs.dr & 0xff00) | (data << 0);
|
||||
regs.dr = (data << 8) | (regs.dr & 0x00ff);
|
||||
}
|
||||
} else {
|
||||
//8-bit
|
||||
regs.sr.rqm = 0;
|
||||
regs.dr = data;
|
||||
regs.dr = (regs.dr & 0xff00) | (data << 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -440,43 +310,7 @@ void UPD77C25::enable() {
|
|||
}
|
||||
|
||||
void UPD77C25::power() {
|
||||
for(unsigned i = 0; i < 2048; i++) programROM[i] = 0x000000;
|
||||
for(unsigned i = 0; i < 1024; i++) dataROM[i] = 0x0000;
|
||||
for(unsigned i = 0; i < 256; i++) dataRAM[i] = 0x0000;
|
||||
|
||||
string filename;
|
||||
file fp;
|
||||
|
||||
filename = string(dir(cartridge.basename()), program);
|
||||
if(fp.open(filename, file::mode::read)) {
|
||||
for(unsigned i = 0; i < 2048; i++) {
|
||||
programROM[i] |= fp.read() << 16;
|
||||
programROM[i] |= fp.read() << 8;
|
||||
programROM[i] |= fp.read() << 0;
|
||||
fp.read(); //skip 24-bit -> 32-bit padding
|
||||
}
|
||||
fp.close();
|
||||
}
|
||||
|
||||
filename = string(dir(cartridge.basename()), data);
|
||||
if(fp.open(filename, file::mode::read)) {
|
||||
for(unsigned i = 0; i < 1024; i++) {
|
||||
dataROM[i] |= fp.read() << 8;
|
||||
dataROM[i] |= fp.read() << 0;
|
||||
}
|
||||
fp.close();
|
||||
}
|
||||
|
||||
#if 0
|
||||
fp.open("/home/byuu/Desktop/disassembly.txt", file::mode::write);
|
||||
for(unsigned i = 0; i < 2048; i++) {
|
||||
string output = disassemble(i);
|
||||
fp.print(output);
|
||||
fp.print("\n");
|
||||
}
|
||||
fp.close();
|
||||
#endif
|
||||
|
||||
reset();
|
||||
}
|
||||
|
||||
|
|
|
@ -7,16 +7,15 @@ public:
|
|||
void power();
|
||||
void reset();
|
||||
|
||||
string disassemble(uint11 ip);
|
||||
void serialize(serializer &s);
|
||||
|
||||
string program;
|
||||
string data;
|
||||
|
||||
private:
|
||||
uint24 programROM[2048];
|
||||
uint16 dataROM[1024];
|
||||
uint16 dataRAM[256];
|
||||
|
||||
string disassemble(uint11 ip);
|
||||
|
||||
private:
|
||||
struct Flag {
|
||||
bool s1, s0, c, z, ov1, ov0;
|
||||
|
||||
|
@ -52,16 +51,16 @@ private:
|
|||
uint11 stack[4]; //LIFO
|
||||
uint10 rp; //ROM pointer
|
||||
uint8 dp; //data pointer
|
||||
uint16 k;
|
||||
uint16 l;
|
||||
uint16 m;
|
||||
uint16 n;
|
||||
uint16 a; //accumulator
|
||||
uint16 b; //accumulator
|
||||
int16 k;
|
||||
int16 l;
|
||||
int16 m;
|
||||
int16 n;
|
||||
int16 a; //accumulator
|
||||
int16 b; //accumulator
|
||||
Flag flaga;
|
||||
Flag flagb;
|
||||
uint16 tr; //temporary registers
|
||||
uint16 trb;
|
||||
uint16 tr; //temporary register
|
||||
uint16 trb; //temporary register
|
||||
Status sr; //status register
|
||||
uint16 dr; //data register
|
||||
bool siack;
|
||||
|
@ -73,8 +72,10 @@ private:
|
|||
void exec_rt(uint24 opcode);
|
||||
void exec_jp(uint24 opcode);
|
||||
void exec_ld(uint24 opcode);
|
||||
|
||||
void stack_push();
|
||||
void stack_pull();
|
||||
|
||||
uint8 read(bool mode);
|
||||
void write(bool mode, uint8 data);
|
||||
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
namespace SNES {
|
||||
namespace Info {
|
||||
static const char Name[] = "bsnes";
|
||||
static const char Version[] = "072.10";
|
||||
static const char Version[] = "072.11";
|
||||
static const unsigned SerializerVersion = 14;
|
||||
}
|
||||
}
|
||||
|
||||
#define DEBUGGER
|
||||
//#define DEBUGGER
|
||||
#define CHEAT_SYSTEM
|
||||
|
||||
#include <libco/libco.h>
|
||||
|
|
|
@ -60,6 +60,7 @@ void System::serialize_all(serializer &s) {
|
|||
if(cartridge.mode() == Cartridge::Mode::SuperGameBoy) supergameboy.serialize(s);
|
||||
if(cartridge.has_superfx()) superfx.serialize(s);
|
||||
if(cartridge.has_sa1()) sa1.serialize(s);
|
||||
if(cartridge.has_upd77c25()) upd77c25.serialize(s);
|
||||
if(cartridge.has_srtc()) srtc.serialize(s);
|
||||
if(cartridge.has_sdd1()) sdd1.serialize(s);
|
||||
if(cartridge.has_spc7110()) spc7110.serialize(s);
|
||||
|
|
|
@ -217,6 +217,7 @@ void System::reset() {
|
|||
if(cartridge.mode() == Cartridge::Mode::SuperGameBoy) cpu.coprocessors.append(&supergameboy);
|
||||
if(cartridge.has_superfx()) cpu.coprocessors.append(&superfx);
|
||||
if(cartridge.has_sa1()) cpu.coprocessors.append(&sa1);
|
||||
if(cartridge.has_upd77c25()) cpu.coprocessors.append(&upd77c25);
|
||||
if(cartridge.has_msu1()) cpu.coprocessors.append(&msu1);
|
||||
if(cartridge.has_serial()) cpu.coprocessors.append(&serial);
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@ Cartridge cartridge;
|
|||
bool Cartridge::loadNormal(const char *basename) {
|
||||
unload();
|
||||
if(loadCartridge(SNES::memory::cartrom, baseXML, basename) == false) return false;
|
||||
baseName = nall::basename(basename);
|
||||
SNES::cartridge.basename = baseName = nall::basename(basename);
|
||||
SNES::cartridge.load(SNES::Cartridge::Mode::Normal, { baseXML });
|
||||
loadMemory(SNES::memory::cartram, baseName, ".srm");
|
||||
loadMemory(SNES::memory::cartrtc, baseName, ".rtc");
|
||||
|
@ -16,7 +16,7 @@ bool Cartridge::loadBsxSlotted(const char *basename, const char *slotname) {
|
|||
unload();
|
||||
if(loadCartridge(SNES::memory::cartrom, baseXML, basename) == false) return false;
|
||||
loadCartridge(SNES::memory::bsxflash, slotAXML, slotname);
|
||||
baseName = nall::basename(basename);
|
||||
SNES::cartridge.basename = baseName = nall::basename(basename);
|
||||
slotAName = nall::basename(slotname);
|
||||
SNES::cartridge.load(SNES::Cartridge::Mode::BsxSlotted, { baseXML, slotAXML });
|
||||
loadMemory(SNES::memory::cartram, baseName, ".srm");
|
||||
|
@ -29,7 +29,7 @@ bool Cartridge::loadBsx(const char *basename, const char *slotname) {
|
|||
unload();
|
||||
if(loadCartridge(SNES::memory::cartrom, baseXML, basename) == false) return false;
|
||||
loadCartridge(SNES::memory::bsxflash, slotAXML, slotname);
|
||||
baseName = nall::basename(basename);
|
||||
SNES::cartridge.basename = baseName = nall::basename(basename);
|
||||
slotAName = nall::basename(slotname);
|
||||
SNES::cartridge.load(SNES::Cartridge::Mode::Bsx, { baseXML, slotAXML });
|
||||
loadMemory(SNES::memory::bsxram, baseName, ".srm");
|
||||
|
@ -43,7 +43,7 @@ bool Cartridge::loadSufamiTurbo(const char *basename, const char *slotAname, con
|
|||
if(loadCartridge(SNES::memory::cartrom, baseXML, basename) == false) return false;
|
||||
loadCartridge(SNES::memory::stArom, slotAXML, slotAname);
|
||||
loadCartridge(SNES::memory::stBrom, slotBXML, slotBname);
|
||||
baseName = nall::basename(basename);
|
||||
SNES::cartridge.basename = baseName = nall::basename(basename);
|
||||
slotAName = nall::basename(slotAname);
|
||||
slotBName = nall::basename(slotBname);
|
||||
SNES::cartridge.load(SNES::Cartridge::Mode::SufamiTurbo, { baseXML, slotAXML, slotBXML });
|
||||
|
@ -57,7 +57,7 @@ bool Cartridge::loadSuperGameBoy(const char *basename, const char *slotname) {
|
|||
unload();
|
||||
if(loadCartridge(SNES::memory::cartrom, baseXML, basename) == false) return false;
|
||||
loadCartridge(SNES::memory::gbrom, slotAXML, slotname);
|
||||
baseName = nall::basename(basename);
|
||||
SNES::cartridge.basename = baseName = nall::basename(basename);
|
||||
slotAName = nall::basename(slotname);
|
||||
SNES::cartridge.load(SNES::Cartridge::Mode::SuperGameBoy, { baseXML, slotAXML });
|
||||
loadMemory(SNES::memory::gbram, slotAName, ".sav");
|
||||
|
|
|
@ -92,7 +92,6 @@ void Utility::setShader() {
|
|||
}
|
||||
|
||||
void Utility::cartridgeLoaded() {
|
||||
SNES::cartridge.basename = cartridge.baseName;
|
||||
SNES::system.power();
|
||||
cheatEditor.load(cartridge.baseName);
|
||||
stateManager.load();
|
||||
|
|
Loading…
Reference in New Issue