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 {
|
namespace Emulator {
|
||||||
static const string Name = "higan";
|
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 Author = "byuu";
|
||||||
static const string License = "GPLv3";
|
static const string License = "GPLv3";
|
||||||
static const string Website = "http://byuu.org/";
|
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 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 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 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 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 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;
|
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 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 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 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 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 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;
|
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 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 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 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 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 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;
|
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 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 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 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 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 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;
|
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 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 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 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 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 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 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;
|
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 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 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 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 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 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;
|
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 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 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 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 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 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;
|
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 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 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 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 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 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;
|
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 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 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 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 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 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;
|
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
|
//46 inc si
|
||||||
//47 inc di
|
//47 inc di
|
||||||
auto V30MZ::opIncReg(uint16_t& reg) {
|
auto V30MZ::opIncReg(uint16_t& reg) {
|
||||||
reg++;
|
reg = alInc(Word, reg);
|
||||||
}
|
}
|
||||||
|
|
||||||
//48 dec ax
|
//48 dec ax
|
||||||
|
@ -158,7 +158,7 @@ auto V30MZ::opIncReg(uint16_t& reg) {
|
||||||
//4e dec si
|
//4e dec si
|
||||||
//4f dec di
|
//4f dec di
|
||||||
auto V30MZ::opDecReg(uint16_t& reg) {
|
auto V30MZ::opDecReg(uint16_t& reg) {
|
||||||
reg--;
|
reg = alDec(Word, reg);
|
||||||
}
|
}
|
||||||
|
|
||||||
//98 cbw
|
//98 cbw
|
||||||
|
|
|
@ -65,8 +65,9 @@ auto V30MZ::opLoadEffectiveAddressRegMem() {
|
||||||
setReg(Word, modrm.address);
|
setReg(Word, modrm.address);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto V30MZ::opLoadSegmentMem(uint16_t& reg) {
|
auto V30MZ::opLoadSegmentMem(uint16_t& segment) {
|
||||||
wait(5);
|
wait(5);
|
||||||
modRM();
|
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 {
|
namespace SuperFamicom {
|
||||||
|
|
||||||
SuperDisc superdisc;
|
SuperDisc superdisc;
|
||||||
|
#include "nec.cpp"
|
||||||
|
#include "sony.cpp"
|
||||||
|
|
||||||
auto SuperDisc::Enter() -> void {
|
auto SuperDisc::Enter() -> void {
|
||||||
while(true) scheduler.synchronize(), superdisc.main();
|
while(true) scheduler.synchronize(), superdisc.main();
|
||||||
}
|
}
|
||||||
|
|
||||||
auto SuperDisc::main() -> void {
|
auto SuperDisc::main() -> void {
|
||||||
if(r21e4 & 0x04) {
|
|
||||||
cpu.regs.irq = 1;
|
|
||||||
r21e1 = 0x81;
|
|
||||||
} else {
|
|
||||||
cpu.regs.irq = 0;
|
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);
|
step(1);
|
||||||
|
@ -37,41 +43,42 @@ auto SuperDisc::power() -> void {
|
||||||
}
|
}
|
||||||
|
|
||||||
auto SuperDisc::reset() -> void {
|
auto SuperDisc::reset() -> void {
|
||||||
r21e0 = 0x00;
|
r.irqEnable = 0x00;
|
||||||
r21e1 = 0x00;
|
|
||||||
r21e2 = 0x00;
|
nec.command.reset();
|
||||||
r21e3 = 0x00;
|
nec.data = 0x00;
|
||||||
r21e4 = 0x00;
|
|
||||||
r21e5 = 0x00;
|
sony.command = 0x00;
|
||||||
|
sony.data = 0x00;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto SuperDisc::read(uint24 addr, uint8 data) -> uint8 {
|
auto SuperDisc::read(uint24 addr, uint8 data) -> uint8 {
|
||||||
addr = 0x21e0 | (addr & 7);
|
addr = 0x21e0 | (addr & 7);
|
||||||
|
|
||||||
if(addr == 0x21e0) {
|
if(addr == 0x21e0) {
|
||||||
data = r21e0;
|
data = 0x00;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(addr == 0x21e1) {
|
if(addr == 0x21e1) {
|
||||||
data = r21e1;
|
cpu.regs.irq = 0;
|
||||||
|
data = necReadData();
|
||||||
}
|
}
|
||||||
|
|
||||||
if(addr == 0x21e2) {
|
if(addr == 0x21e2) {
|
||||||
data = r21e2;
|
data = 0x00;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(addr == 0x21e3) {
|
if(addr == 0x21e3) {
|
||||||
if(r21e2 == 0x01) data = 0x10;
|
cpu.regs.irq = 0;
|
||||||
else data = 0x00;
|
data = sonyReadData();
|
||||||
r21e2++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(addr == 0x21e4) {
|
if(addr == 0x21e4) {
|
||||||
data = r21e4;
|
data = r.irqEnable;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(addr == 0x21e5) {
|
if(addr == 0x21e5) {
|
||||||
data = r21e5;
|
data = 0x00;
|
||||||
}
|
}
|
||||||
|
|
||||||
return data;
|
return data;
|
||||||
|
@ -81,28 +88,25 @@ auto SuperDisc::write(uint24 addr, uint8 data) -> void {
|
||||||
addr = 0x21e0 | (addr & 7);
|
addr = 0x21e0 | (addr & 7);
|
||||||
|
|
||||||
if(addr == 0x21e0) {
|
if(addr == 0x21e0) {
|
||||||
r21e0 = data;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(addr == 0x21e1) {
|
if(addr == 0x21e1) {
|
||||||
r21e1 = data;
|
necWriteCommand(data.bits(0,3));
|
||||||
}
|
}
|
||||||
|
|
||||||
if(addr == 0x21e2) {
|
if(addr == 0x21e2) {
|
||||||
r21e2 = data;
|
sonyWriteCommand(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(addr == 0x21e3) {
|
if(addr == 0x21e3) {
|
||||||
r21e2++;
|
sonyWriteData(data);
|
||||||
r21e3 = data;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(addr == 0x21e4) {
|
if(addr == 0x21e4) {
|
||||||
r21e4 = data;
|
r.irqEnable = data;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(addr == 0x21e5) {
|
if(addr == 0x21e5) {
|
||||||
r21e5 = data;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -11,13 +11,33 @@ struct SuperDisc : Coprocessor, Memory {
|
||||||
auto read(uint24 addr, uint8 data) -> uint8;
|
auto read(uint24 addr, uint8 data) -> uint8;
|
||||||
auto write(uint24 addr, uint8 data) -> void;
|
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:
|
private:
|
||||||
uint8 r21e0;
|
struct Registers {
|
||||||
uint8 r21e1;
|
uint8 irqEnable;
|
||||||
uint8 r21e2;
|
} r;
|
||||||
uint8 r21e3;
|
|
||||||
uint8 r21e4;
|
//NEC
|
||||||
uint8 r21e5;
|
struct NEC {
|
||||||
|
vector<uint4> command;
|
||||||
|
uint8 data;
|
||||||
|
} nec;
|
||||||
|
|
||||||
|
//Sony
|
||||||
|
struct Sony {
|
||||||
|
uint8 command;
|
||||||
|
uint8 data;
|
||||||
|
} sony;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern SuperDisc superdisc;
|
extern SuperDisc superdisc;
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
auto CPU::keypadRead() -> uint4 {
|
auto CPU::keypadRead() -> uint4 {
|
||||||
uint1 orientation = 1;
|
uint1 orientation = 0;
|
||||||
uint4 data = 0;
|
uint4 data = 0;
|
||||||
|
|
||||||
if(r.ypadEnable) {
|
if(r.ypadEnable) {
|
||||||
|
|
Loading…
Reference in New Issue