GBHawk: IR comm working

This commit is contained in:
alyosha-tas 2019-10-01 21:03:30 -04:00
parent 9bfe61a9d4
commit 211e65dbf5
5 changed files with 106 additions and 11 deletions

View File

@ -95,6 +95,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
ser.Sync(nameof(IR_signal), ref IR_signal);
ser.Sync(nameof(IR_receive), ref IR_receive);
ser.Sync(nameof(IR_self), ref IR_self);
ser.Sync(nameof(IR_write), ref IR_write);
ser.Sync(nameof(undoc_6C), ref undoc_6C);
ser.Sync(nameof(undoc_72), ref undoc_72);

View File

@ -55,6 +55,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
public bool speed_switch;
public bool HDMA_transfer; // stalls CPU when in progress
public byte IR_reg, IR_mask, IR_signal, IR_receive, IR_self;
public int IR_write;
// several undocumented GBC Registers
public byte undoc_6C, undoc_72, undoc_73, undoc_74, undoc_75, undoc_76, undoc_77;

View File

@ -149,13 +149,12 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
// can receive data
if ((IR_reg & 0xC0) == 0xC0)
{
ret = (byte)(IR_reg | (IR_self | IR_receive | IR_mask));
ret = IR_reg;
}
else
{
ret = (byte)(IR_reg | 2);
}
}
else
{
@ -432,7 +431,9 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
if ((IR_reg & 0x1) == 0x1) { IR_signal = (byte)(0 | IR_mask); } else { IR_signal = 2; }
// receive own signal if IR on and receive on
if ((IR_reg & 0xC1) == 0xC1) { IR_self = 0; } else { IR_self = 2; }
if ((IR_reg & 0xC1) == 0xC1) { IR_self = (byte)(0 | IR_mask); } else { IR_self = 2; }
IR_write = 8;
}
break;

View File

@ -141,8 +141,31 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawkLink
}
// do IR transfer
L.IR_receive = R.IR_signal;
R.IR_receive = L.IR_signal;
if (L.IR_write > 0)
{
L.IR_write--;
if (L.IR_write ==0)
{
R.IR_receive = L.IR_signal;
if ((R.IR_self & R.IR_receive) == 2) { R.IR_reg |= 2; }
else { R.IR_reg &= 0xFD;}
if ((L.IR_self & L.IR_receive) == 2) { L.IR_reg |= 2; }
else { L.IR_reg &= 0xFD; }
}
}
if (R.IR_write > 0)
{
R.IR_write--;
if (R.IR_write == 0)
{
L.IR_receive = R.IR_signal;
if ((L.IR_self & L.IR_receive) == 2) { L.IR_reg |= 2; }
else { L.IR_reg &= 0xFD; }
if ((R.IR_self & R.IR_receive) == 2) { R.IR_reg |= 2; }
else { R.IR_reg &= 0xFD; }
}
}
}
// if we hit a frame boundary, update video

View File

@ -176,8 +176,31 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawkLink3x
}
// do IR transfer
L.IR_receive = C.IR_signal;
C.IR_receive = L.IR_signal;
if (L.IR_write > 0)
{
L.IR_write--;
if (L.IR_write == 0)
{
C.IR_receive = L.IR_signal;
if ((C.IR_self & C.IR_receive) == 2) { C.IR_reg |= 2; }
else { C.IR_reg &= 0xFD; }
if ((L.IR_self & L.IR_receive) == 2) { L.IR_reg |= 2; }
else { L.IR_reg &= 0xFD; }
}
}
if (C.IR_write > 0)
{
C.IR_write--;
if (C.IR_write == 0)
{
L.IR_receive = C.IR_signal;
if ((L.IR_self & L.IR_receive) == 2) { L.IR_reg |= 2; }
else { L.IR_reg &= 0xFD; }
if ((C.IR_self & C.IR_receive) == 2) { C.IR_reg |= 2; }
else { C.IR_reg &= 0xFD; }
}
}
}
else if (_cableconnected_CR)
{
@ -220,8 +243,31 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawkLink3x
}
// do IR transfer
C.IR_receive = R.IR_signal;
R.IR_receive = C.IR_signal;
if (C.IR_write > 0)
{
C.IR_write--;
if (C.IR_write == 0)
{
R.IR_receive = C.IR_signal;
if ((R.IR_self & R.IR_receive) == 2) { R.IR_reg |= 2; }
else { R.IR_reg &= 0xFD; }
if ((C.IR_self & C.IR_receive) == 2) { C.IR_reg |= 2; }
else { C.IR_reg &= 0xFD; }
}
}
if (R.IR_write > 0)
{
R.IR_write--;
if (R.IR_write == 0)
{
C.IR_receive = R.IR_signal;
if ((C.IR_self & C.IR_receive) == 2) { C.IR_reg |= 2; }
else { C.IR_reg &= 0xFD; }
if ((R.IR_self & R.IR_receive) == 2) { R.IR_reg |= 2; }
else { R.IR_reg &= 0xFD; }
}
}
}
else if (_cableconnected_RL)
{
@ -264,8 +310,31 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawkLink3x
}
// do IR transfer
R.IR_receive = L.IR_signal;
L.IR_receive = R.IR_signal;
if (R.IR_write > 0)
{
R.IR_write--;
if (R.IR_write == 0)
{
L.IR_receive = R.IR_signal;
if ((L.IR_self & L.IR_receive) == 2) { L.IR_reg |= 2; }
else { L.IR_reg &= 0xFD; }
if ((R.IR_self & R.IR_receive) == 2) { R.IR_reg |= 2; }
else { R.IR_reg &= 0xFD; }
}
}
if (L.IR_write > 0)
{
L.IR_write--;
if (L.IR_write == 0)
{
R.IR_receive = L.IR_signal;
if ((R.IR_self & R.IR_receive) == 2) { R.IR_reg |= 2; }
else { R.IR_reg &= 0xFD; }
if ((L.IR_self & L.IR_receive) == 2) { L.IR_reg |= 2; }
else { L.IR_reg &= 0xFD; }
}
}
}