HP Prime High-Level Emulator
基于 Unicorn Engine 构建的 HP Prime 计算器 HLE 模拟器
中文 | English
PrimU2 是一个面向 HP Prime 图形计算器(V1 / V2 / G1)的高级别模拟器(HLE, High-Level Emulator)。与全系统模拟不同,PrimU2 通过拦截固件的系统服务调用(SVC)并在主机上直接实现这些调用来运行计算器固件,从而避免了对底层硬件的完整模拟。
核心 CPU 仿真由 Unicorn Engine 提供,PrimU2 在此基础上叠加了内存管理、文件系统虚拟化、多线程调度、LCD 显示和输入处理等较高层次的抽象。
注意: PrimU2 目前仅针对 HP Prime 固件版本 20250915 进行测试,其他版本不受官方支持。
| 模块 | 说明 |
|---|---|
| ELF 加载器 | 解析并加载 ARM ELF 可执行文件(armfir.elf)到虚拟地址空间 |
| PE 加载器 | 支持加载 PE(DLL)映像,处理节映射、导入/导出表解析及重定位 |
| 虚拟文件系统 | 将固件文件操作映射到主机 .\prime_data 目录,支持 ANSI / Unicode 路径 |
| LCD 显示 | 模拟 320×240 RGB565 LCD,生成独立 Win32 窗口实时渲染帧缓冲区 |
| 多线程 | 每个 guest 线程拥有独立的 Unicorn 引擎实例,共享内存映射,由原生 std::thread 驱动 |
| 同步原语 | Event、Semaphore、Critical Section 的创建 / 等待 / 释放 |
| 内存管理 | 静态映射 + 32 MB 动态堆(带邻接空闲块合并的简单分配器) |
| SVC 服务表 | 700+ 系统服务 ID 定义,数十个关键 handler 已实现 |
| 输入处理 | 键盘映射(VK → 设备键码)及触摸事件注入 |
| 电源管理 | 关机 / 电池检查的模拟 |
| 系统时间 | 将主机时间映射为 guest SYSTEMTIME 结构 |
| INI 配置 | GetPrivateProfileString / WritePrivateProfileString |
| 文件查找 | findfirst / findnext / findclose,DOS 风格通配符匹配 |
| PE DLL 加载 | LoadLibrary / FreeLibrary / GetProcAddress 等 |
| PC 连接套件 | 通过 Named Pipe 桥接实现与 HP 连接套件的通信(HpInterOp) |
| 调试工具 | SVC 调用日志窗口、内存查看器、执行块追踪器(基于 ImGui) |
| 模块 | 说明 |
|---|---|
| GDI 绘图 API | DrawLine、FillRect、DrawCircle 等图形原语 |
| 中断子系统 | 定时器中断、硬件中断分发 |
| 电池 API | 电池类型检测、精确电量模拟 |
| 外部调试器 | 远程 GDB/GDBStub 接口 |
| 跨平台支持 | 当前仅支持 Windows(依赖 Win32 API、MSVC) |
| USB Device | USB OTG 子系统(系统原生仅支持 HID) |
┌──────────────────────────────────────────────────────────────┐
│ PrimU2 Host │
│ ┌──────────┐ ┌──────────────────┐ ┌────────────────────┐ │
│ │ ELF/PE │ │ Unicorn Engine │ │ LCD Window │ │
│ │ Loader │──│ (ARM emulation) │──│ (Win32 + ImGui) │ │
│ └──────────┘ └────────┬─────────┘ └────────────────────┘ │
│ │ SVC trap │
│ ┌─────────▼──────────┐ │
│ │ Interrupt Hook │ │
│ │ (SVC dispatcher) │ │
│ └─────────┬──────────┘ │
│ ┌─────────────────┼─────────────────┐ │
│ ▼ ▼ ▼ │
│ ┌─────────┐ ┌──────────────┐ ┌───────────┐ │
│ │ Thread │ │ Filesystem │ │ System │ │
│ │ Manager │ │ (VFS) │ │ Services │ │
│ └─────────┘ └──────────────┘ └───────────┘ │
│ │ │ │ │
│ ▼ ▼ ▼ │
│ ┌─────────┐ ┌──────────────┐ ┌───────────┐ │
│ │ Sync │ │ Host FS │ │ Memory │ │
│ │Primitive│ │ (prime_data) │ │ Manager │ │
│ └─────────┘ └──────────────┘ └───────────┘ │
└──────────────────────────────────────────────────────────────┘
| 文件 | 职责 |
|---|---|
PrimU.cpp |
程序入口,加载 ELF、初始化 Executor 并启动执行 |
executor.cpp/h |
核心执行器(Singleton),管理 Unicorn 实例、中断钩子和执行循环 |
executable.cpp/h |
ELF 可执行文件的加载和解析 |
PELoader.cpp/h |
PE 映像的加载、节映射和导入解析 |
MemoryManager.cpp/h |
虚拟内存管理:静态映射 + 动态堆分配 |
Thread.cpp/h |
Guest 线程抽象,每线程一个 Unicorn 实例 |
ThreadHandler.cpp/h |
线程生命周期管理(StateManager) |
SyncPrimitives.h |
同步原语抽象接口(IEvent、ISemaphore、ICriticalSection) |
Win32SyncPrimitives.h |
基于 Win32 API 的同步原语具体实现 |
Services.cpp |
SVC 服务注册表,连接 SVC ID 与 handler 函数 |
svc_filesystem.cpp |
文件 I/O、目录操作、INI、文件查找 handler |
svc_system.cpp |
LCD、内存分配、系统时间、电源、事件输入、程序管理 handler |
svc_thread.cpp |
线程创建 / 调度、同步原语操作 handler |
svc_common.cpp/h |
VMPath 路径映射、VFileSystem 虚拟文件系统公共基础设施 |
LCD.cpp/h |
LCD 帧缓冲模拟、Win32 窗口创建和渲染 |
HpInterOp.cpp |
PC 连接套件桥接,通过 Named Pipe 与 HP 连接套件通信 |
interrupts.h |
700+ 系统服务 ID 枚举定义 |
ui.h |
键码定义、事件结构体和输入系统 |
Marshal.h |
SVC 参数提取和类型安全的 AutoBind 模板 |
| 库 | 用途 | 版本 |
|---|---|---|
| Unicorn Engine | ARM CPU 仿真 | 已包含预编译库 |
| Capstone | 反汇编引擎(用于调试追踪) | 已包含预编译库 |
| ELFIO | ELF 文件解析 | 已包含头文件 |
| Dear ImGui | 调试 GUI(SVC 日志、内存查看器等) | 已包含源码 |
| SDL2 | ImGui 后端渲染 | 已包含源码 |
所有依赖已包含在
dependencies/、include/和lib/目录中,无需额外下载。
- 操作系统: Windows 10 / 11(x64)
- 编译器: Visual Studio 2022 或更高版本
- 平台: x64(推荐)或 x86
-
克隆仓库:
git clone https://github.com/telecomadm1145/PrimeU2.git cd PrimeU2 -
使用 Visual Studio 打开
PrimU.sln。 -
选择
Release | x64配置。 -
生成解决方案(
Ctrl+Shift+B)。
你需要从 HP Prime 固件更新文件(版本 20250915)中提取「Disk A」。
Disk A 位于固件更新文件内部:
APPDISK.DAT文件包含一个 FAT-16 文件系统,起始于 8 KB 偏移处。使用合适的工具(如 7z)挂载或提取该文件系统以获得「Disk A」的内容。更多详情请参阅 HP Prime 固件 Wiki: https://tiplanet.org/hpwiki/index.php?title=HP_Prime/Firmware_files
将提取的 Disk A 内容放入 .\prime_data\A 目录:
PrimU2/
├── PrimU.exe
├── prime_data/
│ └── A/
│ └── programs/
│ └── misc/
│ └── armfir.elf ← 固件主程序
│ └── ...
│ └── ...
└── ...
PrimU.exe程序将自动加载 prime_data\A\programs\misc\armfir.elf 并开始执行。如果一切正常,将会弹出一个 LCD 窗口显示计算器的画面。
模拟器将 PC 键盘按键映射到 HP Prime 的物理按键:
| PC 按键 | HP Prime 功能 |
|---|---|
Esc |
ESC |
↑ ↓ ← → |
方向键 |
Enter |
ENTER |
Backspace |
DEL |
0-9 |
数字键 |
F1-F5 |
软键 F1-F5 |
M |
APPS |
B |
HOME |
K |
PLOT |
L |
NUM |
Z |
VIEW |
C |
CAS |
V |
ALPHA |
LCD 窗口还支持直接鼠标触摸交互和虚拟按键面板。
PrimU2 内置了基于 ImGui 的调试工具集:
- SVC 调用日志: 实时记录所有系统服务调用,包括调用 ID、参数和返回值
- 内存查看器: 使用
imgui_memory_editor检查虚拟地址空间 - 执行块追踪器: 记录基本块的执行历史
- 栈回溯: 发生异常时使用 Capstone 反汇编引擎生成调用栈信息
PrimeU-master/
├── PrimU.sln # Visual Studio 解决方案
├── PrimU/ # 主项目目录
│ ├── PrimU.cpp # 入口
│ ├── executor.cpp/h # 核心执行器
│ ├── executable.cpp/h # ELF 加载器
│ ├── PELoader.cpp/h # PE 加载器
│ ├── MemoryManager.cpp/h # 内存管理
│ ├── Thread.cpp/h # 线程抽象
│ ├── ThreadHandler.cpp/h # 线程管理器
│ ├── SyncPrimitives.h # 同步原语接口
│ ├── Win32SyncPrimitives.h # Win32 同步实现
│ ├── LCD.cpp/h # LCD 显示
│ ├── Services.cpp/h # 服务注册表
│ ├── svc_filesystem.cpp # 文件系统 handler
│ ├── svc_system.cpp # 系统服务 handler
│ ├── svc_thread.cpp # 线程服务 handler
│ ├── svc_common.cpp/h # 公共基础设施
│ ├── HpInterOp.cpp # PC 连接套件桥接
│ ├── interrupts.h # SVC ID 定义
│ ├── ui.h # 键码和事件定义
│ ├── Marshal.h # 参数提取模板
│ ├── handlers.h # Handler 声明汇总
│ └── syscalls_sdk.json # SVC ID ↔ 名称映射(参考)
├── dependencies/ # 第三方依赖
│ ├── imgui/ # Dear ImGui 源码
│ └── sdl/ # SDL2 源码
├── include/ # 头文件
│ ├── unicorn/ # Unicorn Engine 头文件
│ ├── elfio/ # ELFIO 头文件
│ └── capstone/ # Capstone 头文件
├── lib/ # 预编译库
│ ├── unicorn.dll/lib/a
│ └── capstone.dll/lib
└── LICENSE # GPL v2
-
加载:
Executable类解析 ARM ELF 文件(armfir.elf),将各段映射到 Unicorn 的虚拟地址空间。 -
初始化:
Executor创建主 Unicorn 实例,分配栈空间和动态堆,注册中断钩子。 -
执行:当 guest 代码执行
SVC指令时,Unicorn 触发中断回调,interrupt_hook根据 SVC 号查表派发到对应的 handler 函数。 -
服务分发:700+ 个 SVC 服务 ID(
0x10000~0x102E5)定义了文件 I/O、内存分配、线程管理、LCD 控制等全部操作系统 API。 -
多线程:每个 guest 线程通过
std::thread运行在独立的 Unicorn 实例上,通过共享MemoryManager中的物理内存映射实现内存共享。 -
显示:LCD handler 在 Win32 窗口中渲染 guest 帧缓冲区的内容,支持键盘和触摸输入回传到 guest 事件队列。
- PrimeU — 原始 PrimeU 项目
- qemuPrime — 基于 QEMU 的 HP Prime 模拟
- ripem — HP Prime 系统替换(停止维护)
- Linux-For-HPPrime-V2 — 在 HP Prime V2 上运行 Linux
- prinux (G2) — HP Prime G2 上的 Linux
- Project-Muteki — Besta/Muteki 平台逆向工程与开发
本项目基于 GNU General Public License v2 (GPL-2.0) 发布。
详见 LICENSE 文件。