Skip to content

Commit

Permalink
a
Browse files Browse the repository at this point in the history
  • Loading branch information
telecomadm1145 committed Aug 2, 2024
1 parent 4ea1905 commit 0142121
Show file tree
Hide file tree
Showing 7 changed files with 202 additions and 56 deletions.
22 changes: 13 additions & 9 deletions CasioEmuMsvc/Chipset/MMU.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -75,16 +75,20 @@ namespace casioemu {
if (segment_index == 8)
return le_read(rom[offset & 0x7ffff]);
segment_index &= 7;
if (segment_index == 7) {
if (segment_offset >= 0x2000) {
return 0xffff;
}
else {
return rom[0x5E000 + segment_offset];
}
}
if (segment_index == 6)
// if (segment_index == 7) {
// if (segment_offset >= 0x2000) {
// return 0xffff;
// }
// else {
// return rom[0x5E000 + segment_offset];
// }
// }
if (segment_index > 6)
return 0xFFFF;
if (segment_index == 5) {
if (segment_offset >= 0xe000)
return 0xFFFF;
}
if (emulator.chipset.remap)
return le_read(rom[offset + (segment_index == 0 && segment_offset < 0x200) ? 0xFE00 : 0]);
else
Expand Down
16 changes: 15 additions & 1 deletion cw2kbd/CasioInternal/Static.cs
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,21 @@ public static byte[] ConvertHexStringToBytes(string hexString)
{
bytes[i / 2] = Convert.ToByte(hexString.Substring(i, 2), 16);
}
return bytes;
Console.WriteLine("[ + ] Build payload:");
int j = 0;
while (true)
{
for (int i = 0; i < 16; i++)
{
if (j >= bytes.Length)
{
Console.WriteLine();
return bytes;
}
Console.Write($"{bytes[j++]:X2} ");
}
Console.WriteLine();
}
}

