【摄影】Nikon F90X/N90s F90/N90系列胶片相机串口通信协议逆向项目

基于尼康官方软件AC-PW,提取其核心 Pcf9032.dll逆向
由 DeepSeek 4.0 Pro 辅助完成。


第一章 概述

1.1 适用范围

本报告完整描述 F90X/N90s F90/N90 胶片单反相机通过串行接口与计算机通信的底层协议、命令集、寄存器映射、功能编号及所有操作序列。所有内容均来自对官方控制库 Pcf9032.dll 及配套软件 PhotoSecretary的逆向分析,并通过资源提取进行验证。

1.2 通信架构

  • 物理层:RS-232C 串行通信,5V 电平
  • 波特率:初始 1200 bps,握手后切换至 9600 bps
  • 数据格式:8 数据位,无校验,1 停止位 (8N1)
  • 端口选择:COM1~COM4,由功能 ID 0 设定
  • DLL 文件:Pcf9032.dll(Nikon 相机通信库),由主程序动态加载

1.3 相机型号识别

型号标识相机返回字符串地址字节对应型号
1F90N900x10F90系列/N90(北美发售型号)系列
2F90xN90s0x20F90X系列/N90S(北美发售型号)系列

第二章 通信初始化

2.1 唤醒与型号识别

  1. 打开串口 COM%d,配置为 1200,8N1。
  2. 发送唤醒字节:00(1 字节),等待 200ms,清空接收缓冲区。
  3. 发送型号查询:53 31 30 30 30 05S1000 + ENQ,共 6 字节)。
  4. 接收相机返回的标识字符串(例如 31 30 32 30 46 39 30 58 2F 4E 39 30 53 00 03 06 表示 1020F90X/N90S)。
  5. 根据字符串确定型号:
    • 若包含 F90N90 → 型号 1,地址字节 0x10。
    • 若包含 F90xN90s → 型号 2,地址字节 0x20。

2.2 波特率升级至 9600

  1. 发送 9 字节命令(型号 1 用 0x10,型号 2 用 0x20):
    01 10 87 05 00 00 00 00 03 或 01 20 87 05 00 00 00 00 03
  2. 等待相机应答 06 00(ACK)。
  3. 将本地串口切换为 9600 bps,等待 200ms 稳定。

2.3 结束 9600 会话(返回 1200)

  • 发送 04 04(EOT 两次),相机返回 04 04 确认,然后串口恢复到 1200。
  • 若相机自动休眠,波特率也会自动降回 1200。

第三章 通信帧格式

校验和仅计算纯数据部分,即从 STX (0x02) 之后的第一个字节开始,到 ETX (0x03) 之前的所有字节,不包括帧头(SOH)、地址、命令码、长度字段等任何头部字节。

波特率切换等特殊握手指令会使用 0x87 作为操作码,此类特殊指令属于硬编码控制帧,不完全遵循常规寄存器读写帧的载荷结构。

3.1 标准命令帧(命令码 ≤ 100)

读请求(无数据)

偏移 大小 值       说明
0 1 0x01 帧头 (SOH)
1 1 ADDR 设备地址 (0x10 或 0x20)
2 1 0x80 读操作
3 1 0x00 保留
4 1 v6 寄存器地址高字节
5 1 v7 寄存器地址低字节
6 1 0x00 保留
7 1 len 期望接收的数据长度
8 1 0x03 帧尾 (ETX)

总长 9 字节,无校验。

写请求(有数据)

偏移 大小 值       说明
0    1    0x01     帧头
1    1    ADDR     设备地址
2    1    0x81     写操作
3    1    0x00     保留
4    1    v6       寄存器地址高字节
5    1    v7       寄存器地址低字节
6    1    0x00     保留
7    1    len      数据长度(实际发送字节数)
8    1    0x02     数据起始标识 (STX)
9~   len   DATA    数据体
9+len  1   CHK     校验和(所有 DATA 字节累加和的低 8 位)
10+len 1   0x03     帧尾 (ETX)
11+len 1   0x00     填充

总长 12 + len 字节。

