319 lines
6.6 KiB
Plaintext
319 lines
6.6 KiB
Plaintext
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;i<mp_cnt;i++) {
|
|
c=mp_cpu_structs+sizeof(CPUStruct)*i;
|
|
if (tss==c->cain_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;i<uS;i++)
|
|
PortNop;
|
|
}
|
|
|
|
void Sleep(U8 mS)
|
|
//This routine is not for power-saving
|
|
//it is to make a program pause without
|
|
//hogging the CPU.
|
|
{
|
|
U8 target_val;
|
|
BoolU4 old_idle;
|
|
if (!mS)
|
|
SwapInNext;
|
|
else {
|
|
old_idle=Bts(&Fs->task_flags,TSSf_IDLE);
|
|
target_val=GetTimeStamp+mS*time_stamp_kHz_freq;
|
|
do SwapInNext;
|
|
while (Fs->time_slice_start<target_val);
|
|
AssignBit(&Fs->task_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);
|
|
}
|