BoolU8 AssignBit(void *field,U8 bit,U8 val) { if (val) return Bts(field,bit); else return Btr(field,bit); } BoolU8 LAssignBit(void *field,U8 bit,U8 val) { if (val) return LBts(field,bit); else return LBtr(field,bit); } void PortNop() { InP(0x379); //This is an innoculous ISA (parallel port) //access which should take //fixed time on all machines. //It takes 1.66uS } void Exit() { Bts(&Fs->task_flags,TSSf_KILL_TASK); while (TRUE) SwapInNext; } BoolU8 ValidateTss(TssStruct *tss) { if (tss->absolute_address!=tss) return FALSE; if (tss->in_queue_signature!=TSSS_IN_QUEUE_SIGNATURE) return FALSE; return TRUE; } void Kill(TssStruct *tss,BoolU4 wait=TRUE) { U8 i; CPUStruct *c; BoolU4 found,old_preempt=Preempt(OFF); if (ValidateTss(tss)) { found=FALSE; if (tss==sys_update_screen_tss) found=TRUE; for (i=0;icain_tss) found=TRUE; } if (!found) { Bts(&tss->task_flags,TSSf_KILL_TASK); if (wait) { do { SwapInNext; if (!Bt(&tss->task_flags,TSSf_KILL_TASK)) break; } while (ValidateTss(tss)); } } } Preempt(old_preempt); } void SimpleTimerIrq(U8 rip) { U8 old_flags=GetFlags; nounusedwarn rip; Cli; if (mp_cnt>1) while (LBts(&sys_semas[SYS_SEMA_SYS_TIMER],0)); sys_jiffies++; t=1.0*sys_jiffies/JIFFY_FREQ; sys_timer+=SYS_TIMER0_PERIOD+1; LBtr(&sys_semas[SYS_SEMA_SYS_TIMER],0); if (mp_cnt>1) MPIntAll(0x20); SetFlags(old_flags); } U8 Jiffies() { return sys_jiffies; } U8 ReadSysTimer() { I8 i; U8 result,old_flags=GetFlags; Cli; if (mp_cnt>1) while (LBts(&sys_semas[SYS_SEMA_SYS_TIMER],0)); OutP(0x43,0); //Latch Timer0 if ((i=InP(0x40)+InP(0x40)<<8)==SYS_TIMER0_PERIOD) { if (InP(0x20) & 1) i=-1; } result=sys_timer+SYS_TIMER0_PERIOD-i; LBtr(&sys_semas[SYS_SEMA_SYS_TIMER],0); SetFlags(old_flags); return result; } U8 TssTotalTime() { U8 old_flags=GetFlags; U8 result; Cli; if (mp_cnt>1) while (LBts(&sys_semas[SYS_SEMA_TIMESTAMP],0)); result=GetTimeStamp-Fs->time_slice_start+Fs->total_time; LBtr(&sys_semas[SYS_SEMA_TIMESTAMP],0); SetFlags(old_flags); return result; } LTDate BootTime() //Roughly 49,710ths of a second since boot { return ReadSysTimer<<14/(1833333*3*3*3/125); } void BusyWait(U8 uS) //Loosely timed { U8 i; uS=uS<<1/3; for (i=0;itask_flags,TSSf_IDLE); target_val=GetTimeStamp+mS*time_stamp_kHz_freq; do SwapInNext; while (Fs->time_slice_starttask_flags,TSSf_IDLE,old_idle); } } U8 RandU2() { U8 i=GetTimeStamp; rnd_SEED^=rnd_SEED*0x763D+i.u4[0]^i.u4[1]+rnd_SEED%0x56233; return rnd_SEED.u2[0]; } U8 RandU4() { U8 result=0; result.u2[0]=RandU2; result.u2[1]=RandU2; return result; } U8 RandU8() { U8 result; result.u2[0]=RandU2; result.u2[1]=RandU2; result.u2[2]=RandU2; result.u2[3]=RandU2; return result; } void Sound(U8 freq) { U8 p,old_flags=GetFlags; if (Bt(&sys_semas[SYS_SEMA_NO_SOUND],0)) return; Cli; if (!LBts(&sys_semas[SYS_SEMA_SOUND],0)) { if (freq) { p=SYS_TIMER_FREQ/freq; OutP(0x43,0xB6); OutP(0x42,p); OutP(0x42,p.u1[1]); OutP(0x61,3|InP(0x61)); } else OutP(0x61,InP(0x61)&~3); LBtr(&sys_semas[SYS_SEMA_SOUND],0); } SetFlags(old_flags); } void Beep(U8 freq=500,BoolU4 busy=FALSE) { Sound(freq); if (busy) BusyWait(500000); else Sleep(500); Sound(0); if (busy) BusyWait(200000); else Sleep(200); } BoolU8 Externs2Imports(BoolU4 val) { return AssignBit(&Fs->last_lex->flags,LFf_EXTERNS_TO_IMPORTS,val); } //Private symbols are accessible but //don't show-up in reports BoolU8 KeepPrivate(BoolU4 val) { return AssignBit(&Fs->last_lex->flags,LFf_KEEP_PRIVATE,val); } //Displays intermediate code as it is being added BoolU8 PTrace(BoolU4 val) { return AssignBit(&Fs->last_lex->flags,LFf_PARSE_TRACE,val); } //Displays intermediate code after passes through optimization BoolU8 OTrace(BoolU4 val) { return AssignBit(&Fs->last_lex->flags,LFf_OPT_TRACE,val); } //Controls which optimizerpasses are displayed U8 OPassTraceMask(U8 i=0b100111111) { U8 old=Fs->last_lex->pass_trace_mask; Fs->last_lex->pass_trace_mask=i; return old; } //Turn on compiler option //See $LK,"OPTf_IGNORE_OVERFLOW","MN:OPTf_IGNORE_OVERFLOW"$ BoolU8 OptOn(U8 num) { return Bts(&Fs->last_lex->opts,num); } //Turn off compiler option //See $LK,"OPTf_IGNORE_OVERFLOW","MN:OPTf_IGNORE_OVERFLOW"$ BoolU8 OptOff(U8 num) { return Btr(&Fs->last_lex->opts,num); } //Get state of compiler option //See $LK,"OPTf_IGNORE_OVERFLOW","MN:OPTf_IGNORE_OVERFLOW"$ BoolU8 GetOpt(U8 num) { return Bt(&Fs->last_lex->opts,num); } //Displays assembly code output BoolU8 CTrace(BoolU4 val) { return AssignBit(&Fs->last_lex->flags,LFf_COMPILE_TRACE,val); } //Displays lexical analyser's output BoolU8 LTrace(BoolU4 val) { return AssignBit(&Fs->last_lex->flags,LFf_LEX_TRACE,val); } BoolU8 NoRegVar(BoolU4 val) { return AssignBit(&Fs->last_lex->flags,LFf_NO_REG_VAR,val); } //Displays text as it is being compiled BoolU8 Echo(BoolU4 val) { return AssignBit(&Fs->last_lex->flags,LFf_ECHO,val); } BoolU8 SysEcho(BoolU4 val) { return AssignBit(&Fs->last_lex->flags,LFf_ECHO,val); } BoolU8 Silent(BoolU4 val) { return AssignBit(&Fs->crt_flags,CRTf_SILENT,val); } BoolU8 IOSound(BoolU4 val) { return !LAssignBit(&sys_semas[SYS_SEMA_NO_IO_SOUND],0,!val); } BoolU8 IsPreempt() { return Bt(&Fs->task_flags,TSSf_PREEMPT); } BoolU8 SysDbg(BoolU4 val) { //Sets or resets a bit which you can //use while debugging. return LAssignBit(&sys_semas[SYS_SEMA_DEBUG],0,val); } BoolU8 IsSysDbg() { //Returns the value of the debug //bit. return Bt(&sys_semas[SYS_SEMA_DEBUG],0); } BoolU8 Raw(BoolU4 val) { //Switches to direct screen output //mode for when you don't have //a working window. return !LAssignBit(&Fs->task_flags,TSSf_NOT_RAW,!val); } BoolU8 IsRaw() { return !Bt(&Fs->task_flags,TSSf_NOT_RAW); } SysHashEntry *FindLocalHash(I1 *st,U8 mask) { return FindHashEntry(st,Fs->hash_table,mask); }