877 lines
16 KiB
Plaintext
877 lines
16 KiB
Plaintext
BoolU4 AssignBit(U1 *field,U8 bit,U8 val)
|
|
{
|
|
if (val)
|
|
return Bts(field,bit);
|
|
else
|
|
return Btr(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;
|
|
}
|
|
|
|
void Kill(TssStruct *tss)
|
|
{
|
|
Bts(&tss->task_flags,TSSf_KILL_TASK);
|
|
}
|
|
|
|
void SimpleTimerIrq()
|
|
{
|
|
U8 old_flags=GetFlags;
|
|
Cli;
|
|
jiffies++;
|
|
sys_timer+=SYS_TIMER0_PERIOD+1;
|
|
SetFlags(old_flags);
|
|
}
|
|
|
|
U8 ReadSysTimer()
|
|
{
|
|
U8 i,old_flags=GetFlags;
|
|
U8 result;
|
|
Cli;
|
|
OutP(0x43,0); //Latch Timer0
|
|
i=InP(0x40);
|
|
i+=(InP(0x40)<<8);
|
|
result=sys_timer+SYS_TIMER0_PERIOD-i;
|
|
SetFlags(old_flags);
|
|
return result;
|
|
}
|
|
|
|
U8 ExceptDepth(TssStruct *tss=NULL)
|
|
{
|
|
U8 result=0;
|
|
ExceptStruct *tempt;
|
|
if (!tss) tss=Fs;
|
|
tempt=tss->next_except;
|
|
while (tempt!=&tss->next_except) {
|
|
result++;
|
|
tempt=tempt->next;
|
|
}
|
|
return result;
|
|
}
|
|
|
|
asm {
|
|
CP_TEST_EXCEPT::
|
|
MOV EAX,U4 FS:[TSS_LAST_EXCEPT]
|
|
MOV EBP,U4 EXCEPT_EBP[EAX]
|
|
MOV ESI,U4 EXCEPT_ESI[EAX]
|
|
MOV EDI,U4 EXCEPT_EDI[EAX]
|
|
CALL U4 EXCEPT_HANDLER_START[EAX]
|
|
RET
|
|
|
|
CP_CATCH_EXCEPT::
|
|
MOV EAX,U4 FS:[TSS_LAST_EXCEPT]
|
|
MOV EDX,U4 EXCEPT_HANDLER_SKIP[EAX]
|
|
MOV ESP,U4 EXCEPT_ESP[EAX]
|
|
JMP EDX
|
|
|
|
CP_SAVE_EXCEPT_ESI_EDI::
|
|
PUSH EBP
|
|
MOV EBP,ESP
|
|
MOV EAX,SF_PARAM1[EBP]
|
|
MOV U4 EXCEPT_ESI[EAX],ESI
|
|
MOV U4 EXCEPT_EDI[EAX],EDI
|
|
POP EBP
|
|
RET
|
|
};
|
|
|
|
LTextern CP_TEST_EXCEPT void TestExcept();
|
|
LTextern CP_CATCH_EXCEPT void TakeExcept();
|
|
LTextern CP_SAVE_EXCEPT_ESI_EDI void SaveExceptRegs(ExceptStruct *t);
|
|
|
|
exe {NoRegVar(ON);}
|
|
void SysTry(U1 *start_label,U1 *skip_label,U8 my_ebp,U8 my_esp)
|
|
{
|
|
U4 *ptr=GetBasePtr;
|
|
ExceptStruct *tempt=MAlloc(sizeof(ExceptStruct));
|
|
tempt->handler_start=start_label;
|
|
tempt->handler_skip=skip_label;
|
|
tempt->esp=my_esp+8;
|
|
tempt->ebp=my_ebp;
|
|
SaveExceptRegs(tempt);
|
|
InsQue(tempt,Fs->last_except);
|
|
}
|
|
|
|
void SysCatch()
|
|
{
|
|
ExceptStruct *tempt=Fs->last_except;
|
|
RemQue(tempt);
|
|
Free(tempt);
|
|
}
|
|
|
|
void throw(...)
|
|
{
|
|
ExceptStruct *tempt=Fs->last_except;
|
|
U8 i;
|
|
|
|
AdamLog("Depth:%02X Tsk:%08X throw(",
|
|
ExceptDepth(Fs),Fs); //TODO: fix compiler--"(FS)"
|
|
for (i=0;i<argc;i++)
|
|
AdamLog("%X,",argv[i]);
|
|
AdamLog(");\r\n");
|
|
|
|
Fs->except_argc=argc;
|
|
Fs->except_argv=argv;
|
|
Fs->except_ebp=GetBasePtr;
|
|
Fs->catch_except=FALSE;
|
|
while (tempt!=&Fs->next_except) {
|
|
TestExcept;
|
|
if (Fs->catch_except)
|
|
TakeExcept;
|
|
SetBasePtr(Fs->except_ebp);
|
|
RemQue(tempt);
|
|
Free(tempt);
|
|
tempt=Fs->last_except;
|
|
}
|
|
PutSysText("ST_UNHANDLED_EXCEPTION");
|
|
while (TRUE)
|
|
SwapInNext;
|
|
}
|
|
exe {NoRegVar(OFF);}
|
|
|
|
void KbdCmdSend(U8 port, U1 val)
|
|
{
|
|
U8 timeout;
|
|
for (timeout=50000;
|
|
(InP(KEYB_CTRL)&2) && timeout;timeout--)
|
|
PortNop;
|
|
if (timeout)
|
|
OutP(port, val);
|
|
else
|
|
throw(EXCEPT_LOCAL);
|
|
}
|
|
|
|
I8 KbdCmdRead()
|
|
{
|
|
U8 timeout;
|
|
for (timeout=50000; timeout; timeout--) {
|
|
if (InP(KEYB_CTRL) & 1)
|
|
return InP(KEYB_PORT);
|
|
else
|
|
PortNop;
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
void KbdCmdFlush()
|
|
{
|
|
I8 i;
|
|
for (i=0;i<1000;i++) {
|
|
if (InP(KEYB_CTRL) & 1) {
|
|
InP(KEYB_PORT);
|
|
i=0;
|
|
} else
|
|
PortNop;
|
|
}
|
|
}
|
|
|
|
void KbdSetLEDs(U8 sc)
|
|
{
|
|
U8 old_flags=GetFlags;
|
|
U1 v=0;
|
|
AssignBit(&v,0,Bt(&sc,SCf_SCROLL));
|
|
AssignBit(&v,1,Bt(&sc,SCf_NUM));
|
|
AssignBit(&v,2,Bt(&sc,SCf_CAPS));
|
|
Cli;
|
|
KbdCmdSend(KEYB_PORT,0xED);
|
|
KbdCmdSend(KEYB_PORT,v);
|
|
SetFlags(old_flags);
|
|
}
|
|
|
|
void KbdMouseCmdAck(U1 val)
|
|
{
|
|
U1 b;
|
|
U8 timeout=32;
|
|
BoolU4 cont=TRUE;
|
|
while (cont && timeout) {
|
|
try {
|
|
KbdCmdSend(KEYB_CTRL,0xD4);
|
|
KbdCmdSend(KEYB_PORT,val);
|
|
b=KbdCmdRead;
|
|
if (b==0xFA)
|
|
cont=FALSE;
|
|
} catch
|
|
Fs->catch_except=TRUE;
|
|
timeout--;
|
|
}
|
|
if (cont)
|
|
throw(EXCEPT_LOCAL);
|
|
}
|
|
|
|
void InitKeyboard()
|
|
{
|
|
KbdCmdSend(KEYB_PORT,0xF0);
|
|
KbdCmdSend(KEYB_PORT,0x02);
|
|
KbdSetLEDs(sys_cur_scan_code);
|
|
}
|
|
|
|
U1 scan_code_map[0x100]={
|
|
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
|
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
|
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
|
0,0,0,0,0,0,SC_SHIFT,0,0,0,0,0,0,0,0,0,
|
|
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
|
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
|
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
|
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
|
|
|
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
|
0,0,0,0,0,0,0,0,0,0,0,0,SC_CR,SC_CTRL,0,0,
|
|
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
|
0,0,0,0,0,0x35,0,0,0,SC_ALT,0,0,0,0,0,0,
|
|
0,0,0,0,0,0,0,SC_HOME,SC_CURSOR_UP,SC_PAGE_UP,0,SC_CURSOR_LEFT,0,SC_CURSOR_RIGHT,0,SC_END,
|
|
SC_CURSOR_DOWN,SC_PAGE_DOWN,SC_INSERT,SC_DELETE,0,0,0,0,0,0,0,0,SC_GUI,0,0,0,
|
|
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
|
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
|
};
|
|
|
|
|
|
U1 num_lock_map[0x100]={
|
|
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
|
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
|
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
|
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
|
0,0,0,0,0,0,0,8,9,10,0,5,6,7,0,2,
|
|
3,4,11,0x34,0,0,0,0,0,0,0,0,0,0,0,0,
|
|
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
|
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
|
|
|
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
|
0,0,0,0,0,0,0,0,0,0,0,0,SC_CR,SC_CTRL,0,0,
|
|
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
|
0,0,0,0,0,0x35,0,0,0,SC_ALT,0,0,0,0,0,0,
|
|
0,0,0,0,0,0,0,SC_HOME,SC_CURSOR_UP,SC_PAGE_UP,0,SC_CURSOR_LEFT,0,SC_CURSOR_RIGHT,0,SC_END,
|
|
SC_CURSOR_DOWN,SC_PAGE_DOWN,SC_INSERT,SC_DELETE,0,0,0,0,0,0,0,0,SC_GUI,0,0,0,
|
|
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
|
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
|
};
|
|
|
|
|
|
asm {CP_KBD_HANDLER::}
|
|
void KbdHandler()
|
|
{
|
|
void kbd_hand2();
|
|
U8 sc=sys_cur_scan_code&~0x1FF,
|
|
sc2=InP(KEYB_PORT),sc3,sc_raw;
|
|
Bts(&sys_irq_flags,1);
|
|
if (sc2==0xE0) {
|
|
sys_cur_scan_code|=SCF_PRIOR_E0;
|
|
return;
|
|
}
|
|
AssignBit(&sc2,SCf_KEY_UP,sc2 & 0x80);
|
|
AssignBit(&sc2,SCf_E0_PREFIX,Btr(&sc,SCf_PRIOR_E0));
|
|
sc_raw=sc2;
|
|
if (sc & SCF_NUM) {
|
|
if (sc3=num_lock_map[sc2.u1[0]])
|
|
sc2.u1[0]=sc3;
|
|
} else {
|
|
if (sc3=scan_code_map[sc2.u1[0]])
|
|
sc2.u1[0]=sc3;
|
|
}
|
|
if (sc2==SC_SHIFT) {
|
|
sc|=SCF_SHIFT;
|
|
goto new_key_done;
|
|
}
|
|
if (sc2==SC_SHIFT+SCF_KEY_UP) {
|
|
sc&=~SCF_SHIFT;
|
|
goto new_key_done;
|
|
}
|
|
|
|
if (sc2==SC_CTRL) {
|
|
sc|=SCF_CTRL;
|
|
goto new_key_done;
|
|
}
|
|
if (sc2==SC_CTRL+SCF_KEY_UP) {
|
|
sc&=~SCF_CTRL;
|
|
goto new_key_done;
|
|
}
|
|
|
|
if (sc2==SC_ALT) {
|
|
sc|=SCF_ALT;
|
|
goto new_key_done;
|
|
}
|
|
if (sc2==SC_ALT+SCF_KEY_UP) {
|
|
sc&=~SCF_ALT;
|
|
goto new_key_done;
|
|
}
|
|
|
|
if (sc2==SC_CAPS)
|
|
goto new_key_done;
|
|
if (sc2==SC_CAPS+SCF_KEY_UP) {
|
|
sc^=SCF_CAPS;
|
|
KbdSetLEDs(sc);
|
|
goto new_key_done;
|
|
}
|
|
|
|
if (sc2==SC_NUM)
|
|
goto new_key_done;
|
|
if (sc2==SC_NUM+SCF_KEY_UP) {
|
|
sc^=SCF_NUM;
|
|
KbdSetLEDs(sc);
|
|
goto new_key_done;
|
|
}
|
|
|
|
if (sc2==SC_SCROLL)
|
|
goto new_key_done;
|
|
if (sc2==SC_SCROLL+SCF_KEY_UP) {
|
|
sc^=SCF_SCROLL;
|
|
KbdSetLEDs(sc);
|
|
goto new_key_done;
|
|
}
|
|
|
|
if (sc & SCF_CTRL && sc & SCF_ALT) {
|
|
if (sc2==SC_DELETE) {
|
|
Bts(&sys_flags,SYSf_CTRL_ALT_DEL);
|
|
goto mostly_done;
|
|
}
|
|
if (sc2==1) {
|
|
Bts(&sys_flags,SYSf_CTRL_ALT_ESC);
|
|
goto mostly_done;
|
|
}
|
|
if (sc2==15) {
|
|
Bts(&sys_flags,SYSf_CTRL_ALT_TAB);
|
|
goto mostly_done;
|
|
}
|
|
if (sc2==0x2D) {
|
|
Bts(&sys_flags,SYSf_CTRL_ALT_X);
|
|
goto mostly_done;
|
|
}
|
|
if (sc2==0x2E) {
|
|
Bts(&sys_flags,SYSf_CTRL_ALT_C);
|
|
goto mostly_done;
|
|
}
|
|
}
|
|
|
|
new_key_done:
|
|
sc|=SCF_NEW_KEY;
|
|
mostly_done:
|
|
sys_cur_scan_code=sc|sc2;
|
|
sys_cur_raw_scan_code=sc|sc_raw;
|
|
if (kbd_hand2=ext[EXT_IRQ01])
|
|
kbd_hand2();
|
|
Btr(&sys_irq_flags,1);
|
|
}
|
|
|
|
U8 DivU8(U8 n1,U8 n2)
|
|
{
|
|
U8 r_lo=n1,r_hi=0;
|
|
U8 i;
|
|
for (i=0;i<64;i++) {
|
|
if (r_lo & 0x8000000000000000) {
|
|
r_hi<<=1;
|
|
r_hi++;
|
|
} else
|
|
r_hi<<=1;
|
|
r_lo<<=1;
|
|
if (r_hi>=n2) {
|
|
r_hi-=n2;
|
|
r_lo++;
|
|
}
|
|
}
|
|
return r_lo;
|
|
}
|
|
|
|
I8 DivI8(I8 n1,I8 n2)
|
|
{
|
|
U8 r_lo,r_hi=0;
|
|
U8 i;
|
|
BoolU4 signed;
|
|
if (n1<0) {
|
|
signed=TRUE;
|
|
n1=-n1;
|
|
} else
|
|
signed=FALSE;
|
|
if (n2<0) {
|
|
signed=!signed;
|
|
n2=-n2;
|
|
}
|
|
r_lo=n1;
|
|
for (i=0;i<64;i++) {
|
|
if (r_lo & 0x8000000000000000) {
|
|
r_hi<<=1;
|
|
r_hi++;
|
|
} else
|
|
r_hi<<=1;
|
|
r_lo<<=1;
|
|
if (r_hi>=n2) {
|
|
r_hi-=n2;
|
|
r_lo++;
|
|
}
|
|
}
|
|
return (signed) ? -r_lo:r_lo;
|
|
}
|
|
|
|
U8 ModU8(U8 n1,U8 n2)
|
|
{
|
|
U8 r_lo=n1,r_hi=0;
|
|
U8 i;
|
|
for (i=0;i<64;i++) {
|
|
if (r_lo & 0x8000000000000000) {
|
|
r_hi<<=1;
|
|
r_hi++;
|
|
} else
|
|
r_hi<<=1;
|
|
r_lo<<=1;
|
|
if (r_hi>=n2) {
|
|
r_hi-=n2;
|
|
r_lo++;
|
|
}
|
|
}
|
|
return r_hi;
|
|
}
|
|
|
|
I8 ModI8(I8 n1,I8 n2)
|
|
{
|
|
U8 r_lo,r_hi=0;
|
|
U8 i;
|
|
BoolU4 signed;
|
|
if (n1<0) {
|
|
signed=TRUE;
|
|
n1=-n1;
|
|
} else
|
|
signed=FALSE;
|
|
if (n2<0) {
|
|
signed=!signed;
|
|
n2=-n2;
|
|
}
|
|
r_lo=n1;
|
|
for (i=0;i<64;i++) {
|
|
if (r_lo & 0x8000000000000000) {
|
|
r_hi<<=1;
|
|
r_hi++;
|
|
} else
|
|
r_hi<<=1;
|
|
r_lo<<=1;
|
|
if (r_hi>=n2) {
|
|
r_hi-=n2;
|
|
r_lo++;
|
|
}
|
|
}
|
|
return (signed) ? -r_hi:r_hi;
|
|
}
|
|
|
|
LTDate BootTime()
|
|
//Roughly 49,710ths of a second since boot
|
|
{
|
|
return DivU8(ReadSysTimer<<14,1833333*3*3*3/125);
|
|
}
|
|
|
|
U2 RandU2() //TODO: fix this
|
|
{
|
|
LTDate i=BootTime;
|
|
rnd_SEED^=MulU8(rnd_SEED,0x56234)+i.date^i.time^jiffies+ModU8(rnd_SEED,0x7635);
|
|
return rnd_SEED.u2[0];
|
|
}
|
|
|
|
U8 RandU4()
|
|
{
|
|
U8 result=0;
|
|
result.u2[0]=RandU2;
|
|
result.u2[1]=RandU2;
|
|
return result;
|
|
}
|
|
|
|
I8 ToUpper(I8 ch)
|
|
{
|
|
if (ch>='a' && ch<='z')
|
|
return ch+'A'-'a';
|
|
else
|
|
return ch;
|
|
}
|
|
|
|
I8 AtoI(I1 *st,I8 radix=10,I1 **end_ptr=NULL)
|
|
{
|
|
BoolU4 neg=FALSE;
|
|
I1 ch;
|
|
I8 result=0,k=0;
|
|
if (radix<2||radix>36) return 0;
|
|
while (*st==CH_SPACE || *st==CH_SHIFT_SPACE || *st==CH_TAB)
|
|
st++;
|
|
if (*st=='-') {
|
|
st++;
|
|
neg=TRUE;
|
|
}
|
|
if (*st=='+') st++;
|
|
while (ch=ToUpper(*st++)) {
|
|
k++;
|
|
if (radix==10) {
|
|
if (ch>='0' && ch<='9')
|
|
result=MulI8(result,10)+ch-'0';
|
|
else if (k==2 && !result) {
|
|
if (ch=='X')
|
|
radix=16;
|
|
else if (ch=='B')
|
|
radix=2;
|
|
else if (ch=='o')
|
|
radix=8;
|
|
else
|
|
break;
|
|
} else
|
|
break;
|
|
} else if (radix>10) {
|
|
if (ch>='0' && ch<='9')
|
|
result=MulI8(result,radix)+ch-'0';
|
|
else if (ch>='A' && ch<='A'+radix-11)
|
|
result=MulI8(result,radix)+ch-'A'+10;
|
|
else
|
|
break;
|
|
} else {
|
|
if (ch>='0' && ch<='0'+radix-1)
|
|
result=MulI8(result,radix)+ch-'0';
|
|
else
|
|
break;
|
|
}
|
|
}
|
|
if (end_ptr) *end_ptr=st-1;
|
|
return (neg)? -result:result;
|
|
}
|
|
|
|
|
|
void BusyWait(U8 uS) //Loosely timed
|
|
{
|
|
U8 i;
|
|
for (i=0;i<uS;i++)
|
|
PortNop;
|
|
}
|
|
|
|
void Sleep(U8 mS)
|
|
{
|
|
U8 old_flags=GetFlags;
|
|
U8 target_jiffies=jiffies+(mS*JIFFY_FREQ/1000);
|
|
Sti;
|
|
do SwapInNext;
|
|
while (jiffies<target_jiffies);
|
|
SetFlags(old_flags);
|
|
}
|
|
|
|
void Sound(U8 freq)
|
|
{
|
|
U8 p,old_flags=GetFlags;
|
|
if (Bt(&sys_flags,SYSf_NO_SOUND))
|
|
return;
|
|
if (freq) {
|
|
p=SYS_TIMER_FREQ/freq;
|
|
Cli;
|
|
OutP(0x43,0xB6);
|
|
OutP(0x42,p);
|
|
OutP(0x42,p.u1[1]);
|
|
OutP(0x61,3);
|
|
SetFlags(old_flags);
|
|
} else
|
|
OutP(0x61,0);
|
|
}
|
|
|
|
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);
|
|
}
|
|
|
|
BoolU4 Externs2Imports(BoolU4 val) {
|
|
return AssignBit(&Fs->last_lex->flags,LFf_EXTERNS_TO_IMPORTS,val);
|
|
}
|
|
|
|
BoolU4 KeepPrivate(BoolU4 val) {
|
|
return AssignBit(&Fs->last_lex->flags,LFf_KEEP_PRIVATE,val);
|
|
}
|
|
|
|
BoolU4 PTrace(BoolU4 val) {
|
|
return AssignBit(&Fs->last_lex->flags,LFf_PARSE_TRACE,val);
|
|
}
|
|
|
|
BoolU4 OTrace(BoolU4 val) {
|
|
return AssignBit(&Fs->last_lex->flags,LFf_OPT_TRACE,val);
|
|
}
|
|
|
|
BoolU4 CTrace(BoolU4 val) {
|
|
return AssignBit(&Fs->last_lex->flags,LFf_COMPILE_TRACE,val);
|
|
}
|
|
|
|
BoolU4 LTrace(BoolU4 val) {
|
|
return AssignBit(&Fs->last_lex->flags,LFf_LEX_TRACE,val);
|
|
}
|
|
|
|
BoolU4 NoRegVar(BoolU4 val) {
|
|
return AssignBit(&Fs->last_lex->flags,LFf_NO_REG_VAR,val);
|
|
}
|
|
|
|
BoolU4 Echo(BoolU4 val) {
|
|
return AssignBit(&Fs->last_lex->flags,LFf_ECHO,val);
|
|
}
|
|
|
|
BoolU4 SysEcho(BoolU4 val) {
|
|
return AssignBit(&Fs->last_lex->flags,LFf_ECHO,val);
|
|
}
|
|
|
|
BoolU4 Silent(BoolU4 val) {
|
|
return AssignBit(&Fs->crt_flags,CRTf_SILENT,val);
|
|
}
|
|
|
|
BoolU4 Preempt(BoolU4 val) {
|
|
return AssignBit(&sys_flags,SYSf_PREEMPTIVE,val);
|
|
}
|
|
|
|
BoolU4 SysDbg(BoolU4 val) {
|
|
return AssignBit(&sys_flags,SYSf_DEBUG,val);
|
|
}
|
|
|
|
BoolU4 IsSysDbg() {
|
|
return Bt(&sys_flags,SYSf_DEBUG);
|
|
}
|
|
|
|
BoolU4 Raw(BoolU4 val) {
|
|
if (val) {
|
|
OutP(VGA_SC_INDEX,VGA_MAP_MASK);
|
|
OutP(VGA_SC_DATA,0x0F);
|
|
}
|
|
return AssignBit(&sys_flags,SYSf_RAW_CRT_OUT,val);
|
|
}
|
|
|
|
BoolU4 IsRaw() {
|
|
return Bt(&sys_flags,SYSf_RAW_CRT_OUT);
|
|
}
|
|
|
|
U1 *Caller()
|
|
{
|
|
U4 *bp=GetBasePtr;
|
|
bp=*bp+4;
|
|
return *bp;
|
|
}
|
|
|
|
U1 *CallerCaller()
|
|
{
|
|
U4 *bp=GetBasePtr;
|
|
bp=*bp;
|
|
bp=*bp+4;
|
|
return *bp;
|
|
}
|
|
|
|
void DbgStr(I1 *st,U8 mS=100)
|
|
{
|
|
BoolU4 old_flags=GetFlags;
|
|
BoolU4 old_raw;
|
|
Cli;
|
|
old_raw=Raw(ON);
|
|
cout "DbgStr(",st,")";
|
|
BusyWait(mS<<10);
|
|
SetFlags(old_flags);
|
|
Raw(old_raw);
|
|
}
|
|
|
|
void DbgNum(U8 num,U8 mS=100)
|
|
{
|
|
BoolU4 old_flags=GetFlags;
|
|
BoolU4 old_raw;
|
|
Cli;
|
|
old_raw=Raw(ON);
|
|
cout "DbgNum(",num,")";
|
|
BusyWait(mS<<10);
|
|
SetFlags(old_flags);
|
|
Raw(old_raw);
|
|
}
|
|
|
|
void DbgF(double d,U8 mS=100)
|
|
{
|
|
BoolU4 old_flags=GetFlags;
|
|
BoolU4 old_raw;
|
|
Cli;
|
|
old_raw=Raw(ON);
|
|
cout "DbgF(",d,")";
|
|
BusyWait(mS<<10);
|
|
SetFlags(old_flags);
|
|
Raw(old_raw);
|
|
}
|
|
|
|
void DbgAdd(U4 *add,U8 mS=100)
|
|
{
|
|
BoolU4 old_flags=GetFlags;
|
|
BoolU4 old_raw;
|
|
Cli;
|
|
old_raw=Raw(ON);
|
|
PrintF("DbgAdd(%P)",add);
|
|
BusyWait(mS<<10);
|
|
SetFlags(old_flags);
|
|
Raw(old_raw);
|
|
}
|
|
|
|
void DbgD(U4 *add,U8 cnt=0x80,U8 mS=100)
|
|
{
|
|
BoolU4 old_flags=GetFlags;
|
|
BoolU4 old_raw;
|
|
Cli;
|
|
old_raw=Raw(ON);
|
|
D(add,cnt);
|
|
BusyWait(mS<<10);
|
|
SetFlags(old_flags);
|
|
Raw(old_raw);
|
|
}
|
|
|
|
void DbgDm(U4 *add,U8 cnt=0x80,U8 mS=100)
|
|
{
|
|
BoolU4 old_flags=GetFlags;
|
|
BoolU4 old_raw;
|
|
Cli;
|
|
old_raw=Raw(ON);
|
|
Dm(add,cnt);
|
|
BusyWait(mS<<10);
|
|
SetFlags(old_flags);
|
|
Raw(old_raw);
|
|
}
|
|
|
|
|
|
SysHashEntry *FindLocalHash(I1 *st,U8 mask)
|
|
{
|
|
return FindHashEntry(st,Fs->hash_table,mask);
|
|
}
|
|
|
|
void Beeps(U8 j,BoolU4 busy)
|
|
{
|
|
U8 i,f;
|
|
for (i=0;i<8;i++) {
|
|
if (Bt(&j,i+24)) {
|
|
f=200;
|
|
if (Bt(&j,i+8))
|
|
f+=400;
|
|
if (Bt(&j,i+16))
|
|
f+=800;
|
|
Sound(f);
|
|
if (busy) {
|
|
if (Bt(&j,i))
|
|
BusyWait(300000);
|
|
else
|
|
BusyWait(100000);
|
|
} else {
|
|
if (Bt(&j,i))
|
|
Sleep(400);
|
|
else
|
|
Sleep(150);
|
|
}
|
|
Sound(0);
|
|
}
|
|
if (busy)
|
|
BusyWait(150000);
|
|
else
|
|
Sleep(300);
|
|
}
|
|
}
|
|
|
|
void UnrecoverableSysError(U8 j)
|
|
{
|
|
Cli;
|
|
while (TRUE) {
|
|
Beeps(j,TRUE);
|
|
Raw(ON);
|
|
coutln "Unrecoverable SysError:",j;
|
|
BusyWait(500000);
|
|
}
|
|
}
|
|
|
|
asm {CP_BREAK::}
|
|
void Break()
|
|
{
|
|
ReleaseTaskPartitions;
|
|
IntFlushMsgs;
|
|
throw(EXCEPT_BREAK);
|
|
}
|
|
|
|
void ThrowDivide(U1 *eip)
|
|
{
|
|
throw(EXCEPT_ARITHMETIC,eip);
|
|
}
|
|
|
|
void ThrowFloating(U1 *eip)
|
|
{
|
|
throw(EXCEPT_FLOATING,eip);
|
|
}
|
|
|
|
|
|
SysHashEntry *FindPSect(U8 add,I8 *offset)
|
|
{
|
|
SysHashEntry *result=NULL,*temph;
|
|
SysHashTable *h=Fs->hash_table;
|
|
ClassStruct *tempc;
|
|
U8 i,best=0x8000,j;
|
|
|
|
while (h) {
|
|
for (i=0;i<=h->mask;i++) {
|
|
temph=h->body[i];
|
|
while (temph) {
|
|
if (temph->type&HTT_FUNCTION) {
|
|
tempc=temph;
|
|
j=tempc->executable_address;
|
|
} else
|
|
j=temph->user0;
|
|
j=add-j;
|
|
if (temph->type&(HTT_SYS_SYMBOL|HTT_FUNCTION)) {
|
|
if (j<best) {
|
|
best=j;
|
|
result=temph;
|
|
}
|
|
}
|
|
temph=temph->next;
|
|
}
|
|
}
|
|
h=h->next;
|
|
}
|
|
*offset=best;
|
|
return result;
|
|
}
|
|
|
|
|
|
U8 GetS(I1 *buf,U8 size)
|
|
{
|
|
I8 ch;
|
|
I1 *buf2;
|
|
U8 i=0;
|
|
void my_SysGetS();
|
|
if (!size || !buf) return 0;
|
|
i=FindExtern("SysGetS");
|
|
if (i) {
|
|
my_SysGetS=i;
|
|
buf2=my_SysGetS();
|
|
if (StrLen(buf2)>size-1) {
|
|
MemCpy(buf,buf2,size-1);
|
|
buf[size-1]=0;
|
|
} else
|
|
StrCpy(buf,buf2);
|
|
i=StrLen(buf);
|
|
Free(buf2);
|
|
} else {
|
|
while (TRUE) {
|
|
ch=GetKey;
|
|
if (ch==CH_CR) {
|
|
PutChar(ch);
|
|
break;
|
|
} if (ch==CH_BACKSPACE) {
|
|
if (i>0) {
|
|
i--;
|
|
PutChar(ch);
|
|
}
|
|
} else {
|
|
if (i<size-1) {
|
|
buf[i++]=ch;
|
|
PutChar(ch);
|
|
}
|
|
}
|
|
}
|
|
buf[i]=0;
|
|
}
|
|
return i;
|
|
}
|
|
|
|
|