ZealOS/src/Kernel/KMisc.CC

266 lines
5.9 KiB
HolyC
Raw Normal View History

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);
}
U0 IntCore0TimerHandler(CTask *)
{//Called from $LK,"IntCore0TimerHandler",A="FF:::/Kernel/KInterrupts.CC,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);
2020-02-16 18:37:19 +00:00
OutU8(PIC1,PIC_EOI); //Acknowledge PIC Interrupt
2020-02-15 20:01:48 +00:00
}
I64 SysTimerRead()
2020-02-16 18:37:19 +00:00
{//System timer count with overflow already handled.
2020-02-15 20:01:48 +00:00
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
2020-02-16 10:19:49 +00:00
OutU8(PIT_CMD, PIT_CMDF_CHANNEL0); //Latch Timer0
if ((i=InU8(PIT0) + InU8(PIT0) << 8) == SYS_TIMER0_PERIOD)
{
2020-02-16 18:37:19 +00:00
if (InU8(PIC1) & 1)
2020-02-15 20:01:48 +00:00
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 TimeCal()
{
2020-02-17 01:36:52 +00:00
static I64 time_stamp_start=0,timer_start=0;
2020-02-15 20:01:48 +00:00
I64 i;
if (time_stamp_start) {
PUSHFD
CLI
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-17 01:36:52 +00:00
timer_start=SysTimerRead;
2020-02-15 20:01:48 +00:00
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-17 01:36:52 +00:00
return SysTimerRead/ToF64(SYS_TIMER_FREQ);
2020-02-15 20:01:48 +00:00
}
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-17 01:36:52 +00:00
for (i=0;i<<EFBFBD>S;i++)
PortNop;
2020-02-15 20:01:48 +00:00
}
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;
2020-02-16 03:41:28 +00:00
LBEqual(&Fs->task_flags,TASKf_IDLE,old_idle);
2020-02-15 20:01:48 +00:00
}
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;
}
2020-02-16 00:49:37 +00:00
U0 Sound(I8 ona=0)
2020-02-15 20:01:48 +00:00
{//Play ona, a piano key num. 0 means rest.
I64 period;
2020-02-16 00:49:37 +00:00
CSoundData *d;
2020-02-15 20:01:48 +00:00
if (!Bt(&sys_semas[SEMA_MUTE],0) &&
2020-02-16 00:49:37 +00:00
!LBts(&sys_semas[SEMA_SOUND],0)) { //Mutex. Just throw-out if in use
2020-02-15 20:01:48 +00:00
if (!ona) {
2020-02-16 00:49:37 +00:00
screencast.ona=ona;
2020-02-16 17:57:16 +00:00
OutU8(PCSPKR, InU8(PCSPKR) & ~3);
2020-02-16 00:49:37 +00:00
} else if (ona!=screencast.ona) {
screencast.ona=ona;
2020-02-15 20:01:48 +00:00
period=ClampI64(SYS_TIMER_FREQ/Ona2Freq(ona),1,U16_MAX);
2020-02-16 17:57:16 +00:00
//See $LK,"::/Doc/PIT.DD",A="FI:::/Doc/PIT.DD"$.
2020-02-16 10:19:49 +00:00
OutU8(PIT_CMD,PIT_CMDF_CHANNEL2 | PIT_CMDF_OPMODE_SQUARE_WAVE | PIT_CMDF_ACCESS_WORD);
OutU8(PIT2,period);
OutU8(PIT2,period.u8[1]);
2020-02-16 17:57:16 +00:00
OutU8(PCSPKR,3|InU8(PCSPKR)); //enable speaker
2020-02-15 20:01:48 +00:00
}
2020-02-16 00:49:37 +00:00
if (!IsDebugMode && screencast.record) {
2020-02-16 02:38:13 +00:00
d=ZCAlloc(sizeof(CSoundData));
2020-02-15 20:01:48 +00:00
d->ona=ona;
d->tS=tS;
2020-02-16 00:49:37 +00:00
QueueInsert(d,screencast.sound_head.last);
2020-02-15 20:01:48 +00:00
}
2020-02-16 00:49:37 +00:00
LBtr(&sys_semas[SEMA_SOUND],0);
2020-02-15 20:01:48 +00:00
}
}
Bool ScreenCast(Bool val=ON,Bool just_audio=FALSE,U8 *print_format="B:/Tmp/%X.GR")
2020-02-15 20:01:48 +00:00
{//WinMgr saves GR files to a dir.
Bool old_val;
2020-02-16 00:49:37 +00:00
screencast.just_audio=just_audio;
2020-02-15 20:01:48 +00:00
if (val) {
2020-02-16 00:49:37 +00:00
if (!(old_val=LBtr(&screencast.record,0))) {
Free(screencast.print_format);
screencast.print_format=ZStrNew(print_format);
2020-02-16 00:49:37 +00:00
screencast.t0_now=Now;
screencast.sound_head.tS=screencast.t0_tS=tS;
screencast.sound_head.ona=screencast.ona;
LBts(&screencast.record,0);
2020-02-15 20:01:48 +00:00
}
} else
2020-02-16 00:49:37 +00:00
old_val=LBtr(&screencast.record,0);
Sound;
2020-02-15 20:01:48 +00:00
return old_val;
}
2020-02-16 00:54:39 +00:00
U0 SoundReset()
2020-02-15 20:01:48 +00:00
{//Fix stuck sound.
2020-02-16 00:49:37 +00:00
if (Bt(&sys_semas[SEMA_SOUND],0)) {
2020-02-15 20:01:48 +00:00
Sleep(1);
2020-02-16 00:49:37 +00:00
if (Bt(&sys_semas[SEMA_SOUND],0)) {
2020-02-15 20:01:48 +00:00
Sleep(1);
2020-02-16 00:49:37 +00:00
LBtr(&sys_semas[SEMA_SOUND],0);
2020-02-15 20:01:48 +00:00
}
}
2020-02-16 00:49:37 +00:00
Sound;
2020-02-15 20:01:48 +00:00
}
U0 Beep(I8 ona=62,Bool busy=FALSE)
{//Make beep at given ona freq.
2020-02-16 00:49:37 +00:00
Sound(ona);
2020-02-15 20:01:48 +00:00
if (busy)
Busy(500000);
else
Sleep(500);
2020-02-16 00:49:37 +00:00
Sound;
2020-02-15 20:01:48 +00:00
if (busy)
Busy(200000);
else
Sleep(200);
}
Bool Mute(Bool val)
{//Turn-off sound.
Bool res;
if (val) {
PUSHFD
CLI
2020-02-16 00:49:37 +00:00
Sound;
2020-02-15 20:01:48 +00:00
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.)
2020-02-16 03:41:28 +00:00
return LBEqual(&Fs->display_flags,DISPLAYf_SILENT,val);
2020-02-15 20:01:48 +00:00
}
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-16 03:41:28 +00:00
return LBEqual(&sys_semas[SEMA_DEBUG],0,val);
2020-02-15 20:01:48 +00:00
}
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)
2020-02-16 04:57:03 +00:00
{//Set to direct screen, BLACK & WHITE, non-windowed output mode.
2020-02-15 20:01:48 +00:00
if (!val)
VGAFlush;
2020-02-16 03:41:28 +00:00
return !LBEqual(&Fs->display_flags,DISPLAYf_NOT_RAW,!val);
2020-02-15 20:01:48 +00:00
}
Bool IsRaw()
2020-02-16 04:57:03 +00:00
{//Are we in BLACK & WHITE raw screen mode?
2020-02-15 20:01:48 +00:00
return !Bt(&Fs->display_flags,DISPLAYf_NOT_RAW);
}
Bool SingleUser(Bool val)
{//Set single-user mode.
2020-02-16 03:41:28 +00:00
return LBEqual(&sys_semas[SEMA_SINGLE_USER],0,val);
2020-02-15 20:01:48 +00:00
}
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)
{//Set debug-mode.
return LBEqual(&sys_semas[SEMA_DEBUG_MODE],0,val);
2020-02-15 20:01:48 +00:00
}
2020-02-15 22:25:33 +00:00
Bool IsDebugMode()
{//Return debug-mode.
return Bt(&sys_semas[SEMA_DEBUG_MODE],0);
2020-02-15 20:01:48 +00:00
}
2020-02-16 00:54:39 +00:00
U0 ProgressBarsReset(U8 *path=NULL)
2020-02-15 20:01:48 +00:00
{//Reset all progress bars to zero.
CallExtStr("ProgressBarsRegTf",path);
MemSet(sys_progresses,0,sizeof(sys_progresses));
}