3.2 扩展命令帧(命令码 > 100)

读请求

偏移 大小 值       说明
0    1    0x01     帧头
1    1    ADDR     设备地址
2    1    0x1B     命令组标识
3    1    0x90     命令组标识
4    1    0x82     读操作
5    1    v6       参数(由命令码决定)
6    1    len      期望接收长度
7    1    0x00     保留
8    1    0x03     帧尾

总长 9 字节。

写请求

偏移 大小 值       说明
0    1    0x01     帧头
1    1    ADDR     设备地址
2    1    0x1B     命令组标识
3    1    0x90     命令组标识
4    1    0x81     写操作
5    1    v6       参数
6    1    len      数据长度
7~   len   DATA    数据体
7+len 1    CHK     校验和
8+len 1    0x03     帧尾
9+len 1    0x00     填充

总长 10 + len 字节。

3.3 应答帧

  • 短应答(ACK)06 00 表示成功。
  • 特殊同步应答04 04 用于同步。
  • 长应答(数据包)
    • 字节 0:状态码(通常忽略,或为 0x01)
    • 字节 1~(n-2):数据
    • 字节 (n-1):校验和(字节 1 到字节 n-2 的累加和低 8 位)
    • 字节 n:0x03 (ETX)

3.4 重试机制

发送命令后,最多重试 4 次(外层循环)× 4 次(内层发送尝试)。每次发送失败等待 200ms,若连续 4 次内层失败则退出内层;内层结束后等待 150ms 再进入下一次外循环。


第四章 命令码与寄存器地址映射表

4.1 标准命令码表(≤100)

从 DLL 函数 sub_1000DB73 的 switch 分支提取。v6v7 以十六进制补码表示(负值转换为无符号字节,例 -3 = 0xFD)。

命令码v6 (hex)v7 (hex)寄存器地址常用数据长度方向关联功能ID
0FD19FD191读/写
1FD17FD172(读)/6(写)读/写
2FD1AFD1A1读/写
3FD1CFD1C1读/写
4FD1BFD1B1读/写
5FD16FD161读/写
6FD28FD28113
7FD26FD26114,15,16
8FD27FD27114,15,16
9FD29FD29118
10FD2BFD2B120
11FD2AFD2A119
12FD2DFD2D121
13FD2EFD2E126
14FD21FD211
15FD2CFD2C122,23
16FE44FE442读/写
17FEC9/C1FE?1型号相关
18FD20FD201读/写0x64,0x66
19FD39FD391读/写
20FD3AFD3A1读/写0x64,0x66
21FD3BFD3B1读/写0x64
22FD3CFD3C2读/写0x64
23FED0FED01用户设置
24FDF2FDF22用户设置
25FDF3FDF31读/写
26FE94FE942用户设置
27FE95FE951读/写
28FE9EFE9E1用户设置
29FD25FD25117
30FD36FD363读/写90-95
31FEC8FEC81用户设置
32FD33FD333(型号1)读/写0x46-0x52
33FD34FD341状态检测
34FD40FD401读/写131
35FD30FD306(型号2)读/写0x46-0x52
36FD41FD413读/写
37FD24FD241状态查询
38FE50FE501状态检测
39FE20FE201读/写
40FEDB/D4FE?1型号相关
41FD93/8EFD?1型号相关
42FD9D/90FD?1型号相关
43FE06FE061
44FD1FFD1F10x64

4.2 扩展命令码表(>100)

从 sub_1000DED3 的 switch 提取,命令码对应 ASCII 字符,v6 为帧内参数。

命令码ASCIIv6 (hex)常用数据长度方向
101‘e’003
102‘f’065
103‘g’101
118‘v’701读/写
119‘w’722读/写
122‘z’801

第五章 功能 ID 完整映射

5.1 设定/读取函数导出索引

