From 49ec644f7125c2fdcd7dd3c832fc178fb951913d Mon Sep 17 00:00:00 2001 From: alyosha-tas <alexei.f.k@gmail.com> Date: Tue, 24 Sep 2019 13:09:17 -0400 Subject: [PATCH] GBHawk: Add in IR transfer support --- .../Consoles/Nintendo/GBHawk/Audio.cs | 4 +- .../Nintendo/GBHawk/GBHawk.IEmulator.cs | 2 +- .../Nintendo/GBHawk/GBHawk.IStatable.cs | 6 +++ .../Consoles/Nintendo/GBHawk/GBHawk.cs | 5 +++ .../Consoles/Nintendo/GBHawk/HW_Registers.cs | 44 +++++++++++++++++++ .../GBHawkLink/GBHawkLink.IEmulator.cs | 29 ++++++------ .../GBHawkLink3x/GBHawkLink3x.IEmulator.cs | 12 +++++ 7 files changed, 85 insertions(+), 17 deletions(-) diff --git a/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawk/Audio.cs b/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawk/Audio.cs index e10e1f9b22..ea55349bc8 100644 --- a/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawk/Audio.cs +++ b/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawk/Audio.cs @@ -277,7 +277,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk } if ((SQ1_vol_state == 0) && !SQ1_env_add) { SQ1_enable = SQ1_swp_enable = false; SQ1_output = 0; } - if ((SQ1_vol_state == 0) && (SQ1_per == 0) && SQ1_env_add) { SQ1_vol_state = 16; } + //if ((SQ1_vol_state == 0) && (SQ1_per == 0) && SQ1_env_add) { SQ1_vol_state = 16; } } SQ1_len_en = (value & 0x40) > 0; @@ -337,7 +337,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk SQ2_vol_state = SQ2_st_vol; SQ2_vol_per = (SQ2_per > 0) ? SQ2_per : 8; if ((SQ2_vol_state == 0) && !SQ2_env_add) { SQ2_enable = false; SQ2_output = 0; } - if ((SQ2_vol_state == 0) && (SQ2_per == 0) && SQ2_env_add) { SQ2_vol_state = 16; } + //if ((SQ2_vol_state == 0) && (SQ2_per == 0) && SQ2_env_add) { SQ2_vol_state = 16; } } SQ2_len_en = (value & 0x40) > 0; diff --git a/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawk/GBHawk.IEmulator.cs b/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawk/GBHawk.IEmulator.cs index 113a8d9c9a..614aa4830e 100644 --- a/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawk/GBHawk.IEmulator.cs +++ b/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawk/GBHawk.IEmulator.cs @@ -226,7 +226,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk if (speed_switch) { speed_switch = false; - Console.WriteLine(cpu.TotalExecutedCycles); + Console.WriteLine("Speed Switch: " + cpu.TotalExecutedCycles); int ret = double_speed ? 70224 * 2 : 70224 * 2; // actual time needs checking double_speed = !double_speed; return ret; diff --git a/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawk/GBHawk.IStatable.cs b/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawk/GBHawk.IStatable.cs index 21d9aa4794..d7ca270d54 100644 --- a/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawk/GBHawk.IStatable.cs +++ b/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawk/GBHawk.IStatable.cs @@ -90,6 +90,12 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk ser.Sync(nameof(speed_switch), ref speed_switch); ser.Sync(nameof(HDMA_transfer), ref HDMA_transfer); + ser.Sync(nameof(IR_reg), ref IR_reg); + ser.Sync(nameof(IR_mask), ref IR_mask); + 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(undoc_6C), ref undoc_6C); ser.Sync(nameof(undoc_72), ref undoc_72); ser.Sync(nameof(undoc_73), ref undoc_73); diff --git a/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawk/GBHawk.cs b/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawk/GBHawk.cs index 9267548b4e..615b4da28c 100644 --- a/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawk/GBHawk.cs +++ b/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawk/GBHawk.cs @@ -54,6 +54,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk public bool double_speed; 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; // several undocumented GBC Registers public byte undoc_6C, undoc_72, undoc_73, undoc_74, undoc_75, undoc_76, undoc_77; @@ -144,6 +145,9 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk _bios = Bios; + // set up IR register to off state + if (is_GBC) { IR_mask = 0; IR_reg = 0x3E; IR_receive = 2; IR_self = 2; IR_signal = 2; } + // Here we modify the BIOS if GBA mode is set (credit to ExtraTricky) if (is_GBC && _syncSettings.GBACGB) { @@ -151,6 +155,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk { _bios[i + 0xF3] = (byte)((GBA_override[i] + _bios[i + 0xF3]) & 0xFF); } + IR_mask = 2; } // CPU needs to know about GBC status too diff --git a/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawk/HW_Registers.cs b/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawk/HW_Registers.cs index 6c386b1d92..3df28da035 100644 --- a/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawk/HW_Registers.cs +++ b/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawk/HW_Registers.cs @@ -133,6 +133,36 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk case 0xFF53: case 0xFF54: case 0xFF55: + if (GBC_compat) + { + ret = ppu.ReadReg(addr); + } + else + { + ret = 0xFF; + } + break; + + case 0xFF56: + if (is_GBC) + { + // can receive data + if ((IR_reg & 0xC0) == 0xC0) + { + ret = (byte)(IR_reg | (IR_self | IR_receive | IR_mask)); + } + else + { + ret = (byte)(IR_reg | 2); + } + + } + else + { + ret = 0xFF; + } + break; + case 0xFF68: case 0xFF69: case 0xFF6A: @@ -392,6 +422,20 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk ppu.WriteReg(addr, value); } break; + + case 0xFF56: + if (is_GBC) + { + IR_reg = (byte)((value & 0xC1) | (IR_reg & 0x3E)); + + // send IR signal out + 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; } + } + break; + case 0xFF68: case 0xFF69: case 0xFF6A: diff --git a/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawkLink/GBHawkLink.IEmulator.cs b/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawkLink/GBHawkLink.IEmulator.cs index d8756b766b..cdc8cd3b39 100644 --- a/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawkLink/GBHawkLink.IEmulator.cs +++ b/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawkLink/GBHawkLink.IEmulator.cs @@ -100,10 +100,10 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawkLink L.do_single_step(); R.do_single_step(); - // the signal to shift out a bit is when serial_clock = 1 - if (((L.serialport.serial_clock == 1) || (L.serialport.serial_clock == 2)) && !do_r_next) + if (_cableconnected) { - if (_cableconnected) + // the signal to shift out a bit is when serial_clock = 1 + if (((L.serialport.serial_clock == 1) || (L.serialport.serial_clock == 2)) && !do_r_next) { L.serialport.send_external_bit((byte)(L.serialport.serial_data & 0x80)); @@ -116,13 +116,10 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawkLink L.serialport.coming_in = R.serialport.going_out; } - } - else if ((R.serialport.serial_clock == 1) || (R.serialport.serial_clock == 2)) - { - do_r_next = false; - - if (_cableconnected) + else if ((R.serialport.serial_clock == 1) || (R.serialport.serial_clock == 2)) { + do_r_next = false; + R.serialport.send_external_bit((byte)(R.serialport.serial_data & 0x80)); if ((L.serialport.clk_rate == -1) && L.serialport.serial_start) @@ -133,13 +130,17 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawkLink } R.serialport.coming_in = L.serialport.going_out; + + if (R.serialport.serial_clock == 2) { do_r_next = true; } + } + else + { + do_r_next = false; } - if (R.serialport.serial_clock == 2) { do_r_next = true; } - } - else - { - do_r_next = false; + // do IR transfer + L.IR_receive = R.IR_signal; + R.IR_receive = L.IR_signal; } // if we hit a frame boundary, update video diff --git a/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawkLink3x/GBHawkLink3x.IEmulator.cs b/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawkLink3x/GBHawkLink3x.IEmulator.cs index 4bb30e5a79..b769d41ce7 100644 --- a/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawkLink3x/GBHawkLink3x.IEmulator.cs +++ b/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawkLink3x/GBHawkLink3x.IEmulator.cs @@ -172,6 +172,10 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawkLink3x { do_2_next = false; } + + // do IR transfer + L.IR_receive = C.IR_signal; + C.IR_receive = L.IR_signal; } else if (_cableconnected_CR) { @@ -210,6 +214,10 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawkLink3x { do_2_next = false; } + + // do IR transfer + C.IR_receive = R.IR_signal; + R.IR_receive = C.IR_signal; } else if (_cableconnected_RL) { @@ -248,6 +256,10 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawkLink3x { do_2_next = false; } + + // do IR transfer + R.IR_receive = L.IR_signal; + L.IR_receive = R.IR_signal; }