//main.ctp Copyright (C) 1989-2008 I.Pedley (CTPP) Tue 17-May-2005 at 20:09:17
//28.12.2009 ChaOS type system revision
#include {os.htm}
#include {i86.htm}
#include {time.htm}
#include {conio.htm}
#include {80x86.htm}
#include {box.htm}
#include {stdlib.htm}
#include {string.htm}
#include {chaoskey.htm}
#include {accdis.htm}
#include {pci.htm}
#include {dev.htm}
SL catdisp(UL row,UL col,CH* format,...);
SL stacksize(VD);
VD stackfill(VD);
SL stackused(VD);
VD emergency(VD);
UL pagebase;
UL OSflags;
UL OSbase;
UL OSsize;
UL memtop;
UL stacktop;
UL stackbase;
UL DOSpsp;
VD clrallbps(VD);
//extern in mem.ctp
EX UL validatefree;
//extern in cmos.ctp
UL getCMOShimem(VD);
#include {heap.htm}
//extern in sym.ctp
VD initSYM(VD);
VD symutils(UL key);
//extern in pic.ctp
VD maskIRQ(UL irq);
VD unmaskIRQ(UL irq);
VD _enable(VD);
VD _disable(VD);
//externs in gen.ctp
EX CH* banner;
EX UL vispage;
VD outmsg(CH* msg);
VD outmem (UC* mem,UL buflen,UL row,UL col);
VD outmemd(UL* mem,UL buflen,UL row,UL col);
VD outstr (CH* str,UL row,UL col);
VD outchar(CH c, UL row,UL col);
VD outhexdword(UL dword,UL row,UL col);
VD setvisiblepage(SL page);
SL getvisiblepage(VD);
EX UC* videobase;
VD clrscreen(VD);
//extern in string.ctp
VD memcpy(VD* dst,VD* src,UL bytes);
//externs in keybd.ctp
VD kbdcmd(UL cmdbyte);
SL getkey(VD);
EX CH* kbddisp;
EX CH* hdcdisp;
EX CH* netdisp;
EX CH* vbuf;
//for LDRIVE structure
#include {drive.htm}
//externs in ipx.ctp
VD termNET(VD);
VD netutils(UL key);
UL getCMOStime(VD);
UL getCMOSdate(VD);
//in gen.ctp
VD set8x8charset(VD);
VD displaycharset(UL row,UL col);
VD displaybanners(VD);
//in SCSI.ctp
VD initSCSI(VD);
VD initIRQ(VD); //in irq.ctp
VD shutdown(UC shutdownbyte);
VD setvbuf(CH* buf);
VD mhidecursor(VD);
VD mshowcursor(VD);
EX UL inrmdebugger;
VD storevscreen(VD)
{
if(inrmdebugger){return;}
// mhidecursor();
if(vbuf)
memcpy(vbuf,videobase+24000,80*50*2);
// mshowcursor();
}
VD getvscreen(VD)
{
if(inrmdebugger){return;}
// mhidecursor();
if(vbuf)
memcpy(videobase+24000,vbuf,80*50*2);
// mshowcursor();
}
EX UL inmalloc;
EX UL inaccdis;
EX UL indebugger;
EX UL inemergency;
EX UL inpoll;
EX UL ldrives;
EX UL devpaths;
EX SL goingdownflag;
VD initDEV(VD);
SL termDEV(VD);
VD oscleanup(VD)
{//perform any necessary re-initialisation of globals before hot reboot
setthread((CBJHEADER*)OSbase);
vbuf=NULL;
goingdownflag=0;
ldrives=0;
inaccdis=0;
indebugger=0;
inemergency=0;
inpoll=0;
inmalloc=0;
clicur=8;
devpaths=0;
initIRQ();
}
//in ipx.ctp
EX UL network;
SL initPAG(VD);
UL* getpagetableentry(UL lin);
VD cli(VD);
SL invoke(CH* commandline,UL len);
VD initENV(VD);
VD setdevpaths(LDRIVE* l);
SL v_invoke(CH* format,...);
SL clidisplay(CH* format,...);
UL initPCI(UL init,UL disp);
VD initDIG(VD);
VD flushfilesystems(UL all);
VD relocateOS(UL newbase);
//in brd.ctp
VD initBRD(VD);
// UC* savedataarea;
//VD savedata(VD)
//{
// CBJHEADER* c=(CBJHEADER*)OSbase;
// savedataarea=malloc(c->dlen);
// UC* ptr=(UC*)OSbase+c->hdrlen+c->dbase;
// memcpy(savedataarea,ptr,c->dlen);
//}
VD initVGA(VD);
VD pagingon(VD);
VD versionstring(CH* str,UL vno,UL zeroterminate);
SL memstats(UL argc,CH* argv[]);
SL downloadfile(CH* fname,UL fsiz,VD* buf);
UL storemachineinfo(VD);
SL getprocessor(VD);
VD maketlookup(CBJHEADER* c);
VD initSYS(VD);
VD initVT0(VD);
VD initSCR(VD);
VD initMSG(VD);
#include {bootmap.htm}
MODESWITCHES* getmodeswitches(VD);
VD setrmPICmasks(VD);
SL findfile (CH* fname);
VD initPRC(VD); //process.ctp
VD initDEV(VD); //dev.ctp
VD initLEGACY(VD); //dev.ctp
SL vesatest(VD);
SL initPnP(UL disp); //pnp.ctp
VD rmtest(VD);
SL initKBD(DEV* d);
VD emptyKBD(VD);
VD loadSRVs(UL max,UL min);
VD rmint(UL intno,DPMIREGS* d);
UL setkbdLEDs(UL locks);
SL initAPIC(VD);
#include {gl.htm}
#include {vesa.htm}
EX VESA* vesa;
VD set8x8font(MEMBUF* mb);
SL setfont(MEMBUF* mb,CH* rootname);
VD bindpointerstovesa(VD);
VD initvesaenvironment(VD);
SL initWND1(VD);
VD osmemory(VD);
SL countmsds(VD);
SL createbdds(UL flg);
VD osvmode(VD)
{
BSINFO* bsi=(BSINFO*)bmLOAD; //pointer bootstrap info
if(!bsi->vflags)
{
DPMIREGS d;memset(&d,0,sizeof(DPMIREGS));
d.eax=3;
realmodeinterrupt(0x10,&d); //set CGA mode 3
bsi->vmode=3;
}
else
{
vesa=(VESA*)bsi->bsendptr;
UC* ptr=(UC*)vesa;
vesa->vbc=(VBCINFO*) vesa->info;
vesa->vbm=(VBMINFO*)(vesa->info+0x200);
vesa->pal= vesa->info+0x300;
vesa->framelen=vesa->mb.buflen=vesa->vbm->pitch*vesa->vbm->h;
UL align=0x10000;
UL msize=vesa->framelen*VESAFRAMES;
msize+=align-1;msize/=align;msize*=align;
memtop-=msize;
vesa->mb.buf=(UC*)memtop;
vesa->mb.pages=VESAFRAMES;
initvesaenvironment();
bsi->vflags=3; //vesa mode is set+membuf can be used
}
}
VD osmain(VD)
{
BSINFO* bsi=(BSINFO*)bmLOAD; //pointer bootstrap info
oscleanup();
initPRC();
dcat(2,0,"ChaOS Full Debug version, initialising debug info....");
initSYM(); //link up symbol tables etc if they are there
initDEV(); //resets DEV table, IRQ table
initMSG();
initLEGACY(); //sets up 9 legacy devices
//CGA CPU RAM PIC DMA TMR RTC KBD BBD
initMSG();
VESA* v=vesa;
VBCINFO* vbc=v->vbc;
VBMINFO* vbm=v->vbm;
UC* pal=v->pal;
if(bsi->vflags)
{
bindpointerstovesa(); //bind pointers after device scan
initWND1(); //GUI test
}
displaybanners(); //construct banners once time and date are known
//TMR device now running
//display some info
CBJHEADER* os=(CBJHEADER*)OSbase;
CH verstr[12]; versionstring(verstr,os->ver,1);
DB q=(DB)OSsize/0x100000;
dcat(2,0,"os %s (flags=0x%04X,base=0x%08X,size=%6.3dMb (0x%08X))",verstr,&OSflags,&OSbase,&q,&OSsize);
initENV(); //start environment string list
if(*(UC*)0x417&0x10) //BIOS keyboard scroll lock on
{
clidisplay("|c1400Legacy mode: no DRVs loaded |c700(BIOS keyboard scroll lock on)");
*(UC*)0x417=0x20;
setkbdLEDs(kbdstate=NUMLOCK);
}
else{
initAPIC();
loadSRVs(5,4); //protocol servers level 5 and 4 IP and ARP
initPCI (1,0); //device scan
// initPnP (0);
}
// initSCSI();
initMSG();
loadSRVs(3,1); //protocol servers level 3 SLPSRV
//message servers level 2 TELSRV FTPSRV HTPSRV
//application servers level 1 PRNSRV
if(LDcur)
{
//don't invoke setup if running over DOS
if(!(OSflags&DOSLOAD))
{
if(!strcmp(LDcur->tag,"bootcd"))
{
setdevpaths(LDcur); //just in case partially installed
v_invoke("setup"); //ChaOS drive has set paths to hda1:\\
}
}
}
if(!countmsds())
{//if no mass storage devices found
//create bda mass storage containers for boot devices
createbdds(0);
}
else
{
createbdds(1);
}
initSYS();
if(!(kbdstate&LSHIFT))
{
if(!findfile("\\go.job"))
{
clidisplay("Found autorun file |c1500go.job");
v_invoke("go");
}
}
cli(); //first call to cli() calls initSCR() and initMSG()
SL key;
UI cw;
UL* pt;
//on exit from shell, fall through to old utilities
while(1)
{
key=dgetkey();
switch(vispage)
{
case 3: //send keystrokes to virtual screen in view
if(vbuf==netdisp)
{
netutils(key&0xffff);
}
break;
case 2:
symutils(key&0xffff);
break;
case 0:
switch(key&0xffff)
{
case (ALT|F12):
cli();
break;
case (ALT|F11):
emergency();
break;
case (ALT|F10):
goto B000;
break;
}
default:
break;
}
}//end while(1)
B000:
setvisiblepage(0);
UL n=stackused();
clidisplay("stackused() is 0x%08X",&n);
n=_memavl();
clidisplay("_memavl() 0x%08X bytes heapsize is 0x%08X bytes validatefree= %1l",&n,&heapsize,&validatefree);
B001:
clidisplay("System halted: restart= DOS Netboot Reboot=");
key=dgetkey();
switch(key&0xffff)
{
case F1:
// oscleanup();
break;
case F5: //test divide by zero trap int_00
#asm
mov ecx,0
div ecx
#endasm
break;
case F6: //test breakpoint trap int_03
#asm
op 0xcc
op 0xf1
#endasm
goto B001;
case F7: //test GP fault trap int_13
#asm
mov eax,0xaaaa
push eax
pop ds
#endasm
case F8: //switch paging on
#asm
mov eax,pagebase
mov cr3,eax
mov eax,cr0
or eax,FLGPG
mov cr0,eax
#endasm
goto B001;
// case F9: //test page fault trap int_14
//#asm
// mov edi,memtop
// dec edi
// stosb
// stosb
// stosb
//#endasm
// goto B001;
case F2:
if(OSflags&NETWORKLOAD)
{
*(UC*)NETROMRESTARTFLAG=0;
}
clrscreen();
shutdown(10);
break;
case F9:
if(OSflags&NETWORKLOAD)
{
*(UC*)NETROMRESTARTFLAG=7;
}
shutdown(10);
break;
case F10:
if(OSflags&NETWORKLOAD)
{
*(UC*)NETROMRESTARTFLAG=3;
}
shutdown(10);
break;
case F11:
if(OSflags&NETWORKLOAD)
{
*(UC*)NETROMRESTARTFLAG=1;
}
shutdown(10);
break;
case F12:
shutdown(0);
break;
case (CTRL|F12):
asm
{
// fstcw cw
// mov cw,0x37e
// or wp cw,1
// fldcw cw
fldpi
fldpi
fldpi
fldpi
fldpi
fldpi
fldpi
fldpi
fldpi
fldpi
fldpi
fldpi
}
break;
case (ALT|F12):
clidisplay("OPTION:");
if(!acceptat(clicur,0,"Enter address to move to 0x%08X",&n))
{
relocateOS(n);
}
goto B001; //in case relocateOS() returned after address error
break;
default:
goto B001;
}
PICSoff(); //mask both PICS off to halt hardware
//before fall through to RESTART
}
VD devhalt(VD);
SL termSRV(VD);
VD clrscreen(UL page);
codelabel RESTART; //for emergency() jmp back into startup code
VD emergency(VD)
{
termSRV();
termNET();
flushfilesystems(1);
// termDEV();
// unmaskIRQ(1);
devhalt();
termDEV();
PICSoff();
clrallbps();
clrscreen(0);
asm{
mov ebx,OSbase //just in case
jmp RESTART
}
}
VD relocateOS(UL newbase)
{
if(newbaseOSbase)
{
clidisplay("Address 0x%08X is within current ChaOS session!",&newbase);
return;
}
}
flushfilesystems(1);
memcpy((CH*)newbase,(CH*)OSbase,OSsize);
asm
{
mov edi,ebx //edi is OSbase for this image
mov ebx,newbase //ebx becomes base of new image
mov esi,dp [ebx+0x80] //get file offset of fastreloc table
add esi,ebx //adjust for loader offset
mov ecx,dp [ebx+0x84] //get fastreloc count
cmp ecx,0 //test for no relocs, just in case you can
jz RELOCSDONE //write an operating system with none at all
NEXTRELOC:
lodsw
sub dp [eax+ebx],edi //reverse fastrelocs for this image
loop NEXTRELOC
RELOCSDONE:
mov eax,newbase
add eax,0x200
mov edi,eax
mov eax,OSflags
mov edx,OSsize
// call edi
}
}
//SHUTDOWN section, including DOS restart preparation
VD restorelowmem(VD);
VD shutdown(UC shutdownbyte)
{
termSRV();
termNET();
flushfilesystems(1);
usecdelay(10000);
sndalldevs(DM_SHUTDOWN,0,0,0);
//reset processor, old-style, via kbd controller!
asm
{
cli
mov al,0x8f
out 0x70,al
mov al,shutdownbyte
out 0x71,al
mov al,0xfe //pulse bit 0 on kbd controlller
out 0x64,al
SHUTDOWN:
hlt
jmp SHUTDOWN
}
}
CH* goingdownmsg[]={
" ...Hot reboot",
" ...Return to bootstrap...(or DOS if it's there)...",
" ...Hot boot rom restart...(send BOOTINIT to server)",
" ...Warm boot rom restart...(re-detect network card)",
" ...Cold boot rom restart...",
" ...Reboot processor...",
" ...Don't shutdown"
};
UL goingdownvalid[]={1,0,0,0,0,1,1};
EX UL shutarg;
VD drestorebox(BOX* b,CH* ptr);
CH* dsavebox(BOX* b);
VD dbox1(BOX* b,UL no,CH* str,UI col);
SL dcat(UL row,UL col,CH* format,...);
VD dclear(BOX* b,UL col);
VD goingdown(VD)
{
if(goingdownflag){return;} //stop keyboard polling loop from re-entering!
goingdownflag=1;
UL vis=getvisiblepage();
setvisiblepage(0);
BOX bp ={10,10,24,70};
BOX bp1 ={25,40,44,78};
CH* ptr=dsavebox(&bp);
dclear(&bp,0);
dbox1(&bp,-1,"System shutdown options",0x20);
CH* ptr1=dsavebox(&bp1);
dclear(&bp1,0);
dbox1(&bp1,-1,"Some system stats",0x60);
UL n=stackused();
UL m=stacksize();
UL o;
o=muldiv(n,100,m);
dcat(bp1.t+1,bp1.l+1,"stack used %8l of %8l %2l%%",&n,&m,&o);
n=_memused();
o=muldiv(n,100,heapsize);
dcat(bp1.t+2,bp1.l+1," heap used %8l of %10l %2l%%",&n,&heapsize,&o);
o=n&0xfffff;
n/=0x100000;
o=muldiv(o,100,0x100000);
m=heapsize/0x100000;
dcat(bp1.t+3,bp1.l+1," only %4l.%02lMb of %4lMb ",&n,&o,&m);
// n=_memavl();
// dcat(bp.t+2,bp.l+1,"_memavl() 0x%08X bytes heapsize is 0x%08X bytes validatefree= %1l",&n,&heapsize,&validatefree);
B001:
dcat(bp.t+3 ,bp.l+1,"Even ChaOS has to end sometime...");
if(OSflags&NETWORKLOAD){goingdownvalid[2]=goingdownvalid[3]=goingdownvalid[4]=1;}
if(OSflags&DOSLOAD) {goingdownvalid[1]=1;}
for(n=0;n<7;n++)
{
if(goingdownvalid[n])
{
dcat(bp.t+5+n ,bp.l+1,goingdownmsg[n]);
}
else
{
dcat(bp.t+5+n ,bp.l+1,"%sc800",goingdownmsg[n]);
}
}
UL key=dgetkey();
switch(key&0xffff)
{
case F1:
emergency();
break;
case F2:
if(OSflags&NETWORKLOAD)
{
*(UC*)NETROMRESTARTFLAG=0;
}
clrscreen();
shutdown(10);
break;
case F9:
if(OSflags&NETWORKLOAD)
{
*(UC*)NETROMRESTARTFLAG=7;
}
shutdown(10);
break;
case F10:
if(OSflags&NETWORKLOAD)
{
*(UC*)NETROMRESTARTFLAG=3;
}
shutdown(10);
break;
case F11:
if(OSflags&NETWORKLOAD)
{
*(UC*)NETROMRESTARTFLAG=1;
}
shutdown(10);
break;
case F12:
*(UI*)0x472=0x1234;
shutdown(shutarg);
break;
default:
goto B001;
case ESC:
break;
}
drestorebox(&bp, ptr);
drestorebox(&bp1, ptr1);
setvisiblepage(vis);
goingdownflag=0;
}