导出序号函数名用途
1FeatureExists检查功能ID是否有效
2GetIndexString获取功能选项文本
3GetMaxIndex获取选项最大索引
8GetValueBool读取布尔型参数
9GetValueFloat未实现
10GetValueIndex读取索引型参数
11GetValueInteger读取整型参数
12GetValueString读取字符串参数
13GetValueStruct读取结构体参数
14InvalidateReads清除读取缓存
15SetValueBool设置布尔型参数
16SetValueFloat未实现
17SetValueIndex设置索引型参数
18SetValueInteger设置整型参数
19SetValueString设置字符串参数
20SetValueStruct设置结构体参数
21StartProcess执行动作(拍摄、对焦、删除等)
23WriteDataToCamera将修改的参数写入相机

5.2 功能 ID → 命令/寄存器映射

以下列出全部功能 ID(0~147)的精确技术映射,包括类型、设置/读取函数、所属 WriteDataToCamera 的 case、具体的命令码、寄存器地址(v6, v7)或扩展命令标识,以及在配置块中的位操作说明。

功能 ID类型设置函数读取函数Case命令码 / 寄存器操作描述
0IntegerSetValueInteger直接设置全局变量 word_10015218通信端口号 (1~4)
1未使用
2StringGetValueString直接返回相机型号字符串指针相机型号字符串 (“F90N90” 或 “F90xN90s”)
3BoolSetValueBool直接设置 word_100122D4相机型号选择 (0=型号1, 1=型号2)
4IndexGetValueIndex特殊:读取 word_10012170 数组电子手帐数据读取状态/进度
5IntegerGetValueInteger直接读取 dword_10012000内部状态值(只读)
6BoolGetValueBool5通过 sub_10008905 读取 word_100122BC未知布尔状态(只读)
7~12未使用
13IndexSetValueIndexGetValueIndex1命令 6 → FD28测光方式 (0=矩阵, 1=中央重点, 2=点)
14IndexSetValueIndexGetValueIndex1命令 7/8 → FD26, FD27;位操作曝光模式 (0=P,1=S,2=A,3=M,4=CP,5-11=变程序)
15IndexSetValueIndexGetValueIndex1命令 7/8 → FD26, FD27;位操作曝光模式(与14共用寄存器,不同位)
16BoolSetValueBoolGetValueBool1命令 7/8 → FD26, FD27;位操作曝光模式扩展布尔
17IndexSetValueIndexGetValueIndex1命令 29 → FD25快门速度 (B门/定时相关)
18IndexSetValueIndexGetValueIndex1命令 9 → FD29卷片模式 (0=单张, 1=低速连拍, 2=高速连拍)
19IndexSetValueIndexGetValueIndex1命令 11 → FD2A闪光同步模式 (0=前帘,1=慢速,2=后帘,3=防红眼)
20IndexSetValueIndexGetValueIndex1命令 10 → FD2B对焦区域 (0=宽区, 1=点)
21IndexSetValueIndexGetValueIndex1命令 12 → FD2D曝光补偿范围 (-5.0~+5.0 EV)
22BoolSetValueBoolGetValueBool1命令 15 → FD2C;位操作DX/手动 ISO 选择
23IndexSetValueIndexGetValueIndex1命令 15 → FD2CISO 感光度 (0=ISO 6, 1=ISO 8 … 30=ISO 6400)
24IndexGetValueIndex1命令 15 读回 FD2CISO 扩展读取
26IndexSetValueIndexGetValueIndex1命令 13 → FD2E闪光补偿/特殊设定
27~28未使用
29BoolGetValueBool3word_100123F2(通过 sub_100058C7 读取)MF-26 状态(只读)
30BoolGetValueBool3word_100123F4(通过 sub_100058C7 读取)MF-26 状态(只读)
31IndexSetValueIndexGetValueIndex3命令 18,20 等,位操作 FD20, FD3A 等MF-26 曝光模式
32IndexSetValueIndexGetValueIndex3同上MF-26 曝光模式
33IndexSetValueIndexGetValueIndex3命令 6 → FD28测光方式 (MF-26)
34IndexSetValueIndexGetValueIndex3命令 9 → FD29卷片模式 (MF-26)
35IndexSetValueIndexGetValueIndex3命令 11 → FD2A闪光同步模式 (MF-26)
36IndexSetValueIndexGetValueIndex3命令 10 → FD2B对焦区域 (MF-26)
37~39未使用
40IndexSetValueIndexGetValueIndex1/8命令 1 → FD17用户设置库名称
41IndexGetValueIndex1/8命令 1/7 读取用户设置库当前选择
42IndexGetValueIndex8命令 43 → FE06镜头光圈值 (F1~F90)
43IndexSetValueIndexGetValueIndex8命令 43 → FE06 等镜头光圈值(设定)
44IndexSetValueIndexGetValueIndex1命令 9 → FD29卷片模式(另一入口)
45IndexSetValueIndexGetValueIndex8命令 45闪光同步(另一设定)
46BoolSetValueBoolGetValueBool8命令 15 → FD2C位操作对焦模式 (0=手动, 1=AF 等)
47IndexGetValueIndex8命令 47ISO 显示(备用)
48IndexSetValueIndexGetValueIndex8命令 10 → FD2B对焦区域(另一入口)
49IndexSetValueIndexGetValueIndex8命令 49AF 方式 (0=释放优先, 1=对焦优先, 2=手动)
50IndexGetValueIndex8命令 50对焦状态选项
51IndexSetValueIndexGetValueIndex8命令 51对焦状态 (0=前焦,1=后焦,2=合焦,3=无法合焦)
52IndexSetValueIndexGetValueIndex8命令 52ON/OFF 开关
53IndexSetValueIndexGetValueIndex8命令 53曝光补偿值 (-20.0~+20.0)
54IndexSetValueIndexGetValueIndex8命令 54曝光补偿值(另一组)
55IndexSetValueIndexGetValueIndex8命令 55胶片计数器 (E, 0~99)
56IndexSetValueIndexGetValueIndex8命令 56电池状态 (0=满电, 1=低电量)
57IndexGetValueIndex8命令 57特定索引
58IndexGetValueIndex8命令 58曝光补偿范围 (-5.0~+5.0 EV)
59IndexSetValueIndexGetValueIndex8命令 59镜头焦距 (5mm~7600mm)
60IndexSetValueIndexGetValueIndex8命令 60镜头焦距(另一组)
61IndexSetValueIndexGetValueIndex8命令 61镜头焦距(另一组)
62IndexGetValueIndex8命令 62光圈值(另一组)
63IndexGetValueIndex8命令 63特定索引
64IndexGetValueIndex8命令 64光圈值(另一组)
65IndexGetValueIndex1/8命令 1 读取用户库读取
66IndexSetValueIndexGetValueIndex1/8命令 6 → FD28测光方式(另一入口)
67IndexSetValueIndexGetValueIndex8命令 67闪光同步(另一组)
68IndexSetValueIndexGetValueIndex8命令 68镜头焦距(另一组)
69BoolSetValueBoolGetValueBool4配置块位操作 (命令32/35)蜂鸣音开关(恢复默认用)
70 (0x46)BoolSetValueBoolGetValueBool4配置块位操作 (命令32/35)合焦音开关
71 (0x47)BoolSetValueBoolGetValueBool4配置块位操作 (命令32/35)DX 优先设定
72 (0x48)BoolSetValueBoolGetValueBool4配置块位操作 (命令32/35)AE/AF 同时锁定
73 (0x49)BoolSetValueBoolGetValueBool4配置块位操作 (命令32/35)AF-C 对焦优先
74 (0x4A)BoolSetValueBoolGetValueBool4配置块位操作 (命令32/35)AF-S 释放优先
75 (0x4B)BoolSetValueBoolGetValueBool4配置块位操作 (命令32/35)AF-S 帧间 AF 驱动
76 (0x4C)BoolSetValueBoolGetValueBool4配置块位操作 (命令32/35)0 帧数据印记
77 (0x4D)BoolSetValueBoolGetValueBool4配置块位操作 (命令32/35)测光偏差显示
78 (0x4E)BoolSetValueBoolGetValueBool4配置块位操作 (命令32/35)A 模式简易曝光补偿
79 (0x4F)BoolSetValueBoolGetValueBool4配置块位操作 (命令32/35)(保留)
80 (0x50)BoolSetValueBoolGetValueBool4配置块位操作 (命令32/35)闪光灯相关设定
81 (0x51)BoolSetValueBoolGetValueBool4配置块位操作 (命令32/35)闪光灯相关设定
82 (0x52)BoolSetValueBoolGetValueBool4配置块位操作 (命令32/35)闪光灯相关设定
83IndexSetValueIndexGetValueIndex4配置块 (命令32/35)闪光灯模式
84IndexSetValueIndexGetValueIndex4配置块 (命令32/35)长时间曝光时间 (4秒~60秒/B门)
85IndexSetValueIndexGetValueIndex4配置块 (命令32/35)同步释放模式
86IndexSetValueIndexGetValueIndex4配置块 (命令32/35)(预留)
87IndexSetValueIndexGetValueIndex4配置块 (命令32/35)自拍/间隔时间
88StartProcess(0x58) 调用恢复默认设置(操作码)
89StartProcess(0x89) 调用触发拍摄(操作码)
90IndexSetValueIndexGetValueIndex7命令 30 → FD36闪光灯/自定义程序点 (快门)
91IndexSetValueIndexGetValueIndex7命令 30 → FD36闪光灯/自定义程序点 (光圈)
92IndexSetValueIndexGetValueIndex7命令 30 → FD36同上
93IndexSetValueIndexGetValueIndex7命令 30 → FD36同上
94IndexSetValueIndexGetValueIndex7命令 30 → FD36同上
95IndexSetValueIndexGetValueIndex7命令 30 → FD36同上
96StartProcess(0x60) 调用闪光灯操作(操作码)
97IndexGetValueIndex8命令 97微调值
98IndexSetValueIndexGetValueIndex8/11命令 98微调值 (0.3~2.0)
99IndexSetValueIndexGetValueIndex8/11命令 99曝光补偿步长 (-3.0~+1.0)
100Bool8(保留)
101IntegerGetValueInteger8读取多个配置寄存器配置块值(只读)
102~105未使用
106IndexSetValueIndexGetValueIndex9扩展命令 103, 122 等时区城市 (1~24)
107未使用
108Index9扩展命令时区城市(备用)
109IndexSetValueIndexGetValueIndex10扩展命令时差数值 (-10~+12, -11)
110IndexSetValueIndexGetValueIndex10扩展命令时差数值 (-11)
111~114未使用
115IndexGetValueIndex11扩展命令模式选择
116IndexSetValueIndexGetValueIndex11扩展命令微调值 (另一入口)
117未使用
118IndexSetValueIndexGetValueIndex11扩展命令曝光补偿步长 (同 99)
119IndexSetValueIndexGetValueIndex11扩展命令特殊设定(自拍/闪光相关)
120~123未使用
124StructGetValueStruct11扩展命令读取结构体 (2 字段)
125StructGetValueStruct11扩展命令读取结构体 (3 字段)
126未使用
127~12912扩展命令保留
130StructGetValueStruct11扩展命令读取结构体 (3 字段)
131IndexSetValueIndexGetValueIndex5命令 34 → FD40数据存储模式 (0/69/78/95)
132IndexSetValueIndexGetValueIndex5命令 5 → FD34 bit7数据印记 / 特殊设定位
133命令 133(内部全消去)内部使用
134IntegerGetMinMaxInteger只读,范围 0-9999胶片编号
135未使用
136StartProcess(0x88) 调用指针复位/状态初始化
137StartProcess(0x89) 调用触发拍摄(同 89)
138未使用
139IndexGetIndexString6字符串资源自定义功能名称/选项
140~145未使用
146StructGetValueStruct6扩展命令相机信息(型号、序列号等)
147StructGetValueStruct6/5扩展命令对焦数据读取

