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:
Tim Allen 2016-03-10 21:35:48 +11:00
parent 3d3ac8c1db
commit 79e7e6ab9e
9 changed files with 418 additions and 48 deletions

View File

@ -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/";

View File

@ -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;

View File

@ -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

View File

@ -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);
} }

View File

@ -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);
}

View File

@ -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;
}

View File

@ -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 = 0;
if(r.irqEnable.bit(3)) {
cpu.regs.irq = 1; cpu.regs.irq = 1;
r21e1 = 0x81; nec.data = necPollIRQ();
} else { }
cpu.regs.irq = 0;
r21e1 = 0x00; 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;
} }
} }

View File

@ -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;

View File

@ -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) {