public static void ApplyPatch(byte* rom, byte[] patch)
Expand Down
143 changes: 102 additions & 41 deletions cw2kbd/Program.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
using static cw2tools.CasioInternal.Static;
Console.WriteLine("cw2kbd by telecomadm1145");
Console.WriteLine("Emulator rom keyboard patcher");
Console.WriteLine("[ + ] cw2kbd by telecomadm1145");
Console.WriteLine("[ + ] Emulator rom keyboard patcher");
string BL(nint func)
{
return $"01 F{(func >> 16) & 0xf:X} {func & 0xff:X2} {(func >> 8) & 0xff:X2}";
Expand All @@ -9,48 +9,57 @@ string B(nint func)
{
return $"00 F{(func >> 16) & 0xf:X} {func & 0xff:X2} {(func >> 8) & 0xff:X2}";
}
unsafe nint CheckSignature(nint signature, string description)
{
if (signature == 0)
{
Console.WriteLine($"[ x ] Signature not found for {description}");
// Handle the error appropriately, e.g., throw an exception or set a default value
throw new Exception($"Signature not found for {description}");
}
else
{
Console.WriteLine($"[ + ] {description}:{signature - (nint)rom:X6}");
}
return signature;
}

unsafe
{
byte* rom = stackalloc byte[0x70000];
byte* rom = stackalloc byte[0x80000];
using (var fs = File.OpenRead("rom.bin"))
_ = fs.Read(new Span<byte>(rom, 0x60000));
var ki_mask_0xff = FindSignature(rom, 0x60000, "ff 00 11 90 42 f0 1f fe");
ki_mask_0xff -= (nint)rom;
var ko_0_0x7f = FindSignature(rom, 0x60000, "7f 00 11 90 46 f0 1f fe");
ko_0_0x7f -= (nint)rom;
var delay = FindSignature(rom, 0x60000, "ce f8 05 f2 91 a0 0a f0 35 c8");
delay -= (nint)rom;
_ = fs.Read(new Span<byte>(rom, 0x80000));
var ki_mask_0xff = CheckSignature(FindSignature(rom, 0x60000, "ff 00 11 90 42 f0 1f fe") - (nint)rom, "ki_mask_0xff");
var ko_0_0x7f = CheckSignature(FindSignature(rom, 0x60000, "7f 00 11 90 46 f0 1f fe") - (nint)rom, "ko_0_0x7f");
var delay = CheckSignature(FindSignature(rom, 0x60000, "ce f8 05 f2 91 a0 0a f0 35 c8") - (nint)rom, "delay");
var reset_timer = delay + 0x7a;
var tick = FindSignature(rom, 0x60000, "ce f8 01 ?? ?? ?? 05 f8 0b f0 00 03 3f fe 08 92 00 03 20 84 00 05 08 90 ff 02 00 01 04 e2");
tick -= (nint)rom;
var is_key_available = FindSignature(rom, 0x60000, "1e 00 ff 10 fe c8 7f 00 11 90 46 f0 00 e0 10 92 40 f0 ff 72 00 60 1f fe");
is_key_available -= (nint)rom;
var ko_0 = FindSignature(rom, 0x60000, "00 02 11 92 46 f0 1f fe");
ko_0 -= (nint)rom;
var ki_mask_0 = FindSignature(rom, 0x60000, "00 00 11 90 42 f0 1f fe");
ki_mask_0 -= (nint)rom;
//var scan_key = FindSignature(rom, 0x60000, "ce f8 01 ?? ?? ?? 05 f8 01 ?? 01 ?? 01 ?? 11 ?? 46 f0");
//scan_key -= (nint)rom;
//var key_debounce = FindSignature(rom, 0x60000, "ce f8 01 ?? ?? ?? 05 f8 01 07 00 05 01 06 0a e0 01 ?? ?? ?? 88 90 01 00 11 90 46 f0 10 90 40 f0 ff 40 00 84");
//key_debounce -= (nint)rom;
var exit = FindSignature(rom, 0x60000, "ea a1 2e f4 3e f8 8e f2");
exit -= (nint)rom;
var enter = FindSignature(rom, 0x60000, "7e f8 6e f4 1a ae 1f fe");
enter -= (nint)rom;
var get_kiko_emu = (byte*)FindSignature(rom, 0x60000, $"ce f8 {BL(enter)} fe e1 f4 04 01 05 07 ce");
var tick = CheckSignature(FindSignature(rom, 0x60000, "ce f8 01 ?? ?? ?? 05 f8 0b f0 00 03 3f fe 08 92 00 03 20 84 00 05 08 90 ff 02 00 01 04 e2") - (nint)rom, "tick");
var is_key_available = CheckSignature(FindSignature(rom, 0x60000, "1e 00 ff 10 fe c8 7f 00 11 90 46 f0 00 e0 10 92 40 f0 ff 72 00 60 1f fe") - (nint)rom, "is_key_available");
var ko_0 = CheckSignature(FindSignature(rom, 0x60000, "00 02 11 92 46 f0 1f fe") - (nint)rom, "ko_0");
var ki_mask_0 = CheckSignature(FindSignature(rom, 0x60000, "00 00 11 90 42 f0 1f fe") - (nint)rom, "ki_mask_0");
var exit = CheckSignature(FindSignature(rom, 0x60000, "ea a1 2e f4 3e f8 8e f2") - (nint)rom, "exit");
var enter = CheckSignature(FindSignature(rom, 0x60000, "7e f8 6e f4 1a ae 1f fe") - (nint)rom, "enter");

var get_kiko_emu = (byte*)CheckSignature(FindSignature(rom, 0x60000, $"ce f8 {BL(enter)} fe e1 f4 04 01 05 07 ce"), "get_kiko_emu");
var scan_key = ((get_kiko_emu[0x39] & 0xf) << 16) | (get_kiko_emu[0x3a] & 0xff) | ((get_kiko_emu[0x3b] & 0xff) << 8);

if (get_kiko_emu[0x38] != 1 && ((get_kiko_emu[0x39] & 0xf0) != 0xf0))
{
Console.WriteLine("shet");
return;
Console.WriteLine("[ x ] Invalid get_kiko_emu data");
// Handle the error appropriately
throw new Exception("Invalid get_kiko_emu data");
}

var key_debounce = ((get_kiko_emu[0x45] & 0xf) << 16) | (get_kiko_emu[0x46] & 0xff) | ((get_kiko_emu[0x47] & 0xff) << 8);

if (get_kiko_emu[0x44] != 1 && ((get_kiko_emu[0x45] & 0xf0) != 0xf0))
{
Console.WriteLine("shet");
return;
Console.WriteLine("[ x ] Invalid get_kiko_emu data");
// Handle the error appropriately
throw new Exception("Invalid get_kiko_emu data");
}
var sleep = FindSignature(rom, 0x60000, "0c f0 14 f0 30 90 fd 20 31 90 0c f0 08 f0 50 00 a0 01 31 90 51 91 02 00 31 90 8f fe 8f fe 1f fe");

var sleep = CheckSignature(FindSignature(rom, 0x60000, "0c f0 14 f0 30 90 fd 20 31 90 0c f0 08 f0 50 00 a0 01 31 90 51 91 02 00 31 90 8f fe 8f fe 1f fe") - (nint)rom, "sleep");
sleep -= (nint)rom;
var key_func = $"""
ce f8
Expand Down Expand Up @@ -82,35 +91,87 @@ dc ce
{B(exit)}
""";
byte[] patch = ConvertHexStringToBytes(key_func);
var wait_kiko_v2 = 0x5fe00; // 安排在0x5fe00 避免冲突(
var wait_kiko_v2 = 0x5c000;
ApplyPatch(rom + wait_kiko_v2, patch);
Console.WriteLine($"[ + ] Wrote wait_kiko_v2 to {wait_kiko_v2:X6}");
var emu_scan_key_1 = FindSignature(rom, 0x60000, $"e5 f0 fa 10 fc 61 {BL(tick)} a0 00 0f 01 {BL(delay)}");
var scan_key_patch = $"""
Console.WriteLine($"[ * ] emu_scan_key patch point: {(byte*)emu_scan_key_1 - rom:X4}");
if (emu_scan_key_1 != 0)
{
var scan_key_patch = $"""
00 00 00 01
13 90 e0 91
e5 f0 fa 10 fc 61
{BL(wait_kiko_v2)}
00 30 00 30 00 30 00 30 00 30 00 30 00 30 00 30 12 90 e0 91 83 90 00 30 13 80
""";
byte[] patch2 = ConvertHexStringToBytes(scan_key_patch);
ApplyPatch((byte*)emu_scan_key_1, patch2);
var scan_key_patch2 = $"""
byte[] patch2 = ConvertHexStringToBytes(scan_key_patch);
ApplyPatch((byte*)emu_scan_key_1, patch2);
var scan_key_patch2 = $"""
01 00 11 90 c9 91 00 30 00 30 00 30 00 30 00 30 00 30 00 30 00 30 00 30 00 30 00 30 00 30 00 30 00 30 00 30 00 30 00 30 00 30 00 30 00 30 00 30 00 30
""";
byte[] patch3 = ConvertHexStringToBytes(scan_key_patch2);
ApplyPatch((byte*)emu_scan_key_1 + 0x3c, patch3);
byte[] patch3 = ConvertHexStringToBytes(scan_key_patch2);
ApplyPatch((byte*)emu_scan_key_1 + 0x3c, patch3);
Console.WriteLine("[ + ] Patched emu_scan_key.");
}

var exicon_func = FindSignature(rom, 0x60000, "03 00 11 90 18 f0 1f fe");
Console.WriteLine($"[ * ] exicon setup: {(byte*)exicon_func - rom:X4}");
if (exicon_func != 0)
{
*(byte*)exicon_func = 0;
Console.WriteLine("[ + ] Patched exicon setup.");
}

var render_copy = (byte*)FindSignature(rom, 0x60000, $"ce f8 {BL(enter)} fa e1 00 88 00 00 11 90 fc 91 10 90 08 92");
Console.WriteLine($"[ * ] render_copy: {render_copy - rom:X4}");
if (render_copy != null)
{
render_copy[0x6c] = 0xf8;
render_copy[0x6e] = 0;
Console.WriteLine($"[ + ] Patched render_copy.");
}

var formula_evaling = (byte*)FindSignature(rom, 0x60000, $"ce f8 5e f4 ?? 04 8e 05 04 02 08 e3 41 92 a0 00 0f 01 {BL(delay)} 1e f4 8e f2");
Console.WriteLine($"[ * ] unknown: {formula_evaling - rom:X4}");
if (formula_evaling != null)
{
ApplyPatch(formula_evaling, ConvertHexStringToBytes("""
1f fe
"""));
Console.WriteLine($"[ + ] Patched unknown.");
}
var is_ac_pressed = (byte*)FindSignature(rom, 0x60000, $"ce f8 5e f4 ?? 04 8e 05 08 02 08 e3 41 92 a0 00 0f 01 {BL(delay)} 00 e0");
Console.WriteLine($"[ * ] is_ac_pressed: {is_ac_pressed - rom:X4}");
if (is_ac_pressed != null)
{
ApplyPatch(is_ac_pressed, ConvertHexStringToBytes("""
10 00 11 90 46 f0 04 00 11 90 42 f0
a1 a0 40 f0
02 c9
00 00
1f fe
01 00
1f fe
"""));
Console.WriteLine($"[ + ] Patched is_ac_pressed.");
}
// Save the modified ROM
var memcpy_far = FindSignature(rom, 0x60000, "5e fe 1a ae 6e f8 6e f4 5e fc 05 f8 20 8a 05 f4 20 86 42 b0 05 fc 0a ce 45 f0 c0 93 6f 90 41 93 81 e0 05 f4 81 ec 44 b0 ff e0 c4 b0 00 e0 44 b2 27 f0 f2 c1 85 f0 a0 82 1e fc 2e f4 2e f8 ea a1 1e fe");
if (memcpy_far != 0)
{
memcpy_far -= (nint)rom;
Console.WriteLine($"[ + ] memcpy_far: {memcpy_far:X4}");
byte* memcpy_far_caller = rom;
nint size = 0x60000;
while ((memcpy_far_caller = (byte*)FindSignature(memcpy_far_caller, size, $"00 00 90 01 08 02 {BL(memcpy_far)}")) != null)
{
Console.WriteLine($"[ + ] memcpy_far caller: {memcpy_far_caller - rom:X4}");
size = (nint)(0x60000 - (memcpy_far_caller - rom));
memcpy_far_caller[0x2] = 0xf8;
memcpy_far_caller[0x4] = 0;
}
}

using (var fs = File.OpenWrite("rom_patched.bin"))
fs.Write(new Span<byte>(rom, 0x60000));
fs.Write(new Span<byte>(rom, 0x80000));
}
1 change: 1 addition & 0 deletions cw2menu_ui/CasioInternal/Static.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ public static byte GetByte(byte* pattern)
}
public static IntPtr FindSignature(byte* start, nint size, string signature)
{
signature = signature.ToUpper();
byte* pattern = (byte*)Marshal.StringToHGlobalAnsi(signature).ToPointer();
byte* oldPat = pattern;
byte* end = start + size;
Expand Down
6 changes: 1 addition & 5 deletions cw2menu_ui/FontWindow.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,7 @@ private WriteableBitmap Clip2(nint bs, int index, int width, int height)
private void Set(nint bs, int index, int width, int height, BitmapSource src)
{
byte* data = stackalloc byte[height * width * 4];
src.CopyPixels(new Int32Rect(0, 0, width, height), (nint)data, height * width * 4, width * 4);
src.CopyPixels(new Int32Rect(0, 0, Math.Min(src.PixelWidth, width),Math.Min(src.PixelHeight, height)), (nint)data, height * width * 4, width * 4);
ushort* buf = (ushort*)(rom + bs);
{
// 这是一个周期性问题,我们有 index*width,我们期望转换成16*index2 + n
Expand Down Expand Up @@ -646,10 +646,6 @@ private BitmapImage LoadBitmap(Stream s)
}
private void Button_Click_3(object sender, RoutedEventArgs e)
{
if (!Path.Exists("00"))
{
throw new Exception("Please put fonts in this style \".\\??\\??.png\".");
}
switch (font_type)
{
case 0:
Expand Down
24 changes: 24 additions & 0 deletions cw2menu_ui/LocalStrings.xaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<Window x:Class="cw2tools.LocalStrings"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:cw2tools"
mc:Ignorable="d"
Title="LocalStrings" Height="450" Width="800">
<StackPanel>
<TextBlock Text="语言LUT"/>
<TextBox x:Name="LUT" HorizontalAlignment="Left" Width="100"/>
<Button Content="查找" HorizontalAlignment="Left" Click="Button_Click"/>
<TextBlock Text="语言代码"/>
<TextBox x:Name="LanguageCode" HorizontalAlignment="Left" Width="100" Text="0"/>
<TextBlock Text="字符串表"/>
<TextBox x:Name="StringLut" HorizontalAlignment="Left" Width="100"/>
<Button Content="查表" HorizontalAlignment="Left" Click="Button_Click_1"/>
<Button Content="导出 csv" HorizontalAlignment="Left" Click="Button_Click_2"/>
<TextBlock Text="字符串池基址"/>
<TextBox x:Name="StringsBase" HorizontalAlignment="Left" Width="100"/>
<Button Content="导入 csv(字符串池法)" HorizontalAlignment="Left"/>
<Button Content="导入 csv(就地替换)" HorizontalAlignment="Left"/>
</StackPanel>
</Window>
46 changes: 46 additions & 0 deletions cw2menu_ui/LocalStrings.xaml.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using static cw2tools.CasioInternal.Static;
using static cw2tools.CasioInternal.Strings;

namespace cw2tools
{
/// <summary>
/// LocalStrings.xaml 的交互逻辑
/// </summary>
public unsafe partial class LocalStrings : Window
{
public LocalStrings()
{
InitializeComponent();
}

private void Button_Click(object sender, RoutedEventArgs e)
{
LUT.Text = $"{LookupLangauge():X4}";
}

private void Button_Click_1(object sender, RoutedEventArgs e)
{
var lut = Convert.ToUInt32(LUT.Text);
var code = Convert.ToUInt32(LanguageCode.Text);
StringLut.Text = $"{((ushort*)lut)[code]:X4}";
}

private void Button_Click_2(object sender, RoutedEventArgs e)
{

}
}
}

0 comments on commit 0142121

Please sign in to comment.