注释

  • 配置块位操作:功能 ID 69~82 的具体位定义已在第七章详细列出。每个布尔值对应配置块(命令32/35)的某一位,通过读-修改-写流程改变。
  • 扩展命令:功能 ID 106~130 使用命令码 >100 的扩展命令(格式 1B 90 cmd v6 len),具体 v6 和 len 见第四章扩展命令表。
  • 操作码:88, 89, 96, 136, 137 等不直接对应设置/读取函数,而是由 StartProcess 分发执行,内部命令序列已在前文各章详述。
  • 表中粗体为软件中直接面向用户的主要功能。
  • 未使用的功能 ID 在 DLL 中返回错误 2(不支持)。
  • 对于131:
  • 这些值直接写入 FD40 寄存器,对应相机的“数据存储模式”0 (0x00) → 不存储数据(Disabled)
  • 69 (0x45) → 存储最小数据量(Minimum)
  • 78 (0x4E) → 存储中间数据量(Intermediate)
  • 95 (0x5F) → 存储最大数据量(Maximum)
    该映射与我们之前整理的 FD40 寄存器功能一致,且与 DLL 资源中对应的字符串(“記憶しない”、“最小情報量記憶”等)吻合。

第六章 特殊操作流程

6.1 拍摄(快门释放)

  • 操作码:StartProcess(0x89)
  • DLL 函数:sub_10007BB0 → 型号1调用 sub_10007C4B,型号2调用 sub_10007CE0
  • 命令序列(以型号1为例):
    1. 读 FD20FD24FD40 获取状态。
    2. 构造写命令 01 10 81 00 FD 41 00 01 02 <data> <cs> 03 00,数据为 0x42(’B’)及校验。
    3. 等待 ACK,再读 FD20 和 FD24 完成清理。

