📄 mmugen.c
字号:
notted=0;
}
else
{
global.rule.cb |= 1 ;
}
//completed rule, so implement it
return 1 ;
case NOT :
notted=1;
break;
case LARGEPAGES :
global.rule.entrytype = 'L';
break ;
case SMALLPAGES :
global.rule.entrytype = 'S';
break ;
case POSTPROCESS :
GetWord(buffer); //skip ENTRY
GetWord(buffer); //get address
fseek( global.outfile, atox(buffer) ,SEEK_SET );
GetWord(buffer); //skip EQUALS
GetWord(buffer); //get value
i = atox(buffer);
fwrite( &i, 4, 1, global.outfile );
break ;
case UNRECOGNISED:
printf("Unrecognised word '%s'\n",buffer);
}
}
// must have hit end of rule file without finding the end of a rule
return 0;
}
//--WRITETABLEENTRIES--------------------------------------------------------
int WriteTableEntries (void)
{
switch( global.state )
{
case 1: return WriteLevel1();
case 2: return WriteLevel2();
default: printf("MMU page table level not set\n");
return -1;
}
}
//--WRITELEVEL1--------------------------------------------------------------
int WriteLevel1(void)
{
unsigned long fields ;
unsigned long physical ;
unsigned long writevalue ;
unsigned long i ;
/* Check the table-entry number matches the virtual base address for this section */
if( global.table_entry != (global.rule.v_base>>20) )
{
printf("MMU Table synchronisation error!\n table_entry = %08lx, v_base = %08lx\n",
global.table_entry, global.rule.v_base);
return -1 ;
}
if (global.rule.entrytype == 'S' || global.rule.entrytype == 'F')
{
if(global.rule.entrytype == 'S')
{
fields = 0x12 | (global.rule.access<<10) | (global.rule.cb<<2) ;
}
else
{
fields = 0; //generate fault on access
}
physical = global.rule.p_base ;
/* generate all the SECTION entries for this descriptor */
for (i = global.rule.v_base; i<global.rule.v_end; )
{
writevalue = physical|fields ;
fwrite( &writevalue, 4, 1, global.outfile );
global.table_entry++ ;
physical += 0x100000 ;
/* check for memory wrap-round */
i+=0x100000 ;
if (i==0x00000000) break;
}
}
else
{
/* Single PAGE entry */
writevalue = 0x11 + global.base_address + 0x4000 + 0x400*global.pagescount++ ;
fwrite( &writevalue, 4, 1, global.outfile );
global.table_entry++ ;
}
return 0 ;
}
//--WRITELEVEL2--------------------------------------------------------------
int WriteLevel2(void)
{
unsigned long fields ;
unsigned long physical ;
unsigned long writevalue ;
unsigned long i ;
/* work out repeated data fields - note: this line would change if per-page access levels were to be supported*/
fields = (global.rule.access << 10)|(global.rule.access << 8)|(global.rule.access << 6)|(global.rule.access << 4)|(global.rule.cb <<2);
if (global.rule.entrytype == 'L')
{
fields |= 1 ;
}
else
{
fields |= 2 ;
}
/* create entries for this descriptor */
i = global.rule.v_base ;
physical = global.rule.p_base ;
while(i<global.rule.v_end)
{
if( global.rule.entrytype == 'L' )
{
int j ;
writevalue = physical|fields ;
for( j=16; j; j-- )
{
fwrite( &writevalue, 4, 1, global.outfile );
}
physical += 0x10000;
i += 0x10000;
}
else
{
writevalue = physical|fields ;
fwrite( &writevalue, 4, 1, global.outfile );
physical += 0x1000;
i += 0x1000;
}
}
return 0 ;
}
//--GETWORD------------------------------------------------------------------
// fetch next word, stepping over whitespace and comments
// return 0 if end-of-file
int GetWord (char *buffer)
{
int c=fgetc(global.rulefile);
while(c=='\t' || c==' ' || c=='/' || c==0xd || c==0xa)
{
if( c=='/') //start of comment
{
do
{
c=fgetc(global.rulefile);
} while( c!= '/' ) ;
// get next character beyond comment
c=fgetc(global.rulefile);
}
while( c=='\t' || c==' ' || c==0xd || c==0xa ) c=fgetc(global.rulefile);
}
// Check for end of file
if( c==EOF ) return 0;
// Ok, should be at the start of a word
while ( c!='\t' && c!=' ' && c!=0xd && c!=0xa && c!=EOF)
{
*buffer++ = (char)c ;
c=fgetc(global.rulefile);
}
//terminate word
*buffer = '\0';
return 1;
}
//--GETWORDINDEX-------------------------------------------------------------
int GetWordIndex (char *buffer)
{
int index=0 ;
while ( parsedata[index].index != UNRECOGNISED
&& stricomp(parsedata[index].word,buffer) )
{
index++ ;
}
return index ;
}
//--ATOX---------------------------------------------------------------------
long atox( char *buffer)
{
long v=0;
while(*buffer)
{
v*=16;
if(*buffer>='0' && *buffer<='9') v+= *buffer - '0';
if(*buffer>='a' && *buffer<='f') v+= *buffer - 'a'+10;
if(*buffer>='A' && *buffer<='F') v+= *buffer - 'A'+10;
buffer++;
}
return v ;
}
//--STRICOMP-----------------------------------------------------------------
/*
The program originally used stricmp, but this does
not appear to be included in the ARM C library.
This is not a true stricmp (or strcmpi), since only
the "match" string is converted to upper case,
allowing "original" to be in read-only memory.
*/
int stricomp( char *original, char *match )
{
char *ptr = match ;
while(*ptr)
{
*ptr=toupper(*ptr) ;
ptr++ ;
}
return strcmp(original,match) ;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -