2020-02-15 20:01:48 +00:00
|
|
|
|
U0 PortNop()
|
|
|
|
|
{//Innoculous (reads IRQ Mask) which should take fixed time
|
|
|
|
|
//because it's an ISA-bus standard. It takes 1.0uS-2.0uS.
|
|
|
|
|
InU8(0x21);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
U16 EndianU16(U16 d)
|
|
|
|
|
{//Swap big<-->little endian.
|
|
|
|
|
I64 res=0;
|
|
|
|
|
res.u8[1]=d.u8[0];
|
|
|
|
|
res.u8[0]=d.u8[1];
|
|
|
|
|
return res;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
U32 EndianU32(U32 d)
|
|
|
|
|
{//Swap big<-->little endian.
|
|
|
|
|
I64 res=0;
|
|
|
|
|
res.u8[3]=d.u8[0];
|
|
|
|
|
res.u8[2]=d.u8[1];
|
|
|
|
|
res.u8[1]=d.u8[2];
|
|
|
|
|
res.u8[0]=d.u8[3];
|
|
|
|
|
return res;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
I64 EndianI64(I64 d)
|
|
|
|
|
{//Swap big<-->little endian.
|
|
|
|
|
U64 res;
|
|
|
|
|
res.u8[7]=d.u8[0];
|
|
|
|
|
res.u8[6]=d.u8[1];
|
|
|
|
|
res.u8[5]=d.u8[2];
|
|
|
|
|
res.u8[4]=d.u8[3];
|
|
|
|
|
res.u8[3]=d.u8[4];
|
|
|
|
|
res.u8[2]=d.u8[5];
|
|
|
|
|
res.u8[1]=d.u8[6];
|
|
|
|
|
res.u8[0]=d.u8[7];
|
|
|
|
|
return res;
|
|
|
|
|
}
|
|
|
|
|
|
2020-02-16 00:20:04 +00:00
|
|
|
|
I64 BCount(I64 d)
|
2020-02-15 20:01:48 +00:00
|
|
|
|
{//Count set bits in I64.
|
|
|
|
|
I64 res=0,i;
|
|
|
|
|
for (i=0;i<8;i++)
|
|
|
|
|
res+=set_bits_table[d.u8[i]];
|
|
|
|
|
return res;
|
|
|
|
|
}
|
|
|
|
|
|
2020-02-15 23:09:55 +00:00
|
|
|
|
U0 IntCore0TimerHandler(CTask *)
|
|
|
|
|
{//Called from $LK,"IntCore0TimerHandler",A="FF:::/Kernel/KInts.HC,IntCore0TimerHandler"$
|
2020-02-15 20:01:48 +00:00
|
|
|
|
I64 i;
|
2020-02-16 00:20:04 +00:00
|
|
|
|
if (mp_count>1)
|
2020-02-15 20:01:48 +00:00
|
|
|
|
while (LBts(&sys_semas[SEMA_SYS_TIMER],0))
|
|
|
|
|
PAUSE
|
2020-02-16 00:20:04 +00:00
|
|
|
|
lock counts.jiffies++;
|
|
|
|
|
counts.timer+=SYS_TIMER0_PERIOD+1;
|
2020-02-15 20:01:48 +00:00
|
|
|
|
LBtr(&sys_semas[SEMA_SYS_TIMER],0);
|
2020-02-16 00:20:04 +00:00
|
|
|
|
for (i=1;i<mp_count;i++)
|
2020-02-15 20:01:48 +00:00
|
|
|
|
MPInt(I_TIMER,i);
|
|
|
|
|
OutU8(0x20,0x20); //Acknowledge PIC Interrupt
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
I64 SysTimerRead()
|
|
|
|
|
{//System timer count with overflow already handled.
|
|
|
|
|
I64 i,res;
|
|
|
|
|
PUSHFD
|
|
|
|
|
CLI
|
2020-02-16 00:20:04 +00:00
|
|
|
|
if (mp_count>1)
|
2020-02-15 20:01:48 +00:00
|
|
|
|
while (LBts(&sys_semas[SEMA_SYS_TIMER],0))
|
|
|
|
|
PAUSE
|
|
|
|
|
OutU8(0x43,0); //Latch Timer0
|
|
|
|
|
if ((i=InU8(0x40)+InU8(0x40)<<8)==SYS_TIMER0_PERIOD) {
|
|
|
|
|
if (InU8(0x20) & 1)
|
|
|
|
|
i=-1;
|
|
|
|
|
}
|
2020-02-16 00:20:04 +00:00
|
|
|
|
res=counts.timer+SYS_TIMER0_PERIOD-i;
|
2020-02-15 20:01:48 +00:00
|
|
|
|
LBtr(&sys_semas[SEMA_SYS_TIMER],0);
|
|
|
|
|
POPFD
|
|
|
|
|
return res;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
I64 HPET()
|
|
|
|
|
{ //Get high precision event timer.
|
|
|
|
|
return *(dev.uncached_alias+HPET_MAIN_CNT)(I64 *);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
I64 TimeCal()
|
|
|
|
|
{
|
|
|
|
|
static I64 time_stamp_start=0,timer_start=0,HPET_start=0;
|
|
|
|
|
I64 i;
|
|
|
|
|
if (time_stamp_start) {
|
|
|
|
|
PUSHFD
|
|
|
|
|
CLI
|
|
|
|
|
if (HPET_start) {
|
2020-02-16 00:20:04 +00:00
|
|
|
|
counts.time_stamp_freq=counts.HPET_freq*(GetTSC-time_stamp_start);
|
2020-02-15 20:01:48 +00:00
|
|
|
|
i=HPET-HPET_start;
|
|
|
|
|
} else {
|
2020-02-16 00:20:04 +00:00
|
|
|
|
counts.time_stamp_freq=SYS_TIMER_FREQ*(GetTSC-time_stamp_start);
|
2020-02-15 20:01:48 +00:00
|
|
|
|
i=SysTimerRead-timer_start;
|
|
|
|
|
}
|
|
|
|
|
if (!i)
|
2020-02-15 22:25:33 +00:00
|
|
|
|
ZenithErr("Timer Cal Error");
|
2020-02-15 20:01:48 +00:00
|
|
|
|
else {
|
2020-02-16 00:20:04 +00:00
|
|
|
|
counts.time_stamp_freq/=i;
|
|
|
|
|
counts.time_stamp_kHz_freq=counts.time_stamp_freq/1000;
|
|
|
|
|
counts.time_stamp_calibrated=TRUE;
|
2020-02-15 20:01:48 +00:00
|
|
|
|
}
|
|
|
|
|
POPFD
|
|
|
|
|
}
|
|
|
|
|
PUSHFD
|
|
|
|
|
CLI
|
2020-02-16 00:20:04 +00:00
|
|
|
|
if (counts.HPET_freq) {
|
2020-02-15 20:01:48 +00:00
|
|
|
|
timer_start=0;
|
|
|
|
|
HPET_start=HPET;
|
|
|
|
|
} else {
|
|
|
|
|
timer_start=SysTimerRead;
|
|
|
|
|
HPET_start=0;
|
|
|
|
|
}
|
|
|
|
|
time_stamp_start=GetTSC;
|
|
|
|
|
POPFD
|
2020-02-16 00:20:04 +00:00
|
|
|
|
return counts.time_stamp_freq;
|
2020-02-15 20:01:48 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
F64 tS()
|
|
|
|
|
{//Time since boot in seconds as a float.
|
2020-02-16 00:20:04 +00:00
|
|
|
|
if (counts.HPET_freq)
|
|
|
|
|
return ToF64(HPET-counts.HPET_initial)/counts.HPET_freq;
|
2020-02-15 20:01:48 +00:00
|
|
|
|
else
|
|
|
|
|
return SysTimerRead/ToF64(SYS_TIMER_FREQ);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Bool Blink(F64 Hz=2.5)
|
|
|
|
|
{//Return TRUE, then FALSE, then TRUE at given frequency.
|
|
|
|
|
if (!Hz) return 0;
|
2020-02-16 00:20:04 +00:00
|
|
|
|
return ToI64(counts.jiffies*2*Hz/JIFFY_FREQ)&1;
|
2020-02-15 20:01:48 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
U0 Busy(I64 <EFBFBD>S)
|
|
|
|
|
{//Loosely timed.
|
|
|
|
|
I64 i;
|
2020-02-16 00:20:04 +00:00
|
|
|
|
if (counts.HPET_freq) {
|
|
|
|
|
i=HPET+counts.HPET_freq*<EFBFBD>S/1000000;
|
2020-02-15 20:01:48 +00:00
|
|
|
|
while (HPET<i);
|
|
|
|
|
} else
|
|
|
|
|
for (i=0;i<<EFBFBD>S;i++)
|
|
|
|
|
PortNop;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
U0 SleepUntil(I64 wake_jiffy)
|
|
|
|
|
{//Not for power-saving.It is to make a program pause without hogging the CPU.
|
|
|
|
|
Bool old_idle=LBts(&Fs->task_flags,TASKf_IDLE);
|
|
|
|
|
Fs->wake_jiffy=wake_jiffy;
|
|
|
|
|
Yield;
|
|
|
|
|
LBEqu(&Fs->task_flags,TASKf_IDLE,old_idle);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
U0 Sleep(I64 mS)
|
|
|
|
|
{//Not for power-saving.It is to make a program pause without hogging the CPU.
|
|
|
|
|
if (!mS)
|
|
|
|
|
Yield;
|
|
|
|
|
else
|
2020-02-16 00:20:04 +00:00
|
|
|
|
SleepUntil(counts.jiffies+mS*JIFFY_FREQ/1000);
|
2020-02-15 20:01:48 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
F64 Ona2Freq(I8 ona)
|
2020-02-15 23:30:38 +00:00
|
|
|
|
{//Ona to freq. Ona=60 is 432.0Hz.
|
2020-02-15 20:01:48 +00:00
|
|
|
|
if (!ona)
|
|
|
|
|
return 0;
|
|
|
|
|
else
|
2020-02-16 00:20:04 +00:00
|
|
|
|
return 432.0/32*2.0`(ona/12.0);
|
2020-02-15 20:01:48 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
I8 Freq2Ona(F64 freq)
|
2020-02-15 23:30:38 +00:00
|
|
|
|
{//Freq to Ona. 432.0Hz is Ona=60.
|
2020-02-15 20:01:48 +00:00
|
|
|
|
if (freq>0)
|
2020-02-15 23:30:38 +00:00
|
|
|
|
return ClampI64(12*Log2(32.0/432.0*freq),1,I8_MAX);
|
2020-02-15 20:01:48 +00:00
|
|
|
|
else
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
U0 Snd(I8 ona=0)
|
|
|
|
|
{//Play ona, a piano key num. 0 means rest.
|
|
|
|
|
I64 period;
|
|
|
|
|
CSndData *d;
|
|
|
|
|
if (!Bt(&sys_semas[SEMA_MUTE],0) &&
|
|
|
|
|
!LBts(&sys_semas[SEMA_SND],0)) { //Mutex. Just throw-out if in use
|
|
|
|
|
if (!ona) {
|
|
|
|
|
scrncast.ona=ona;
|
|
|
|
|
OutU8(0x61,InU8(0x61)&~3);
|
|
|
|
|
} else if (ona!=scrncast.ona) {
|
|
|
|
|
scrncast.ona=ona;
|
|
|
|
|
period=ClampI64(SYS_TIMER_FREQ/Ona2Freq(ona),1,U16_MAX);
|
|
|
|
|
OutU8(0x43,0xB6);
|
|
|
|
|
OutU8(0x42,period);
|
|
|
|
|
OutU8(0x42,period.u8[1]);
|
|
|
|
|
OutU8(0x61,3|InU8(0x61));
|
|
|
|
|
}
|
2020-02-15 22:25:33 +00:00
|
|
|
|
if (!IsDebugMode && scrncast.record) {
|
2020-02-15 20:01:48 +00:00
|
|
|
|
d=ACAlloc(sizeof(CSndData));
|
|
|
|
|
d->ona=ona;
|
|
|
|
|
d->tS=tS;
|
2020-02-15 22:53:02 +00:00
|
|
|
|
QueueInsert(d,scrncast.snd_head.last);
|
2020-02-15 20:01:48 +00:00
|
|
|
|
}
|
|
|
|
|
LBtr(&sys_semas[SEMA_SND],0);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2020-02-15 23:19:08 +00:00
|
|
|
|
Bool ScreenCast(Bool val=ON,Bool just_audio=FALSE,U8 *print_fmt="B:/Tmp/%X.GR")
|
2020-02-15 20:01:48 +00:00
|
|
|
|
{//WinMgr saves GR files to a dir.
|
|
|
|
|
Bool old_val;
|
|
|
|
|
scrncast.just_audio=just_audio;
|
|
|
|
|
if (val) {
|
|
|
|
|
if (!(old_val=LBtr(&scrncast.record,0))) {
|
|
|
|
|
Free(scrncast.print_fmt);
|
|
|
|
|
scrncast.print_fmt=AStrNew(print_fmt);
|
|
|
|
|
scrncast.t0_now=Now;
|
|
|
|
|
scrncast.snd_head.tS=scrncast.t0_tS=tS;
|
|
|
|
|
scrncast.snd_head.ona=scrncast.ona;
|
|
|
|
|
LBts(&scrncast.record,0);
|
|
|
|
|
}
|
|
|
|
|
} else
|
|
|
|
|
old_val=LBtr(&scrncast.record,0);
|
|
|
|
|
Snd;
|
|
|
|
|
return old_val;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
U0 SndRst()
|
|
|
|
|
{//Fix stuck sound.
|
|
|
|
|
if (Bt(&sys_semas[SEMA_SND],0)) {
|
|
|
|
|
Sleep(1);
|
|
|
|
|
if (Bt(&sys_semas[SEMA_SND],0)) {
|
|
|
|
|
Sleep(1);
|
|
|
|
|
LBtr(&sys_semas[SEMA_SND],0);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
Snd;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
U0 Beep(I8 ona=62,Bool busy=FALSE)
|
|
|
|
|
{//Make beep at given ona freq.
|
|
|
|
|
Snd(ona);
|
|
|
|
|
if (busy)
|
|
|
|
|
Busy(500000);
|
|
|
|
|
else
|
|
|
|
|
Sleep(500);
|
|
|
|
|
Snd;
|
|
|
|
|
if (busy)
|
|
|
|
|
Busy(200000);
|
|
|
|
|
else
|
|
|
|
|
Sleep(200);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Bool Mute(Bool val)
|
|
|
|
|
{//Turn-off sound.
|
|
|
|
|
Bool res;
|
|
|
|
|
if (val) {
|
|
|
|
|
PUSHFD
|
|
|
|
|
CLI
|
|
|
|
|
Snd;
|
|
|
|
|
res=LBts(&sys_semas[SEMA_MUTE],0);
|
|
|
|
|
POPFD
|
|
|
|
|
} else
|
|
|
|
|
res=LBtr(&sys_semas[SEMA_MUTE],0);
|
|
|
|
|
return res;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Bool IsMute()
|
|
|
|
|
{//Return is-mute flag.
|
|
|
|
|
return Bt(&sys_semas[SEMA_MUTE],0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Bool Silent(Bool val=ON)
|
|
|
|
|
{//Turn-off StdOut console text. (Not sound.)
|
|
|
|
|
return LBEqu(&Fs->display_flags,DISPLAYf_SILENT,val);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Bool IsSilent()
|
|
|
|
|
{//Return StdOut turned-off?
|
|
|
|
|
return Bt(&Fs->display_flags,DISPLAYf_SILENT);
|
|
|
|
|
}
|
|
|
|
|
|
2020-02-15 22:25:33 +00:00
|
|
|
|
Bool SysDebug(Bool val)
|
|
|
|
|
{//Set SysDebug bit you can use while debugging.
|
2020-02-15 20:01:48 +00:00
|
|
|
|
return LBEqu(&sys_semas[SEMA_DEBUG],0,val);
|
|
|
|
|
}
|
|
|
|
|
|
2020-02-15 22:25:33 +00:00
|
|
|
|
Bool IsSysDebug()
|
|
|
|
|
{//Return SysDebug bit.
|
2020-02-15 20:01:48 +00:00
|
|
|
|
return Bt(&sys_semas[SEMA_DEBUG],0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Bool Raw(Bool val)
|
|
|
|
|
{//Set to direct scrn, BLACK & WHITE, non-windowed output mode.
|
|
|
|
|
if (!val)
|
|
|
|
|
VGAFlush;
|
|
|
|
|
return !LBEqu(&Fs->display_flags,DISPLAYf_NOT_RAW,!val);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Bool IsRaw()
|
|
|
|
|
{//Are we in BLACK & WHITE raw scrn mode?
|
|
|
|
|
return !Bt(&Fs->display_flags,DISPLAYf_NOT_RAW);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Bool SingleUser(Bool val)
|
|
|
|
|
{//Set single-user mode.
|
|
|
|
|
return LBEqu(&sys_semas[SEMA_SINGLE_USER],0,val);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Bool IsSingleUser()
|
|
|
|
|
{//Return single-user mode.
|
|
|
|
|
return Bt(&sys_semas[SEMA_SINGLE_USER],0);
|
|
|
|
|
}
|
|
|
|
|
|
2020-02-15 22:25:33 +00:00
|
|
|
|
Bool DebugMode(Bool val)
|
2020-02-15 20:01:48 +00:00
|
|
|
|
{//Set dbg-mode.
|
|
|
|
|
return LBEqu(&sys_semas[SEMA_DBG_MODE],0,val);
|
|
|
|
|
}
|
|
|
|
|
|
2020-02-15 22:25:33 +00:00
|
|
|
|
Bool IsDebugMode()
|
2020-02-15 20:01:48 +00:00
|
|
|
|
{//Return dbg-mode.
|
|
|
|
|
return Bt(&sys_semas[SEMA_DBG_MODE],0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
U0 ProgressBarsRst(U8 *path=NULL)
|
|
|
|
|
{//Reset all progress bars to zero.
|
|
|
|
|
CallExtStr("ProgressBarsRegTf",path);
|
|
|
|
|
MemSet(sys_progresses,0,sizeof(sys_progresses));
|
|
|
|
|
}
|