6.2 自动对焦

  • DLL 中未作为独立导出命令,但 EXE 的“AFの実行”菜单调用 StartProcess,其内部可触发对焦操作,对应的相机命令为 01 20 86 00 00 00 00 00 03(也可被直接发送)。

6.3 用户设置库(保存/调用)

  • 保存到库:StartProcess(0x25) → sub_10005B79
  • 从库读取:StartProcess(0x26) → sub_10005A2EStartProcess(0x27) → sub_10005D47
  • 这些函数内部发送命令 18、20、31、119 以及 sub_1000E07D/sub_1000E183 等位操作,并读写 FD17、FD26、FD27 等寄存器。

6.4 恢复默认设置

  • StartProcess(0x58)
  • 先将内部变量设为一组出厂默认值(详见代码中的连续赋值),然后调用 sub_100065A7,发送命令 119 或 18,最后写入配置块(命令 32 或 35)和公共配置(命令 20)。

6.5 胶卷数据读取

  • 入口:sub_10006F09 → 型号1调用 sub_10007042,型号2调用 sub_1000749C
  • 步骤:
    1. 读 FD20FD24FD40 验证状态和存储模式。
    2. 读 FD41 获取帧数 v19 和相关信息。
    3. 根据 v19 计算动态地址:addr = 2 * v19(可能进行回绕修正)。
    4. 调用 sub_10007A14 发送动态读命令,接收数据包。
    5. 数据以 0xFF 作为卷结束标记,ISO 索引在最后。
    6. 解析帧数据(每帧 3/4/6 字节,取决于存储模式),字段包括快门速度、光圈、曝光模式、测光方式、焦距、曝光补偿等。
    7. 发送确认命令 0x42(’B’)完成本次读取。

