mirror of https://github.com/bsnes-emu/bsnes.git
Update to v097r23 release.
byuu says: Changelog: - emulated SuperDisc $21e1 basic interface (NEC 4-bit MCU); all hardware tests pass now (but they don't test much) - WS/V30MZ: fixed inc/dec reg flag calculation - WS/V30MZ: fixed lds/les instructions WS/C compatibility should be way up now. SuperDisc BIOS passes all tests now (but they only test for the presence of the interface, nothing more.)
This commit is contained in:
parent
3d3ac8c1db
commit
79e7e6ab9e
|
@ -6,7 +6,7 @@ using namespace nall;
|
|||
|
||||
namespace Emulator {
|
||||
static const string Name = "higan";
|
||||
static const string Version = "097.22";
|
||||
static const string Version = "097.23";
|
||||
static const string Author = "byuu";
|
||||
static const string License = "GPLv3";
|
||||
static const string Website = "http://byuu.org/";
|
||||
|
|
|
@ -148,7 +148,7 @@ auto R65816::disassemble_opcode(char* output, uint32 addr, bool e, bool m, bool
|
|||
case 0x0d: sprintf(t, "ora $%.4x [%.6x]", op16, decode(OPTYPE_ADDR, op16)); break;
|
||||
case 0x0e: sprintf(t, "asl $%.4x [%.6x]", op16, decode(OPTYPE_ADDR, op16)); break;
|
||||
case 0x0f: sprintf(t, "ora $%.6x [%.6x]", op24, decode(OPTYPE_LONG, op24)); break;
|
||||
case 0x10: sprintf(t, "bpl $%.4x [%.6x]", uint16(decode(OPTYPE_RELB, op8)), decode(OPTYPE_RELB, op8)); break;
|
||||
case 0x10: sprintf(t, "bpl $%.4x [%.6x]", uint16_t(decode(OPTYPE_RELB, op8)), decode(OPTYPE_RELB, op8)); break;
|
||||
case 0x11: sprintf(t, "ora ($%.2x),y [%.6x]", op8, decode(OPTYPE_IDPY, op8)); break;
|
||||
case 0x12: sprintf(t, "ora ($%.2x) [%.6x]", op8, decode(OPTYPE_IDP, op8)); break;
|
||||
case 0x13: sprintf(t, "ora ($%.2x,s),y [%.6x]", op8, decode(OPTYPE_ISRY, op8)); break;
|
||||
|
@ -181,7 +181,7 @@ auto R65816::disassemble_opcode(char* output, uint32 addr, bool e, bool m, bool
|
|||
case 0x2d: sprintf(t, "and $%.4x [%.6x]", op16, decode(OPTYPE_ADDR, op16)); break;
|
||||
case 0x2e: sprintf(t, "rol $%.4x [%.6x]", op16, decode(OPTYPE_ADDR, op16)); break;
|
||||
case 0x2f: sprintf(t, "and $%.6x [%.6x]", op24, decode(OPTYPE_LONG, op24)); break;
|
||||
case 0x30: sprintf(t, "bmi $%.4x [%.6x]", uint16(decode(OPTYPE_RELB, op8)), decode(OPTYPE_RELB, op8)); break;
|
||||
case 0x30: sprintf(t, "bmi $%.4x [%.6x]", uint16_t(decode(OPTYPE_RELB, op8)), decode(OPTYPE_RELB, op8)); break;
|
||||
case 0x31: sprintf(t, "and ($%.2x),y [%.6x]", op8, decode(OPTYPE_IDPY, op8)); break;
|
||||
case 0x32: sprintf(t, "and ($%.2x) [%.6x]", op8, decode(OPTYPE_IDP, op8)); break;
|
||||
case 0x33: sprintf(t, "and ($%.2x,s),y [%.6x]", op8, decode(OPTYPE_ISRY, op8)); break;
|
||||
|
@ -214,7 +214,7 @@ auto R65816::disassemble_opcode(char* output, uint32 addr, bool e, bool m, bool
|
|||
case 0x4d: sprintf(t, "eor $%.4x [%.6x]", op16, decode(OPTYPE_ADDR, op16)); break;
|
||||
case 0x4e: sprintf(t, "lsr $%.4x [%.6x]", op16, decode(OPTYPE_ADDR, op16)); break;
|
||||
case 0x4f: sprintf(t, "eor $%.6x [%.6x]", op24, decode(OPTYPE_LONG, op24)); break;
|
||||
case 0x50: sprintf(t, "bvc $%.4x [%.6x]", uint16(decode(OPTYPE_RELB, op8)), decode(OPTYPE_RELB, op8)); break;
|
||||
case 0x50: sprintf(t, "bvc $%.4x [%.6x]", uint16_t(decode(OPTYPE_RELB, op8)), decode(OPTYPE_RELB, op8)); break;
|
||||
case 0x51: sprintf(t, "eor ($%.2x),y [%.6x]", op8, decode(OPTYPE_IDPY, op8)); break;
|
||||
case 0x52: sprintf(t, "eor ($%.2x) [%.6x]", op8, decode(OPTYPE_IDP, op8)); break;
|
||||
case 0x53: sprintf(t, "eor ($%.2x,s),y [%.6x]", op8, decode(OPTYPE_ISRY, op8)); break;
|
||||
|
@ -247,7 +247,7 @@ auto R65816::disassemble_opcode(char* output, uint32 addr, bool e, bool m, bool
|
|||
case 0x6d: sprintf(t, "adc $%.4x [%.6x]", op16, decode(OPTYPE_ADDR, op16)); break;
|
||||
case 0x6e: sprintf(t, "ror $%.4x [%.6x]", op16, decode(OPTYPE_ADDR, op16)); break;
|
||||
case 0x6f: sprintf(t, "adc $%.6x [%.6x]", op24, decode(OPTYPE_LONG, op24)); break;
|
||||
case 0x70: sprintf(t, "bvs $%.4x [%.6x]", uint16(decode(OPTYPE_RELB, op8)), decode(OPTYPE_RELB, op8)); break;
|
||||
case 0x70: sprintf(t, "bvs $%.4x [%.6x]", uint16_t(decode(OPTYPE_RELB, op8)), decode(OPTYPE_RELB, op8)); break;
|
||||
case 0x71: sprintf(t, "adc ($%.2x),y [%.6x]", op8, decode(OPTYPE_IDPY, op8)); break;
|
||||
case 0x72: sprintf(t, "adc ($%.2x) [%.6x]", op8, decode(OPTYPE_IDP, op8)); break;
|
||||
case 0x73: sprintf(t, "adc ($%.2x,s),y [%.6x]", op8, decode(OPTYPE_ISRY, op8)); break;
|
||||
|
@ -263,9 +263,9 @@ auto R65816::disassemble_opcode(char* output, uint32 addr, bool e, bool m, bool
|
|||
case 0x7d: sprintf(t, "adc $%.4x,x [%.6x]", op16, decode(OPTYPE_ADDRX, op16)); break;
|
||||
case 0x7e: sprintf(t, "ror $%.4x,x [%.6x]", op16, decode(OPTYPE_ADDRX, op16)); break;
|
||||
case 0x7f: sprintf(t, "adc $%.6x,x [%.6x]", op24, decode(OPTYPE_LONGX, op24)); break;
|
||||
case 0x80: sprintf(t, "bra $%.4x [%.6x]", uint16(decode(OPTYPE_RELB, op8)), decode(OPTYPE_RELB, op8)); break;
|
||||
case 0x80: sprintf(t, "bra $%.4x [%.6x]", uint16_t(decode(OPTYPE_RELB, op8)), decode(OPTYPE_RELB, op8)); break;
|
||||
case 0x81: sprintf(t, "sta ($%.2x,x) [%.6x]", op8, decode(OPTYPE_IDPX, op8)); break;
|
||||
case 0x82: sprintf(t, "brl $%.4x [%.6x]", uint16(decode(OPTYPE_RELW, op16)), decode(OPTYPE_RELW, op16)); break;
|
||||
case 0x82: sprintf(t, "brl $%.4x [%.6x]", uint16_t(decode(OPTYPE_RELW, op16)), decode(OPTYPE_RELW, op16)); break;
|
||||
case 0x83: sprintf(t, "sta $%.2x,s [%.6x]", op8, decode(OPTYPE_SR, op8)); break;
|
||||
case 0x84: sprintf(t, "sty $%.2x [%.6x]", op8, decode(OPTYPE_DP, op8)); break;
|
||||
case 0x85: sprintf(t, "sta $%.2x [%.6x]", op8, decode(OPTYPE_DP, op8)); break;
|
||||
|
@ -280,7 +280,7 @@ auto R65816::disassemble_opcode(char* output, uint32 addr, bool e, bool m, bool
|
|||
case 0x8d: sprintf(t, "sta $%.4x [%.6x]", op16, decode(OPTYPE_ADDR, op16)); break;
|
||||
case 0x8e: sprintf(t, "stx $%.4x [%.6x]", op16, decode(OPTYPE_ADDR, op16)); break;
|
||||
case 0x8f: sprintf(t, "sta $%.6x [%.6x]", op24, decode(OPTYPE_LONG, op24)); break;
|
||||
case 0x90: sprintf(t, "bcc $%.4x [%.6x]", uint16(decode(OPTYPE_RELB, op8)), decode(OPTYPE_RELB, op8)); break;
|
||||
case 0x90: sprintf(t, "bcc $%.4x [%.6x]", uint16_t(decode(OPTYPE_RELB, op8)), decode(OPTYPE_RELB, op8)); break;
|
||||
case 0x91: sprintf(t, "sta ($%.2x),y [%.6x]", op8, decode(OPTYPE_IDPY, op8)); break;
|
||||
case 0x92: sprintf(t, "sta ($%.2x) [%.6x]", op8, decode(OPTYPE_IDP, op8)); break;
|
||||
case 0x93: sprintf(t, "sta ($%.2x,s),y [%.6x]", op8, decode(OPTYPE_ISRY, op8)); break;
|
||||
|
@ -315,7 +315,7 @@ auto R65816::disassemble_opcode(char* output, uint32 addr, bool e, bool m, bool
|
|||
case 0xad: sprintf(t, "lda $%.4x [%.6x]", op16, decode(OPTYPE_ADDR, op16)); break;
|
||||
case 0xae: sprintf(t, "ldx $%.4x [%.6x]", op16, decode(OPTYPE_ADDR, op16)); break;
|
||||
case 0xaf: sprintf(t, "lda $%.6x [%.6x]", op24, decode(OPTYPE_LONG, op24)); break;
|
||||
case 0xb0: sprintf(t, "bcs $%.4x [%.6x]", uint16(decode(OPTYPE_RELB, op8)), decode(OPTYPE_RELB, op8)); break;
|
||||
case 0xb0: sprintf(t, "bcs $%.4x [%.6x]", uint16_t(decode(OPTYPE_RELB, op8)), decode(OPTYPE_RELB, op8)); break;
|
||||
case 0xb1: sprintf(t, "lda ($%.2x),y [%.6x]", op8, decode(OPTYPE_IDPY, op8)); break;
|
||||
case 0xb2: sprintf(t, "lda ($%.2x) [%.6x]", op8, decode(OPTYPE_IDP, op8)); break;
|
||||
case 0xb3: sprintf(t, "lda ($%.2x,s),y [%.6x]", op8, decode(OPTYPE_ISRY, op8)); break;
|
||||
|
@ -349,7 +349,7 @@ auto R65816::disassemble_opcode(char* output, uint32 addr, bool e, bool m, bool
|
|||
case 0xcd: sprintf(t, "cmp $%.4x [%.6x]", op16, decode(OPTYPE_ADDR, op16)); break;
|
||||
case 0xce: sprintf(t, "dec $%.4x [%.6x]", op16, decode(OPTYPE_ADDR, op16)); break;
|
||||
case 0xcf: sprintf(t, "cmp $%.6x [%.6x]", op24, decode(OPTYPE_LONG, op24)); break;
|
||||
case 0xd0: sprintf(t, "bne $%.4x [%.6x]", uint16(decode(OPTYPE_RELB, op8)), decode(OPTYPE_RELB, op8)); break;
|
||||
case 0xd0: sprintf(t, "bne $%.4x [%.6x]", uint16_t(decode(OPTYPE_RELB, op8)), decode(OPTYPE_RELB, op8)); break;
|
||||
case 0xd1: sprintf(t, "cmp ($%.2x),y [%.6x]", op8, decode(OPTYPE_IDPY, op8)); break;
|
||||
case 0xd2: sprintf(t, "cmp ($%.2x) [%.6x]", op8, decode(OPTYPE_IDP, op8)); break;
|
||||
case 0xd3: sprintf(t, "cmp ($%.2x,s),y [%.6x]", op8, decode(OPTYPE_ISRY, op8)); break;
|
||||
|
@ -383,7 +383,7 @@ auto R65816::disassemble_opcode(char* output, uint32 addr, bool e, bool m, bool
|
|||
case 0xed: sprintf(t, "sbc $%.4x [%.6x]", op16, decode(OPTYPE_ADDR, op16)); break;
|
||||
case 0xee: sprintf(t, "inc $%.4x [%.6x]", op16, decode(OPTYPE_ADDR, op16)); break;
|
||||
case 0xef: sprintf(t, "sbc $%.6x [%.6x]", op24, decode(OPTYPE_LONG, op24)); break;
|
||||
case 0xf0: sprintf(t, "beq $%.4x [%.6x]", uint16(decode(OPTYPE_RELB, op8)), decode(OPTYPE_RELB, op8)); break;
|
||||
case 0xf0: sprintf(t, "beq $%.4x [%.6x]", uint16_t(decode(OPTYPE_RELB, op8)), decode(OPTYPE_RELB, op8)); break;
|
||||
case 0xf1: sprintf(t, "sbc ($%.2x),y [%.6x]", op8, decode(OPTYPE_IDPY, op8)); break;
|
||||
case 0xf2: sprintf(t, "sbc ($%.2x) [%.6x]", op8, decode(OPTYPE_IDP, op8)); break;
|
||||
case 0xf3: sprintf(t, "sbc ($%.2x,s),y [%.6x]", op8, decode(OPTYPE_ISRY, op8)); break;
|
||||
|
|
|
@ -146,7 +146,7 @@ auto V30MZ::opMultiplySignedRegMemImm(Size size) {
|
|||
//46 inc si
|
||||
//47 inc di
|
||||
auto V30MZ::opIncReg(uint16_t& reg) {
|
||||
reg++;
|
||||
reg = alInc(Word, reg);
|
||||
}
|
||||
|
||||
//48 dec ax
|
||||
|
@ -158,7 +158,7 @@ auto V30MZ::opIncReg(uint16_t& reg) {
|
|||
//4e dec si
|
||||
//4f dec di
|
||||
auto V30MZ::opDecReg(uint16_t& reg) {
|
||||
reg--;
|
||||
reg = alDec(Word, reg);
|
||||
}
|
||||
|
||||
//98 cbw
|
||||
|
|
|
@ -65,8 +65,9 @@ auto V30MZ::opLoadEffectiveAddressRegMem() {
|
|||
setReg(Word, modrm.address);
|
||||
}
|
||||
|
||||
auto V30MZ::opLoadSegmentMem(uint16_t& reg) {
|
||||
auto V30MZ::opLoadSegmentMem(uint16_t& segment) {
|
||||
wait(5);
|
||||
modRM();
|
||||
reg = getMem(Word);
|
||||
setReg(Word, getMem(Word));
|
||||
segment = getMem(Word, 2);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,202 @@
|
|||
//NEC D75P308GF
|
||||
//4-bit microcontroller
|
||||
//CD-player interface
|
||||
|
||||
auto SuperDisc::necPollIRQ() -> uint8 {
|
||||
auto match = [&](const string& compare) -> bool {
|
||||
if(nec.command.size() != compare.size()) return false;
|
||||
for(auto n : range(nec.command)) {
|
||||
char c = compare[n];
|
||||
if(c == '?') continue;
|
||||
if(c >= '0' && c <= '9') c -= '0';
|
||||
if(c >= 'a' && c <= 'f') c -= 'a' - 10;
|
||||
if(nec.command[n] != c) return false;
|
||||
}
|
||||
return true;
|
||||
};
|
||||
|
||||
//access ??/??/??
|
||||
if(match("b" )) return 0x8f;
|
||||
if(match("b?" )) return 0x8f;
|
||||
if(match("b??" )) return 0x8f;
|
||||
if(match("b???" )) return 0x8f;
|
||||
if(match("b????" )) return 0x8f;
|
||||
if(match("b?????" )) return 0x8f;
|
||||
if(match("b??????" )) return 0x8f;
|
||||
if(match("b??????f")) {
|
||||
nec.command.reset();
|
||||
return 0x8f;
|
||||
}
|
||||
|
||||
//access t??/i??
|
||||
if(match("c" )) return 0x8f;
|
||||
if(match("c?" )) return 0x8f;
|
||||
if(match("c??" )) return 0x8f;
|
||||
if(match("c???" )) return 0x8f;
|
||||
if(match("c????" )) return 0x8f;
|
||||
if(match("c????f")) {
|
||||
nec.command.reset();
|
||||
return 0x8f;
|
||||
}
|
||||
|
||||
//d-prefixes
|
||||
if(match("d" )) return 0x8f;
|
||||
if(match("d0")) return 0x8f;
|
||||
if(match("d1")) return 0x8f;
|
||||
if(match("d4")) return 0x8f;
|
||||
if(match("d5")) return 0x8f;
|
||||
|
||||
//stop
|
||||
if(match("d01" )) return 0x8f;
|
||||
if(match("d01f")) {
|
||||
nec.command.reset();
|
||||
return 0x8f;
|
||||
}
|
||||
|
||||
//play
|
||||
if(match("d02" )) return 0x8f;
|
||||
if(match("d02f")) {
|
||||
nec.command.reset();
|
||||
return 0x8f;
|
||||
}
|
||||
|
||||
//pause
|
||||
if(match("d03" )) return 0x8f;
|
||||
if(match("d03f")) {
|
||||
nec.command.reset();
|
||||
return 0x8f;
|
||||
}
|
||||
|
||||
//open / close
|
||||
if(match("d04" )) return 0x8f;
|
||||
if(match("d04f")) {
|
||||
nec.command.reset();
|
||||
return 0x8f;
|
||||
}
|
||||
|
||||
//fast forward
|
||||
if(match("d10" )) return 0x8f;
|
||||
if(match("d10f")) {
|
||||
nec.command.reset();
|
||||
return 0x8f;
|
||||
}
|
||||
|
||||
//fast reverse
|
||||
if(match("d11" )) return 0x8f;
|
||||
if(match("d11f")) {
|
||||
nec.command.reset();
|
||||
return 0x8f;
|
||||
}
|
||||
|
||||
//forward
|
||||
if(match("d12" )) return 0x8f;
|
||||
if(match("d12f")) {
|
||||
nec.command.reset();
|
||||
return 0x8f;
|
||||
}
|
||||
|
||||
//reverse
|
||||
if(match("d13" )) return 0x8f;
|
||||
if(match("d13f")) {
|
||||
nec.command.reset();
|
||||
return 0x8f;
|
||||
}
|
||||
|
||||
//key direct
|
||||
if(match("d40" )) return 0x8f;
|
||||
if(match("d40f")) {
|
||||
nec.command.reset();
|
||||
return 0x8f;
|
||||
}
|
||||
|
||||
//key ignore
|
||||
if(match("d41" )) return 0x8f;
|
||||
if(match("d41f")) {
|
||||
nec.command.reset();
|
||||
return 0x8f;
|
||||
}
|
||||
|
||||
//continuous play
|
||||
if(match("d42" )) return 0x8f;
|
||||
if(match("d42f")) {
|
||||
nec.command.reset();
|
||||
return 0x8f;
|
||||
}
|
||||
|
||||
//auto track pause
|
||||
if(match("d43" )) return 0x8f;
|
||||
if(match("d43f")) {
|
||||
nec.command.reset();
|
||||
return 0x8f;
|
||||
}
|
||||
|
||||
//auto index pause
|
||||
if(match("d44" )) return 0x8f;
|
||||
if(match("d44f")) {
|
||||
nec.command.reset();
|
||||
return 0x8f;
|
||||
}
|
||||
|
||||
//normal speed
|
||||
if(match("d45" )) return 0x8f;
|
||||
if(match("d45f")) {
|
||||
nec.command.reset();
|
||||
return 0x8f;
|
||||
}
|
||||
|
||||
//double speed
|
||||
if(match("d46" )) return 0x8f;
|
||||
if(match("d46f")) {
|
||||
nec.command.reset();
|
||||
return 0x8f;
|
||||
}
|
||||
|
||||
//q-data request
|
||||
if(match("d50" )) return 0x8f;
|
||||
if(match("d50f" )) return 0x8f;
|
||||
if(match("d50f?" )) return 0x80;
|
||||
if(match("d50f??" )) return 0x80;
|
||||
if(match("d50f???" )) return 0x80;
|
||||
if(match("d50f????" )) return 0x80;
|
||||
if(match("d50f?????" )) return 0x80;
|
||||
if(match("d50f??????" )) return 0x80;
|
||||
if(match("d50f???????" )) return 0x80;
|
||||
if(match("d50f????????" )) return 0x80;
|
||||
if(match("d50f?????????" )) return 0x80;
|
||||
if(match("d50f??????????" )) return 0x80;
|
||||
if(match("d50f???????????" )) return 0x80;
|
||||
if(match("d50f????????????" )) return 0x80;
|
||||
if(match("d50f?????????????" )) return 0x80;
|
||||
if(match("d50f??????????????" )) return 0x80;
|
||||
if(match("d50f???????????????" )) return 0x80;
|
||||
if(match("d50f????????????????" )) return 0x80;
|
||||
if(match("d50f????????????????f")) {
|
||||
nec.command.reset();
|
||||
return 0x8f;
|
||||
}
|
||||
|
||||
//status request
|
||||
if(match("d51" )) return 0x8f;
|
||||
if(match("d51f" )) return 0x8f;
|
||||
if(match("d51f0" )) return 0x81;
|
||||
if(match("d51f01" )) return 0x80;
|
||||
if(match("d51f012" )) return 0x81;
|
||||
if(match("d51f0123" )) return 0x80;
|
||||
if(match("d51f01234" )) return 0x80;
|
||||
if(match("d51f01234f")) {
|
||||
nec.command.reset();
|
||||
return 0x8f;
|
||||
}
|
||||
|
||||
nec.command.reset();
|
||||
return 0x00;
|
||||
}
|
||||
|
||||
auto SuperDisc::necReadData() -> uint8 {
|
||||
return nec.data;
|
||||
}
|
||||
|
||||
auto SuperDisc::necWriteCommand(uint4 data) -> void {
|
||||
if(nec.command.size() >= 32) return;
|
||||
nec.command.append(data);
|
||||
}
|
|
@ -0,0 +1,143 @@
|
|||
//Sony CXD1800Q
|
||||
//CD-ROM decoder
|
||||
|
||||
auto SuperDisc::sonyPollIRQ() -> uint8 {
|
||||
return 0x00;
|
||||
}
|
||||
|
||||
auto SuperDisc::sonyReadData() -> uint8 {
|
||||
uint8 command = sony.command++;
|
||||
|
||||
auto match = [&](const string& compare) -> bool {
|
||||
char hi = compare[0];
|
||||
if(hi == '?') hi = 0;
|
||||
if(hi >= '0' && hi <= '9') hi -= '0';
|
||||
if(hi >= 'a' && hi <= 'f') hi -= 'a' - 10;
|
||||
if(hi != '?' && hi != command.bits(4,7)) return false;
|
||||
|
||||
char lo = compare[1];
|
||||
if(lo == '?') lo = 0;
|
||||
if(lo >= '0' && lo <= '9') lo -= '0';
|
||||
if(lo >= 'a' && lo <= 'f') lo -= 'a' - 10;
|
||||
if(lo != '?' && lo != command.bits(0,3)) return false;
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
//DMA
|
||||
if(match("00")) return 0x00;
|
||||
|
||||
//INST
|
||||
if(match("01")) return 0x10;
|
||||
|
||||
//STS
|
||||
if(match("02")) return 0x00;
|
||||
|
||||
//HFLG
|
||||
if(match("03")) return 0x00;
|
||||
|
||||
//HMIN
|
||||
if(match("?4")) return 0x00;
|
||||
|
||||
//HSEC
|
||||
if(match("?5")) return 0x00;
|
||||
|
||||
//HBLK
|
||||
if(match("?6")) return 0x00;
|
||||
|
||||
//HMOD
|
||||
if(match("?7")) return 0x00;
|
||||
|
||||
//SFIL
|
||||
if(match("08")) return 0x00;
|
||||
|
||||
//SCH
|
||||
if(match("09")) return 0x00;
|
||||
|
||||
//SMOD
|
||||
if(match("0a")) return 0x00;
|
||||
|
||||
//SCI
|
||||
if(match("0b")) return 0x00;
|
||||
|
||||
//CMAD
|
||||
if(match("0c")) return 0x00;
|
||||
if(match("0d")) return 0x00;
|
||||
|
||||
//MDFM
|
||||
if(match("?e")) return 0x00;
|
||||
|
||||
//ADPC
|
||||
if(match("?f")) return 0x00;
|
||||
|
||||
//DMXF
|
||||
if(match("18")) return 0x00;
|
||||
if(match("19")) return 0x00;
|
||||
|
||||
//DMAD
|
||||
if(match("1a")) return 0x00;
|
||||
if(match("1b")) return 0x00;
|
||||
|
||||
//DRAD
|
||||
if(match("1c")) return 0x00;
|
||||
if(match("1d")) return 0x00;
|
||||
|
||||
return 0x00;
|
||||
}
|
||||
|
||||
auto SuperDisc::sonyWriteCommand(uint8 data) -> void {
|
||||
sony.command = data;
|
||||
}
|
||||
|
||||
auto SuperDisc::sonyWriteData(uint8 data) -> void {
|
||||
uint8 command = sony.command++;
|
||||
|
||||
auto match = [&](const string& compare) -> bool {
|
||||
char hi = compare[0];
|
||||
if(hi == '?') hi = 0;
|
||||
if(hi >= '0' && hi <= '9') hi -= '0';
|
||||
if(hi >= 'a' && hi <= 'f') hi -= 'a' - 10;
|
||||
if(hi != '?' && hi != command.bits(4,7)) return false;
|
||||
|
||||
char lo = compare[1];
|
||||
if(lo == '?') lo = 0;
|
||||
if(lo >= '0' && lo <= '9') lo -= '0';
|
||||
if(lo >= 'a' && lo <= 'f') lo -= 'a' - 10;
|
||||
if(lo != '?' && lo != command.bits(0,3)) return false;
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
//DRIF
|
||||
if(match("?1")) return;
|
||||
|
||||
//CHCT
|
||||
if(match("?2")) return;
|
||||
|
||||
//DECT
|
||||
if(match("?3")) return;
|
||||
|
||||
//INMS
|
||||
if(match("?4")) return;
|
||||
|
||||
//INCL
|
||||
if(match("?5")) return;
|
||||
|
||||
//CI
|
||||
if(match("?6")) return;
|
||||
|
||||
//DMAD
|
||||
if(match("?7")) return;
|
||||
if(match("?8")) return;
|
||||
|
||||
//DMXF
|
||||
if(match("?9")) return;
|
||||
if(match("?a")) return;
|
||||
|
||||
//DRAD
|
||||
if(match("?b")) return;
|
||||
if(match("?c")) return;
|
||||
|
||||
//PLBA
|
||||
if(match("0d")) return;
|
||||
}
|
|
@ -3,18 +3,24 @@
|
|||
namespace SuperFamicom {
|
||||
|
||||
SuperDisc superdisc;
|
||||
#include "nec.cpp"
|
||||
#include "sony.cpp"
|
||||
|
||||
auto SuperDisc::Enter() -> void {
|
||||
while(true) scheduler.synchronize(), superdisc.main();
|
||||
}
|
||||
|
||||
auto SuperDisc::main() -> void {
|
||||
if(r21e4 & 0x04) {
|
||||
cpu.regs.irq = 1;
|
||||
r21e1 = 0x81;
|
||||
} else {
|
||||
cpu.regs.irq = 0;
|
||||
r21e1 = 0x00;
|
||||
|
||||
if(r.irqEnable.bit(3)) {
|
||||
cpu.regs.irq = 1;
|
||||
nec.data = necPollIRQ();
|
||||
}
|
||||
|
||||
if(r.irqEnable.bit(2)) {
|
||||
cpu.regs.irq = 1;
|
||||
sony.data = sonyPollIRQ();
|
||||
}
|
||||
|
||||
step(1);
|
||||
|
@ -37,41 +43,42 @@ auto SuperDisc::power() -> void {
|
|||
}
|
||||
|
||||
auto SuperDisc::reset() -> void {
|
||||
r21e0 = 0x00;
|
||||
r21e1 = 0x00;
|
||||
r21e2 = 0x00;
|
||||
r21e3 = 0x00;
|
||||
r21e4 = 0x00;
|
||||
r21e5 = 0x00;
|
||||
r.irqEnable = 0x00;
|
||||
|
||||
nec.command.reset();
|
||||
nec.data = 0x00;
|
||||
|
||||
sony.command = 0x00;
|
||||
sony.data = 0x00;
|
||||
}
|
||||
|
||||
auto SuperDisc::read(uint24 addr, uint8 data) -> uint8 {
|
||||
addr = 0x21e0 | (addr & 7);
|
||||
|
||||
if(addr == 0x21e0) {
|
||||
data = r21e0;
|
||||
data = 0x00;
|
||||
}
|
||||
|
||||
if(addr == 0x21e1) {
|
||||
data = r21e1;
|
||||
cpu.regs.irq = 0;
|
||||
data = necReadData();
|
||||
}
|
||||
|
||||
if(addr == 0x21e2) {
|
||||
data = r21e2;
|
||||
data = 0x00;
|
||||
}
|
||||
|
||||
if(addr == 0x21e3) {
|
||||
if(r21e2 == 0x01) data = 0x10;
|
||||
else data = 0x00;
|
||||
r21e2++;
|
||||
cpu.regs.irq = 0;
|
||||
data = sonyReadData();
|
||||
}
|
||||
|
||||
if(addr == 0x21e4) {
|
||||
data = r21e4;
|
||||
data = r.irqEnable;
|
||||
}
|
||||
|
||||
if(addr == 0x21e5) {
|
||||
data = r21e5;
|
||||
data = 0x00;
|
||||
}
|
||||
|
||||
return data;
|
||||
|
@ -81,28 +88,25 @@ auto SuperDisc::write(uint24 addr, uint8 data) -> void {
|
|||
addr = 0x21e0 | (addr & 7);
|
||||
|
||||
if(addr == 0x21e0) {
|
||||
r21e0 = data;
|
||||
}
|
||||
|
||||
if(addr == 0x21e1) {
|
||||
r21e1 = data;
|
||||
necWriteCommand(data.bits(0,3));
|
||||
}
|
||||
|
||||
if(addr == 0x21e2) {
|
||||
r21e2 = data;
|
||||
sonyWriteCommand(data);
|
||||
}
|
||||
|
||||
if(addr == 0x21e3) {
|
||||
r21e2++;
|
||||
r21e3 = data;
|
||||
sonyWriteData(data);
|
||||
}
|
||||
|
||||
if(addr == 0x21e4) {
|
||||
r21e4 = data;
|
||||
r.irqEnable = data;
|
||||
}
|
||||
|
||||
if(addr == 0x21e5) {
|
||||
r21e5 = data;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -11,13 +11,33 @@ struct SuperDisc : Coprocessor, Memory {
|
|||
auto read(uint24 addr, uint8 data) -> uint8;
|
||||
auto write(uint24 addr, uint8 data) -> void;
|
||||
|
||||
//nec.cpp
|
||||
auto necPollIRQ() -> uint8;
|
||||
auto necReadData() -> uint8;
|
||||
auto necWriteCommand(uint4 data) -> void;
|
||||
|
||||
//sony.cpp
|
||||
auto sonyPollIRQ() -> uint8;
|
||||
auto sonyReadData() -> uint8;
|
||||
auto sonyWriteCommand(uint8 data) -> void;
|
||||
auto sonyWriteData(uint8 data) -> void;
|
||||
|
||||
private:
|
||||
uint8 r21e0;
|
||||
uint8 r21e1;
|
||||
uint8 r21e2;
|
||||
uint8 r21e3;
|
||||
uint8 r21e4;
|
||||
uint8 r21e5;
|
||||
struct Registers {
|
||||
uint8 irqEnable;
|
||||
} r;
|
||||
|
||||
//NEC
|
||||
struct NEC {
|
||||
vector<uint4> command;
|
||||
uint8 data;
|
||||
} nec;
|
||||
|
||||
//Sony
|
||||
struct Sony {
|
||||
uint8 command;
|
||||
uint8 data;
|
||||
} sony;
|
||||
};
|
||||
|
||||
extern SuperDisc superdisc;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
auto CPU::keypadRead() -> uint4 {
|
||||
uint1 orientation = 1;
|
||||
uint1 orientation = 0;
|
||||
uint4 data = 0;
|
||||
|
||||
if(r.ypadEnable) {
|
||||
|
|
Loading…
Reference in New Issue