Files
TempleOS-Rijn/LT/UTILS/DBG.CPZ
T
2018-09-08 21:45:17 +02:00

1078 lines
24 KiB
Plaintext

InstructionEntry **disasm_table=NULL;
I8 disasm_table_entries=0;
I8 CompareInstructionEntries(InstructionEntry **tempi1,InstructionEntry **tempi2)
{
I8 i1,i2,j=0,result=0;
while (TRUE) {
if (j<(*tempi1)->opcode_cnt && j<(*tempi2)->opcode_cnt) {
i1=(*tempi1)->opcode[j];
i2=(*tempi2)->opcode[j];
result=i1-i2;
if (result) return result;
j++;
} else {
i1=(*tempi1)->opcode_cnt;
i2=(*tempi2)->opcode_cnt;
result=i1-i2;
if (result) return result;
i1=(*tempi1)->slash_value;
i2=(*tempi2)->slash_value;
if (i1==8) i1=-1;
if (i2==8) i2=-1;
result=i1-i2;
if (result) return result;
i1=(*tempi1)->operand_size32;
i2=(*tempi2)->operand_size32;
result=i1-i2;
if (result) return result;
return result;
}
}
}
void LoadDisasmTable()
{
SysHashTable *h=asm_hash;
OpcodeHashEntry *temph;
InstructionEntry *tempi;
U8 cnt=0;
I8 i,j,k;
for (i=0;i<=h->mask;i++) {
temph=h->body[i];
while (temph) {
if (temph->type==HTT_OPCODE)
cnt+=temph->instruction_entry_cnt;
temph=temph->next;
}
}
disasm_table_entries=cnt;
j=0;
disasm_table=MAlloc(cnt*PTR_SIZE);
for (i=0;i<=h->mask;i++) {
temph=h->body[i];
while (temph) {
if (temph->type==HTT_OPCODE) {
tempi=&temph->ins;
for (k=0;k<temph->instruction_entry_cnt;k++) {
disasm_table[j++]=tempi;
tempi+=sizeof(InstructionEntry);
}
}
temph=temph->next;
}
}
QSort(disasm_table,cnt,PTR_SIZE,&CompareInstructionEntries);
}
if (!disasm_table)
LoadDisasmTable;
BoolU4 PutSourceLine(U4 *add,U8 cnt)
{
ClassStruct *tempc;
U8 i,minl,maxl,offset;
DbgInfo *dbg;
U4 *body;
I1 *src,*src2;
tempc=FindPSect(add,&offset);
if (tempc) {
dbg=tempc->debug;
if (dbg) {
body=dbg->body;
minl=dbg->min_line;
maxl=dbg->max_line;
for (i=minl;i<=maxl;i++) {
if ((body[i-minl]>=add) &&
(body[i-minl]<add+cnt)) {
src=NewString(tempc->source_link);
src2=MAlloc(StrLen(src)+1);
RemoveFirstSeg(src,":",src2);
RemoveLastSeg(src,",",src2);
PrintF("$$LK -A \"FL:%s,%d\"$$",src,i);
Free(src);
Free(src2);
return TRUE;
}
}
}
}
return FALSE;
}
public void DasmIns(I1 *buf,U1 **add,BoolU4 use16=FALSE)
{
U1 *ip=*add,*bb;
U2 *ww;
U4 *dd;
I4 disp,imm;
BoolU4 opsize16=use16,opadd16=use16,cont;
I4 i,j,k,l,m,o1,o2,a1,a2,aa1,aa2,arg1_size=0,arg2_size=0,a1_size,a2_size,
ModrM=-1,SIB=-1,scale,r1,r2,
Mod=-1,RM1=-1,RM2=-1;
InstructionEntry *tempi;
OpcodeHashEntry *tempo,dummy;
I1 *a1_st,*a2_st,*bin_data_area,*bin_data_area2,
buf2[256],buf3[256],seg_overrides[40],arg1_st[256],arg2_st[256];
*arg1_st=0;
*arg2_st=0;
a1_st=arg1_st;
a2_st=arg2_st;
if (PutSourceLine(ip,1))
CrLf;
SPrintF(buf,"%16tP ",ip);
bin_data_area=buf+StrLen(buf);
for (i=0;i<6;i++) {
SPrintF(buf2,"%02X",ip[i]);
StrCat(buf,buf2);
}
StrCat(buf," ");
SPrintF(buf3,"%16tP ",ip+6);
bin_data_area2=buf3+StrLen(buf3);
for (i=6;i<12;i++) {
SPrintF(buf2,"%02X",ip[i]);
StrCat(buf3,buf2);
}
*seg_overrides=0;
cont=TRUE;
do {
switch (*ip++) {
case 0x2E: StrCat(seg_overrides,"CS:"); break;
case 0x36: StrCat(seg_overrides,"SS:"); break;
case 0x3E: StrCat(seg_overrides,"DS:"); break;
case 0x26: StrCat(seg_overrides,"ES:"); break;
case 0x64: StrCat(seg_overrides,"FS:"); break;
case 0x65: StrCat(seg_overrides,"GS:"); break;
case 0x66: opsize16=!opsize16; break;
case 0x67: opadd16=!opadd16; break;
default: cont=FALSE;
}
} while (cont);
ip--;
i=0;
j=disasm_table_entries-1;
do {
k=(i+j)>>1; //binary search
tempi=disasm_table[k];
m=0;
l=0;
while (TRUE) {
if (l<tempi->opcode_cnt) {
o1=ip[l];
if (l==tempi->opcode_cnt-1 &&
tempi->plus_opcode)
o1&=-8;
o2=tempi->opcode[l];
m=o1-o2;
l++;
if (m)
break;
} else {
if (tempi->slash_value<8) {
o1=(ip[l] >> 3) & 7;
o2=tempi->slash_value;
m=o1-o2;
if (!m) {
if (opsize16) {
if (tempi->operand_size32)
m=-1;
} else {
if (tempi->operand_size16)
m=1;
}
}
break;
} else {
m=0;
if (opsize16) {
if (tempi->operand_size32)
m=-1;
} else {
if (tempi->operand_size16)
m=1;
}
break;
}
}
}
if (m>0) {
if (k==i) {
k=j;
break;
} else
i=k;
} else if (m<0) {
if (k-i<=1) {
k=i;
break;
} else
j=k;
} else
break;
} while (TRUE);
tempi=disasm_table[k];
ip+=tempi->opcode_cnt;
tempo=tempi-(tempi->ins_entry_num*sizeof(InstructionEntry))+&dummy-&dummy.ins;
StrCat(buf,tempo->string);
a1=tempi->arg1;
a2=tempi->arg2;
aa1=a1;
aa2=a2;
StrCpy(buf2,SysTextSub(a1,"ST_ARGUMENT_TYPES"));
if (StrStr(buf2,"8"))
arg1_size=1;
else if (StrStr(buf2,"16"))
arg1_size=2;
else if (StrStr(buf2,"32"))
arg1_size=4;
StrCpy(buf2,SysTextSub(a2,"ST_ARGUMENT_TYPES"));
if (StrStr(buf2,"8"))
arg2_size=1;
else if (StrStr(buf2,"16"))
arg2_size=2;
else if (StrStr(buf2,"32"))
arg2_size=4;
a1_size=arg1_size;
a2_size=arg2_size;
if (tempi->plus_opcode && (tempi->slash_value==8 ||
tempi->opcode_modifier>=OM_RB && tempi->opcode_modifier<=OM_RD)) {
ip--;
RM1=*(ip++) - tempi->opcode[tempi->opcode_cnt-1];
*buf2=0;
if (a1>=ARGT_R8 && a1<=ARGT_R32) {
if (a1_size==1)
SPrintF(buf2,"%Z",RM1,"ST_U1_REGS");
else if (a1_size==2)
SPrintF(buf2,"%Z",RM1,"ST_U2_REGS");
else if (a1_size==4)
SPrintF(buf2,"%Z",RM1,"ST_U4_REGS");
StrCat(a1_st,buf2);
} else {
if (a2_size==1)
SPrintF(buf2,"%Z",RM1,"ST_U1_REGS");
else if (a2_size==2)
SPrintF(buf2,"%Z",RM1,"ST_U2_REGS");
else if (a2_size==4)
SPrintF(buf2,"%Z",RM1,"ST_U4_REGS");
StrCat(a2_st,buf2);
}
}
if ((a1>=ARGT_RM8 && a1<=ARGT_RM32) ||
(a2>=ARGT_RM8 && a2<=ARGT_RM32)) {
if (a2>=ARGT_RM8 && a2<=ARGT_RM32) {
a1_st=arg2_st;
a2_st=arg1_st;
a1_size=arg2_size;
a2_size=arg1_size;
aa1=a2;
aa2=a1;
}
StrCat(a1_st,seg_overrides);
ModrM=*(ip++);
Mod=(ModrM>>6) & 3;
RM1=ModrM & 7;
RM2=(ModrM>>3) & 7;
if (Mod<3 && RM1==4) {
SIB=*(ip++);
}
if (Mod==1) {
bb=ip;
disp=*bb;
SPrintF(buf2,"%02X",disp);
StrCat(a1_st,buf2);
ip++;
}
if (Mod==2) {
dd=ip;
disp=*dd;
SPrintF(buf2,"%08X",disp);
StrCat(a1_st,buf2);
ip=ip+4;
}
if (tempi->slash_value<8)
RM2=-1;
else {
*buf2=0;
if (aa2==ARGT_SREG)
SPrintF(buf2,"%Z",RM2,"ST_SEG_REGS");
else if (!(aa2>=ARGT_IMM8 && aa2<=ARGT_IMM32) &&
!(aa2>=ARGT_UIMM8 && aa2<=ARGT_UIMM32)) {
if (a2_size==1)
SPrintF(buf2,"%Z",RM2,"ST_U1_REGS");
else if (a2_size==2)
SPrintF(buf2,"%Z",RM2,"ST_U2_REGS");
else if (a2_size==4)
SPrintF(buf2,"%Z",RM2,"ST_U4_REGS");
}
StrCat(a2_st,buf2);
}
if (RM1==5 && Mod==0) {
dd=ip;
disp=*dd;
SPrintF(buf2,"[%X] ",disp);
StrCat(a1_st,buf2);
ip=ip+4;
RM1=-1;
} else {
if (Mod<3) {
if (RM1==4) {
RM1=-1;
r1=SIB & 7;
r2=(SIB >> 3) & 7;
scale=(SIB >> 6) &3;
if (scale==3)
scale=8;
else if (scale==2)
scale=4;
else if (scale==1)
scale=2;
else
scale=1;
if (r1==5 && Mod==0) {
dd=ip;
disp=*dd;
SPrintF(buf2,"%08X",disp);
StrCat(a1_st,buf2);
ip=ip+4;
SPrintF(buf2,"[%Z*%d]",r2,"ST_U4_REGS",scale);
StrCat(a1_st,buf2);
} else {
SPrintF(buf2,"[%Z+%Z*%d]",r1,"ST_U4_REGS",
r2,"ST_U4_REGS",scale);
StrCat(a1_st,buf2);
}
} else {
*buf2=0;
if (opadd16)
SPrintF(buf2,"[%Z]",RM1,"ST_U2_REGS");
else
SPrintF(buf2,"[%Z]",RM1,"ST_U4_REGS");
StrCat(a1_st,buf2);
}
} else {
*buf2=0;
if (a1_size==1)
SPrintF(buf2,"%Z",RM1,"ST_U1_REGS");
else if (a1_size==2)
SPrintF(buf2,"%Z",RM1,"ST_U2_REGS");
else if (a1_size==4)
SPrintF(buf2,"%Z",RM1,"ST_U4_REGS");
StrCat(a1_st,buf2);
}
}
}
if (a1>=ARGT_MOFFS8 && a1<=ARGT_MOFFS32) {
StrCat(arg1_st,seg_overrides);
if (arg1_size==1) {
bb=ip;
disp=*bb;
ip++;
SPrintF(buf2,"[%X]",disp);
StrCat(arg1_st,buf2);
} else if (opadd16) {
ww=ip;
disp=*ww;
ip=ip+2;
SPrintF(buf2,"[%X]",disp);
StrCat(arg1_st,buf2);
} else {
dd=ip;
disp=*dd;
ip=ip+4;
SPrintF(buf2,"[%X]",disp);
StrCat(arg1_st,buf2);
}
}
if (a2>=ARGT_MOFFS8 && a2<=ARGT_MOFFS32) {
StrCat(arg2_st,seg_overrides);
if (arg2_size==1) {
bb=ip;
disp=*bb;
ip++;
SPrintF(buf2,"[%X]",disp);
StrCat(arg2_st,buf2);
} else if (opadd16) {
ww=ip;
disp=*ww;
ip=ip+2;
SPrintF(buf2,"[%X]",disp);
StrCat(arg2_st,buf2);
} else {
dd=ip;
disp=*dd;
ip=ip+4;
SPrintF(buf2,"[%X]",disp);
StrCat(arg2_st,buf2);
}
}
if (a1==ARGT_IMM8 || a1==ARGT_UIMM8) {
bb=ip;
imm=*bb;
SPrintF(buf2,"%02X",imm);
StrCat(arg1_st,buf2);
ip++;
} else if (a1==ARGT_IMM16 || a1==ARGT_UIMM16) {
ww=ip;
imm=*ww;
SPrintF(buf2,"%04X",imm);
StrCat(arg1_st,buf2);
ip=ip+2;
} else if (a1==ARGT_IMM32 || a1==ARGT_UIMM32) {
dd=ip;
imm=*dd;
SPrintF(buf2,"%08X",imm);
StrCat(arg1_st,buf2);
ip=ip+4;
} else if (a1==ARGT_REL8) {
bb=ip;
disp=*bb;
if (disp>=0x80)
disp=disp | 0xFFFFFF00;
ip++;
disp=disp+ip;
SPrintF(buf2,"%P ",disp);
StrCat(arg1_st,buf2);
} else if (a1==ARGT_REL16) {
ww=ip;
disp=*ww;
if (disp>=0x8000)
disp=disp | 0xFFFF0000;
ip=ip+2;
disp=disp+ip;
SPrintF(buf2,"%P ",disp);
StrCat(arg1_st,buf2);
} else if (a1==ARGT_REL32) {
dd=ip;
disp=*dd;
ip=ip+4;
disp=disp+ip;
SPrintF(buf2,"%P ",disp);
StrCat(arg1_st,buf2);
} else if (a1==ARGT_CL)
StrCat(arg1_st,"CL");
else if (a1==ARGT_AL)
StrCat(arg1_st,"AL");
else if (a1==ARGT_AX)
StrCat(arg1_st,"AX");
else if (a1==ARGT_EAX)
StrCat(arg1_st,"EAX");
else if (a1==ARGT_DX)
StrCat(arg1_st,"DX");
else if (a1==ARGT_SS)
StrCat(arg1_st,"SS");
else if (a1==ARGT_DS)
StrCat(arg1_st,"DS");
else if (a1==ARGT_ES)
StrCat(arg1_st,"ES");
else if (a1==ARGT_FS)
StrCat(arg1_st,"FS");
else if (a1==ARGT_GS)
StrCat(arg1_st,"GS");
else if (a1==ARGT_CS)
StrCat(arg1_st,"CS");
if (a2==ARGT_IMM8 || a2==ARGT_UIMM8) {
bb=ip;
imm=*bb;
SPrintF(buf2,"%02X",imm);
StrCat(arg2_st,buf2);
ip++;
} else if (a2==ARGT_IMM16 || a2==ARGT_UIMM16) {
ww=ip;
imm=*ww;
SPrintF(buf2,"%04X",imm);
StrCat(arg2_st,buf2);
ip=ip+2;
} else if (a2==ARGT_IMM32 || a2==ARGT_UIMM32) {
dd=ip;
imm=*dd;
SPrintF(buf2,"%08X",imm);
StrCat(arg2_st,buf2);
ip=ip+4;
} else if (a2==ARGT_CL)
StrCat(arg2_st,"CL");
else if (a2==ARGT_AL)
StrCat(arg2_st,"AL");
else if (a2==ARGT_AX)
StrCat(arg2_st,"AX");
else if (a2==ARGT_EAX)
StrCat(arg2_st,"EAX");
else if (a2==ARGT_DX)
StrCat(arg2_st,"DX");
else if (a2==ARGT_SS)
StrCat(arg2_st,"SS");
else if (a2==ARGT_DS)
StrCat(arg2_st,"DS");
else if (a2==ARGT_ES)
StrCat(arg2_st,"ES");
else if (a2==ARGT_FS)
StrCat(arg2_st,"FS");
else if (a2==ARGT_GS)
StrCat(arg2_st,"GS");
else if (a2==ARGT_CS)
StrCat(arg2_st,"CS");
if (*arg1_st) {
StrCat(buf,"\t");
StrCat(buf,arg1_st);
}
if (*arg2_st) {
StrCat(buf,",");
StrCat(buf,arg2_st);
}
for (i=ip-*add;i<6;i++) {
bin_data_area[i<<1]=CH_SPACE;
bin_data_area[i<<1+1]=CH_SPACE;
}
for (i=ip-*add;i<12;i++) {
bin_data_area2[(i-6)<<1]=CH_SPACE;
bin_data_area2[(i-6)<<1+1]=CH_SPACE;
}
StrCat(buf,"\r\n");
if (ip-*add>6) {
StrCat(buf,buf3);
StrCat(buf,"\r\n");
}
*add=ip;
}
public U1 *Dasm(U1 *ip,U8 cnt=20,BoolU4 use16=FALSE)
{ //This counts instructions
I8 i;
I1 buf[512];
for (i=0;i<cnt;i++) {
DasmIns(buf,&ip,use16);
cout buf;
}
return ip;
}
public I8 Dasm2(U1 *ip,U8 cnt=0x80,BoolU4 use16=FALSE)
{ //This does an address range, not instruction count
I8 i=0;
U1 *end_ip=ip+cnt;
I1 buf[512];
while (ip<end_ip) {
DasmIns(buf,&ip,use16);
cout buf;
i++;
}
return i;
}
#define PF_ARRAY_CNT 8192
U8 pf_jiffies=0;
U8 pf_low=0,pf_high=SYS_CS_SIZE,pf_size=PF_ARRAY_CNT;
U4 pf_array[PF_ARRAY_CNT];
U4 chained_timer_routine=ext[EXT_IRQ00];
BoolU4 prof_on=FALSE;
void ProfileTimerIrq(U8 ip)
{
void my_Chained();
U8 i;
if (prof_on) {
i=(ip-pf_low) * pf_size/(pf_high-pf_low);
if (i>=0 && i<pf_size)
pf_array[i]++;
}
my_Chained=chained_timer_routine;
my_Chained();
}
ext[EXT_IRQ00]=&ProfileTimerIrq;
public void Prof(U1 *start,U8 cnt=PF_ARRAY_CNT*3)
{
if (cnt<PF_ARRAY_CNT)
pf_size=cnt;
else
pf_size=PF_ARRAY_CNT;
pf_low=start;
pf_high=start+cnt;
MemSet(pf_array,0,PF_ARRAY_CNT<<2);
pf_jiffies=jiffies;
prof_on=TRUE;
}
public void ProfRep(U8 filter_cnt=1)
{
I8 i,ip,last_ip=pf_low,hits;
U8 total_time=jiffies-pf_jiffies,
routine_total=0;
I1 buf[128],buf2[128],buf3[128],last_buf[128];
prof_on=FALSE;
if (!total_time) total_time=1;
*last_buf=0;
for (i=0;i<pf_size;i++) {
ip=pf_low+i*(pf_high-pf_low)/pf_size;
SPrintF(buf,"%P",ip);
StrCpy(buf3,buf);
RemoveFirstSeg(buf3,",",buf2);
if (StrCmp(buf2,last_buf)) {
if (*last_buf && routine_total>=filter_cnt) {
PrintF("$$FG GREEN$$%3d.%02d%% %08X:",routine_total*100/total_time,
routine_total*10000/total_time%100,routine_total);
PrintF("%s\r\n$$FG$$",last_buf);
}
StrCpy(last_buf,buf2);
routine_total=0;
}
hits=pf_array[i];
routine_total+=hits;
if (hits>=filter_cnt) {
PrintF("%3d.%02d%% %08X:",hits*100/total_time,
hits*10000/total_time%100,hits);
if (!PutSourceLine(ip,ip-last_ip+1))
PrintF("%s\r\n",buf);
else
CrLf;
last_ip=ip;
}
}
if (*last_buf && routine_total>=filter_cnt) {
PrintF("$$FG GREEN$$%3d.%02d%% %08X:",routine_total*100/total_time,
routine_total*10000/total_time%100,routine_total);
PrintF("%s\r\n$$FG$$",last_buf);
}
prof_on=TRUE;
}
public void FunRep(I1 *st)
{
ClassStruct *tempc=FindLocalHash(st,HTT_FUNCTION);
MemberListStruct *tempm;
if (tempc) {
tempm=tempc->member_list;
while (tempm) {
PrintF("%08X %s\r\n",tempm->offset,tempm->string);
tempm=tempm->next;
}
}
}
public BoolU4 CheckPtr(U1 *ptr)
{
if (ptr>=sys_heap_base && ptr<=sys_heap_limit)
return TRUE;
else if (ptr<sys_boot_base)
return FALSE;
else if (ptr<SYS_CS_SIZE)
return TRUE;
else
return FALSE;
}
void ClassRep2(Ltf *l,U1 *d,I1 *class_name,I8 depth,U8 types=HTT_CLASS)
{
U8 i,j;
MemberListStruct *ml;
I1 ch,*s,*s2;
U4 *ptr;
U8 *ptr2;
ClassStruct *cl2,*cl=FindLocalHash(class_name,types);
if (!cl) {
LtfPutS(l,"Class Not Found.\r\n");
return;
}
if (!CheckPtr(d) || !CheckPtr(d+cl->size)) {
LtfPrintF(l,"Bad Ptr:%08X\r\n",d);
return;
}
LtfPrintF(l,"Class:\"%s\"\r\n",class_name);
ml=cl->member_list;
while (ml) {
cl2=ml->member_class;
ptr=d+ml->offset;
LtfPrintF(l,"%08X ",ptr);
j=cl2->pointer_cnt;
cl2-=cl2->pointer_cnt*sizeof(ClassStruct);
while (cl2->return_class) {
cl2=cl2->return_class;
cl2-=cl2->pointer_cnt*sizeof(ClassStruct);
}
if (cl2->type & HTT_INTERNAL_TYPE) {
LtfPrintF(l,"$$FG GREEN$$%-20ts:$$FG$$",ml->string);
if (!j && ml->cnt==0) {
switch (cl2->sub_type) {
case IT_I1:
LtfPrintF(l,"%02X '%c'",ptr->u1[0],ptr->u1[0]);
break;
case IT_U1:
LtfPrintF(l,"%02X",ptr->u1[0]);
break;
case IT_I2:
LtfPrintF(l,"%04X",ptr->u2[0]);
break;
case IT_U2:
LtfPrintF(l,"%04X",ptr->u2[0]);
break;
case IT_I4:
LtfPrintF(l,"%08X",*ptr);
break;
case IT_U4:
LtfPrintF(l,"%08X",*ptr);
break;
case IT_I8:
ptr2=ptr;
LtfPrintF(l,"%016X",*ptr2);
break;
case IT_U8:
ptr2=ptr;
LtfPrintF(l,"%016X",*ptr2);
break;
case IT_DOUBLE:
ptr2=ptr;
LtfPrintF(l,"%16g",*ptr2);
break;
default:
LtfPrintF(l,"%08X",*ptr);
break;
}
} else if ((j==1 || ml->cnt) &&
cl2->sub_type==IT_I1) {
if (j==1) {
if (CheckPtr(*ptr)) {
s2=MStringUtil(*ptr,SU_SAFE_DOLLAR);
LtfPrintF(l,"\"%40ts\"",s2);
Free(s2);
}
} else {
if (ml->cnt<40)
s=ptr+ml->cnt;
else
s=ptr+40;
ch=*s;
*s=0;
s2=MStringUtil(ptr,SU_SAFE_DOLLAR);
LtfPrintF(l,"\"%s\"",s2);
Free(s2);
*s=ch;
}
} else if (ml->cnt>0 && ml->cnt<=32 && !j) {
for (i=0;i<ml->cnt;i++) {
switch (cl2->sub_type) {
case IT_I1:
LtfPrintF(l,"%02X '%c' ",ptr->u1[0],ptr->u1[0]);
ptr+=1;
break;
case IT_U1:
LtfPrintF(l,"%02X ",ptr->u1[0]);
ptr+=1;
break;
case IT_I2:
LtfPrintF(l,"%04X ",ptr->u2[0]);
ptr+=2;
break;
case IT_U2:
LtfPrintF(l,"%04X ",ptr->u2[0]);
ptr+=2;
break;
case IT_I4:
LtfPrintF(l,"%08X ",*ptr);
ptr+=4;
break;
case IT_U4:
LtfPrintF(l,"%08X ",*ptr);
ptr+=4;
break;
case IT_I8:
ptr2=ptr;
LtfPrintF(l,"%016X ",*ptr2);
ptr+=8;
break;
case IT_U8:
ptr2=ptr;
LtfPrintF(l,"%016X ",*ptr2);
ptr+=8;
break;
case IT_DOUBLE:
ptr2=ptr;
LtfPrintF(l,"%16g ",*ptr2);
ptr+=8;
break;
default:
LtfPrintF(l,"%08X ",*ptr);
ptr+=4;
break;
}
}
} else
LtfPrintF(l,"%08X",*ptr);
LtfPutS(l,"\r\n");
} else {
if (depth<2) {
if (j==1 && !CheckPtr(*ptr))
LtfPrintF(l,"%-20ts:%08X\r\n",ml->string,*ptr);
else {
LtfPrintF(l,"$$TR,\"%s\"$$\r\n",ml->string);
LtfPutS(l,"$$ID,2$$");
if (!j)
ClassRep2(l,ptr,cl2->string,depth+1);
else if (j==1)
ClassRep2(l,*ptr,cl2->string,depth+1);
LtfPutS(l,"$$ID,-2$$");
}
} else
LtfPrintF(l,"%-20ts\r\n",ml->string);
}
ml=ml->next;
}
}
public void ClassRep(U1 *d,I1 *class_name)
{
BoolU4 old_preempt=Preempt(OFF);
LtfSetMax(MAX_I4);
ClassRep2(Fs->cur_ltf,d,class_name,0);
LtfPutS(Fs->cur_ltf,"\r\n");
LtfRecalc(Fs->cur_ltf);
Preempt(old_preempt);
}
public void MachineRegsRep()
{
ClassStruct *cl,*cn;
MemberListStruct *ml;
MachineRegsStruct m;
I4 *i_ptr;
GetMachineRegs(&m);
cl=FindLocalHash("MachineRegsStruct",HTT_CLASS);
ml=cl->member_list;
while (ml) {
if (ml->fmtstr) {
i_ptr=&m+ml->offset;
cn=ml->member_class;
if (cn->type==HTT_INTERNAL_TYPE && ml->cnt==0) {
if (ml->fmtdata)
PrintF(ml->fmtstr,*i_ptr,ml->fmtdata);
else
PrintF(ml->fmtstr,*i_ptr);
PrintF(" %P",*i_ptr);
} else {
if (ml->fmtdata)
PrintF(ml->fmtstr,i_ptr,ml->fmtdata);
else
PrintF(ml->fmtstr,i_ptr);
PrintF(" %P",*i_ptr);
}
CrLf;
}
ml=ml->next;
}
CrLf;
}
public void TssRep(TssStruct *tss=NULL)
{
ClassStruct *cl,*cn;
MemberListStruct *ml;
I4 *i_ptr;
if (!tss) tss=Fs;
cl=FindLocalHash("TssStruct",HTT_CLASS);
ml=cl->member_list;
while (ml) {
if (ml->fmtstr) {
i_ptr=tss+ml->offset;
cn=ml->member_class;
if ((cn->type & HTT_INTERNAL_TYPE) && ml->cnt==0) {
if (ml->fmtdata)
PrintF(ml->fmtstr,*i_ptr,ml->fmtdata);
else
PrintF(ml->fmtstr,*i_ptr);
PrintF(" %P",*i_ptr);
} else {
if (ml->fmtdata)
PrintF(ml->fmtstr,i_ptr,ml->fmtdata);
else
PrintF(ml->fmtstr,i_ptr);
PrintF(" %P",*i_ptr);
}
CrLf;
}
ml=ml->next;
}
CrLf;
}
public void StackRep(U4 *esp)
{
U8 i;
U4 my_esp[32];
BoolU4 old_preempt=Preempt(OFF);
for (i=0;i<32;i++) {
my_esp[i]=*esp;
esp=esp+4;
}
Preempt(old_preempt);
for (i=0;i<32;i++)
PrintF("%08X [ESP+%04X]: %08X %P\r\n",my_esp+i<<2,i<<2,my_esp[i],my_esp[i]);
CrLf;
}
void DrawIt()
{
ClearWindowText;
}
public void ViewDisk(I1 drive=0)
{
LTPartition *p=DriveToPartition(drive);
U1 *old_update_window=Fs->update_window;
Ltf *old_ltf=Fs->cur_ltf;
U8 lohi,c1,i,x,y,
l=(grheight-3*FONT_HEIGHT)*(grwidth-FONT_WIDTH<<1),
s=(p->size+p->spc-1)/p->spc;
U8 sc,ch;
U1 *bitmap;
GrBitMap *base=GrNew(grbase);
if (p->type!=PT_LT)
return;
MaximizeWindow;
UpdateDerivedTssValues(Fs);
Fs->update_window=&DrawIt;
Fs->cur_ltf=NULL;
GrClear;
ClearWindowText;
try {
i=((s+7)>>3+BLK_SIZE-1)/BLK_SIZE;
bitmap=MAlloc(BLK_SIZE*i);
RBlks(p,bitmap,p->MAP1,i,TRUE);
i=0;
for (y=0;y<(grheight-3*FONT_HEIGHT);y++) {
if (ScanChar(&sc,&ch))
break;
for (x=0;x<(grwidth-FONT_WIDTH<<1);x++) {
lohi=MulI8(i,s);
c1=lohi/l;
if (Bt(bitmap,c1))
base->color=ROP_XOR+(GR_BLUE^GR_WHITE);
else
base->color=ROP_XOR+(GR_WHITE^GR_WHITE);
GrPlot3(base,x,y,0);
i++;
}
}
Free(bitmap);
} catch
UnlockPartition(p);
GetChar;
Fs->update_window=old_update_window;
GrClear;
Fs->cur_ltf=old_ltf;
}
void ChkDskList(LTDirEntry *tempm1,U1 *bits,U1 *bits2,U8 size,U8 bpc)
{
LTDirEntry *tempm2;
U8 i,j;
tempm2=tempm1->next; //skip "." directory
while (tempm1) {
tempm2=tempm1->next;
if (tempm1->attr & LT_ATTR_DIR) {
if (tempm1->sub) {
coutln SysText("ST_SCANNING_DIRECTORY"),tempm1->full_name;
ChkDskList(tempm1->sub,bits,bits2,size,bpc);
}
}
j=(tempm1->size+bpc-1)/bpc;
for (i=0;i<j;i++) {
if (i+tempm1->cluster>size) {
PutSysText("ST_ERR_START");
coutln "Invalid Cluster:",tempm1->full_name,
" Cluster:",i+tempm1->cluster;
PutSysText("ST_ERR_END");
break;
}
if (Bts(bits,i+tempm1->cluster)) {
PutSysText("ST_ERR_START");
coutln "Double Alloc:",tempm1->full_name,
" Cluster:",i+tempm1->cluster;
PutSysText("ST_ERR_END");
}
if (!Btr(bits2,i+tempm1->cluster)) {
PutSysText("ST_ERR_START");
coutln "UnAlloc:",tempm1->full_name,
" Cluster:",i+tempm1->cluster;
PutSysText("ST_ERR_END");
}
}
DelLTDirEntry(tempm1);
tempm1=tempm2;
}
}
public void ChkDsk(I1 drive=0)
{
U8 i,j,bpc,size,my_flags=(1<<FUf_RECURSE);
LTPartition *p=DriveToPartition(drive);
I1 *mask=MSPrintF("%c:/*",PartitionToDrive(p));
U1 *bits,*bits2;
if (p->type!=PT_LT) {
PutSysText("ST_NOT_LT");
return;
}
size=(p->size-(p->data-p->offset))/p->spc;
bits=MAllocZ((size+7)>>3);
bits2=MAllocZ((size+7)>>3+BLK_SIZE);
RBlks(p,bits2,p->MAP1,((size+7)>>3+BLK_SIZE-1)/BLK_SIZE,TRUE);
bpc=p->spc*BLK_SIZE;
j=1; //TODO: get rootdir size
for (i=0;i<j;i++) {
if (i+p->root_cluster>size) {
PutSysText("ST_ERR_START");
coutln "Invalid Cluster: RootDir",
" Cluster:",i+p->root_cluster;
PutSysText("ST_ERR_END");
break;
}
if (Bts(bits,i+p->root_cluster)) {
PutSysText("ST_ERR_START");
coutln "Double Alloc: RootDir",
" Cluster:",i+p->root_cluster;
PutSysText("ST_ERR_END");
}
if (!Btr(bits2,i+p->root_cluster)) {
PutSysText("ST_ERR_START");
coutln "UnAlloc: RootDir",
" Cluster:",i+p->root_cluster;
PutSysText("ST_ERR_END");
}
}
ChkDskList(FindFiles(mask,&my_flags),bits,bits2,size,bpc);
for (i=1;i<size;i++)
if (Bt(bits2,i))
coutln "Shouldn't Alloc Cluster:",i;
Free(mask);
Free(bits);
Free(bits2);
}