6.6 删除胶卷数据

  • 全消去StartProcess(0x1C) → sub_1000A9CD
    • 检查相机内是否有数据,若无则发送命令 133,相机清空整个环形缓冲区。
  • 部分删除(移动读取指针)StartProcess(0x1B) → sub_1000A7E1
    • 发送命令 134,并操作命令 19(FD39)的位 3,使相机内部的待读指针前移,等效于删除已读取的卷。
  • 指针/状态复位StartProcess(0x88) → sub_10008403
    • 型号1:写 FD41 特定值,清除 FED6 的 bit0,清零 FD40。
    • 型号2:读 FD00,写命令 ‘B’,清除 FECE 的 bit0,清零 FD40。

第七章 配置块位定义

从 sub_1000694E 提取(以型号1配置块命令32为例):

  • v34 低字节 = a3[10]
  • v34 高字节:
    • bit0: a3[13] 控制
    • bit1: a3[2] 控制
    • bit2: a3[11] 控制
    • bit3: a3[3] 控制
    • bit5: a3[9] 控制
    • bit6: a3[8] 控制
  • v35 低字节:
    • bit2: a3[12] (1或3置1)
    • bit3: a3[12] (2或3置1)
    • bit4: a3[5] 控制
    • bit5: a3[7] 控制
    • bit7: a3[6] 控制

