EMU8086 似乎正在模拟 8254 计时器 0,大多数 PC 系统仍在模拟,以下是计时值:
8254 channel 0 runs at 1.19318 mhz or ~ 838.0965 nsecs / cycle
System timer interrupts every 65536 cycles ~= 54.9255 ms
or ~ 18.20648 ticks per second
1 ms = 1193.18 cycles
1 hour ~= 65543 ticks ~= 3599.9816 secs
24 hour ~= 1573040 (hex 1800B0) ticks ~= 86399.998 secs
用于将刻度精确转换为小时/分钟/秒(截断)的示例 C 代码:
i = itick<<10; /* itick * 1024 */
hour = 0;
while(i >= 67116375){
hour++;
i -= 67116375;
}
i <<= 4; /* itick * 16384 */
minute = 0;
while(i >= 17897700){
minute++;
i -= 17897700;
}
second = 0;
while(i >= 298295){
second++;
i -= 298295;
}
使用 32 位乘 16 位乘法例程,您可以乘以 floor((2^32)/divisor),之后只需进行一次减法检查。
uint32_t i, tick, hour, minute, second;
/* ... */
i = tick<<10;
hour = (uint32_t)(((uint64_t)i*63)>>32);
i -= hour*67116375;
if(i >= 67116375){
hour++;
i -= 67116375;
}
i <<= 4;
minute = (uint32_t)(((uint64_t)i*239)>>32);
i -= minute*17897700;
if(i >= 17897700){
minute++;
i -= 17897700;
}
second = (uint32_t)(((uint64_t)i*14398)>>32);
i -= second*298295;
if(i >= 298295){
second++;
i -= 298295;
}
使用 32 x 32 位乘法例程,可以消除单减法检查:
i = tick<<10;
hour = (uint32_t)(((uint64_t)i*2147243323u)>>57);
i -= hour*67116375;
i <<= 4;
minute = (uint32_t)(((uint64_t)i*4026081231u)>>56);
i -= minute*17897700;
second = (uint32_t)(((uint64_t)i*1887225577u)>>49);
i -= second*298295;