型号2配置块(命令35)有类似的位定义,详见原始反编译代码。


第八章 错误码表

错误码 (hex)含义
0x19 (25)参数无效
0x1D (29)数据块读取校验失败
0x25 (37)对焦扫描初始化失败
0x28 (40)功能不可用/状态错误
0x29 (41)功能不支持
0x32 (50)通用“不支持此操作”
0x33 (51)参数冲突
0x34 (52)参数范围错误
0x35 (53)参数范围错误
0x37 (55)模式不匹配
0x45 (69)初始化失败
-18校验和不匹配
-27未收到 ACK (0x06)
-30接收超时
-35相机状态错误

所有错误均通过全局变量 dword_10015220 返回。


第九章 数值编码与资源字符串

相机参数值到显示文本的映射完全来自 DLL/EXE 资源,无需第三方数据。例如:

  • 快门速度:EXE 资源 17408 开始 "30"",连续列出 Bulb、30″、25″、… 1/8000。
  • 光圈:资源 17664 起 F1、F1.1、… F90。
  • ISO:资源 19968 起 ISO 6、ISO 8、… ISO 6400。
  • 曝光补偿:资源 19712 起 0.0、-0.2、… +20.0。
  • 测光方式:资源 22190 起 “多分区测光”、”中央重点测光”、”点测光”。
  • 曝光模式:资源 17920 起 “P:多程序自动”、”S:快门优先” 等。

所有字符串均已在 EXE 和 DLL 的资源提取中完整列出,并翻译为中文。


第十章 与第三方文档的主要差异说明(主要指f90x-serial-documentation/f90x-serial-documentation.md at trunk · antarktikali/f90x-serial-documentation · GitHubgIcon source 项目等)

  • 地址字节:第三方固定使用 0x20,我们根据 DLL 逻辑动态使用 0x10 或 0x20
  • 扩展命令格式:第三方可能省略 0x90,我们严格采用 DLL 的 1B 90 cmd 格式。
  • 环形缓冲区指针:第三方直接操作 FD44/FD46,DLL 通过动态地址计算和 FED6/FECE 等寄存器间接实现,功能等效。
  • 部分只读状态寄存器(如 FE20、FE22)在 DLL 中未出现立即数,但其信息已通过功能 ID 提供,不影响使用。
  • 所有命令码和寄存器映射完全基于 DLL 的 sub_1000DB73sub_1000DED3,比第三方仅列举的片段更为完整和准确。

附录 A 数据块格式(胶卷记录)

卷头:2 字节 0x5A58(“ZX”)
     2 字节 元数据
     2 字节 0x0000
     2 字节 卷号(BCD)
帧数据:N × (3/4/6 字节) 取决于存储模式
     1 字节 0xFF(结束标记)
     1 字节 ISO 索引

每帧数据字段(6 字节最大模式):快门速度、光圈、曝光模式、测光模式、闪光同步、焦距、曝光补偿、闪光补偿。具体编码与命令寄存器返回的原始值一致,可参照资源字符串表解析。

补充:

  • 在 sub_10007042 中,读取胶卷数据时使用的动态地址 v28 = 2 * v19,并且有如下回绕处理:
v15 = 总字节数 + v28;
if ( v15 >= 0x200u )
    v15 -= 444;   // 回绕修正,444 = 0x1BC
  • 这说明环形缓冲区的大小为 512 (0x200) 字节,当读取指针超过 0x1FF 时,会回绕到 0x200 - 444 = 0x44(实际基址由相机固定)。DLL 内部自动处理了回绕,开发者只需按此逻辑实现即可。

评论

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注