00001 #include <stdio.h>
00002 #include <stdlib.h>
00003 #include <string.h>
00004
00005 #include "uctools.h"
00006
00007 static opcode_desc push_table[]=
00008 {
00009 {"true",0,0x13},
00010 {"false",0,0x14},
00011 {"itemref",0,0x3e},
00012 {"eventid",0,0x48}
00013 };
00014
00015 static opcode_desc pop_table[]=
00016 {
00017 {"eventid",0,0x4b}
00018 };
00019
00020 static const char* compiler_table[]=
00021 {
00022 ".argc",
00023 ".extern",
00024 ".externsize",
00025 ".localc"
00026 };
00027
00028 #define MAX_LABELS 3500
00029 #define TOKEN_LENGTH 25600
00030
00031 char token[TOKEN_LENGTH],*token2,curlabel[256],indata;
00032 int byte,word,pass,offset,datasize,codesize,funcnum;
00033 int extended;
00034
00035 char labels[MAX_LABELS][10];
00036 int offsets[MAX_LABELS];
00037 int lindex;
00038
00039 FILE *fo,*fi;
00040
00041 void emit_byte(int i)
00042 {
00043 if (pass>0)
00044 {
00045 fputc(i,fo);
00046 if (indata) datasize++;
00047 }
00048 offset++;
00049 codesize++;
00050 }
00051
00052 void emit_word(int i)
00053 {
00054 emit_byte(i&0xff);
00055 emit_byte((i>>8)&0xff);
00056 }
00057
00058 void emit_dword(int i)
00059 {
00060 emit_byte(i&0xff);
00061 emit_byte((i>>8)&0xff);
00062 emit_byte((i>>16)&0xff);
00063 emit_byte((i>>24)&0xff);
00064 }
00065
00066 void add_label(void)
00067 {
00068 int i;
00069 if (token[strlen(token)-1]==':')
00070 token[strlen(token)-1]=0;
00071 if (lindex>=MAX_LABELS)
00072 {
00073 printf("Too many labels.\n");
00074 exit(0);
00075 }
00076 for (i=0;i<lindex;i++)
00077 {
00078 if (!strcasecmp(token,labels[i]))
00079 {
00080 printf("Warning: label '%s' already exists.\n",token);
00081 return;
00082 }
00083 }
00084 strcpy(labels[lindex],token);
00085 offsets[lindex++]=offset;
00086 }
00087
00088 int get_label(void)
00089 {
00090 int i;
00091 for (i=0;i<lindex;i++)
00092 {
00093 if (!strcasecmp(token,labels[i]))
00094 return(offsets[i]);
00095 }
00096 printf("Warning: label '%s' does not exist.\n",token);
00097 if (token[0]=='L')
00098 sscanf(token,"L%x",&word);
00099 else
00100 sscanf(token,"%x",&word);
00101 return(word);
00102 }
00103
00104 void check_jump_label_16(int label)
00105 {
00106 if (label < -32768 || label > 32767)
00107 printf("Warning: offset too big for 16 bit at label %s!\n", curlabel);
00108 }
00109
00110 void check_data_label_16(int label)
00111 {
00112 if (label > 65535)
00113 printf("Warning: offset too big for 16 bit at label %s!\n", curlabel);
00114 }
00115
00116
00117 void read_token(FILE *fi)
00118 {
00119 int i=0,c=32;
00120 while (((c==' ') || (c=='\t') || (c=='\n') || (c==',')) && (!feof(fi)))
00121 c=fgetc(fi);
00122 while (!((c==' ') || (c=='\t') || (c=='\n') || (c==',')) && (!feof(fi)))
00123 {
00124 if (i >= TOKEN_LENGTH - 1) {
00125 fprintf(stderr, "Error: token too long!\n");
00126 exit(-1);
00127 }
00128 token[i++]=c;
00129 if (c==';')
00130 {
00131 while ((c=fgetc(fi))!='\n') ;
00132 i=0;
00133 }
00134 if (c==39)
00135 {
00136 while ((c=fgetc(fi))!='\n') {
00137 if (i >= TOKEN_LENGTH - 1) {
00138 fprintf(stderr, "Error: token too long!\n");
00139 exit(-1);
00140 }
00141 token[i++]=c;
00142 }
00143 ungetc(c,fi);
00144 i--;
00145 }
00146 c=fgetc(fi);
00147 }
00148
00149 if (i >= TOKEN_LENGTH - 1) {
00150 fprintf(stderr, "Error: token too long!\n");
00151 exit(-1);
00152 }
00153 token[i]=0;
00154 }
00155
00156 int main(int argc,char *argv[])
00157 {
00158 int i,opsize=sizeof(opcode_table)/sizeof(opcode_desc),
00159 pushsize=sizeof(push_table)/sizeof(opcode_desc),
00160 popsize=sizeof(pop_table)/sizeof(opcode_desc),
00161 compsize=sizeof(compiler_table)/sizeof(char*);
00162 int label;
00163 const char **func_table = bg_intrinsic_table;
00164 int funsize = bg_intrinsic_size;
00165 int findex = 1;
00166 unsigned int opcodetype;
00167 indata=codesize=datasize=0;
00168
00169
00170 if (argc<3)
00171 {
00172 printf("syntax: %s [-s] infile outfile\n", argv[0]);
00173 exit(0);
00174 }
00175
00176 if (strcmp(argv[1], "-s") == 0)
00177 {
00178 findex++;
00179 func_table = si_intrinsic_table;
00180 funsize = si_intrinsic_size;
00181 }
00182
00183 lindex=0;
00184 for (pass=0;pass<2;pass++)
00185 {
00186
00187 if ((fi=fopen(argv[findex],"r"))==NULL)
00188 {
00189 printf("Can't open infile for reading\n");
00190 exit(0);
00191 }
00192 if ((fo=fopen(argv[findex + 1],"wb"))==NULL)
00193 {
00194 printf("Can't open outfile for writing\n");
00195 exit(0);
00196 }
00197 while (!feof(fi))
00198 {
00199 read_token(fi);
00200 if (strlen(token)>1 && token[strlen(token)-1]==':') {
00201 token[strlen(token)-1]=0;
00202 if (pass == 0)
00203 add_label();
00204 strcpy(curlabel, token);
00205 }
00206 else if (!strcmp(token,".code"))
00207 {
00208 indata=0;
00209 offset=0;
00210 }
00211 else if (!strcmp(token,".data"))
00212 {
00213 if (extended == 0) {
00214 emit_word(funcnum);
00215 emit_word(0);
00216 emit_word(0);
00217 codesize = 2;
00218 } else {
00219 emit_word(-1);
00220 emit_word(funcnum);
00221 emit_dword(0);
00222 emit_dword(0);
00223 codesize = 4;
00224 }
00225
00226 indata=1;
00227 offset=0;
00228
00229 }
00230 else if (!strcmp(token,".funcnumber"))
00231 {
00232 read_token(fi);
00233 sscanf(token,"%x",&funcnum);
00234 printf("Function %04X\n", funcnum);
00235
00236 extended = 0;
00237 }
00238 else if (!strcmp(token,".ext32"))
00239 {
00240 extended = 1;
00241 }
00242 else if (token[0]=='.')
00243 {
00244 indata=0;
00245 for (i=0;i<compsize;i++)
00246 if (!strcasecmp(compiler_table[i],token))
00247 {
00248 read_token(fi);
00249 sscanf(token,"%x",&word);
00250 emit_word(word);
00251 }
00252 }
00253 else if (!strcmp(token,"db"))
00254 {
00255 read_token(fi);
00256 if (token[0]==39)
00257 for (i=1;i<strlen(token);i++)
00258 emit_byte(token[i]);
00259 else
00260 {
00261 sscanf(token,"%x",&byte);
00262 emit_byte(byte);
00263 }
00264 }
00265 else if (!strcasecmp(token,"dw"))
00266 {
00267 read_token(fi);
00268 sscanf(token,"%x",&word);
00269 emit_word(word);
00270 }
00271 else
00272 for (i=0;i<opsize;i++)
00273 {
00274 if (!opcode_table[i].mnemonic) continue;
00275 if (!strcasecmp(opcode_table[i].mnemonic,token))
00276 {
00277 if (opcode_table[i].nbytes==0 && opcode_table[i].type==0)
00278 emit_byte(i);
00279 else {
00280 opcodetype = opcode_table[i].type;
00281 if (i == 0x21) opcodetype = PUSH;
00282 if (i == 0x12) opcodetype = POP;
00283 switch (opcodetype)
00284 {
00285 case BYTE:
00286 emit_byte(i);
00287 read_token(fi);
00288 sscanf(token,"%x",&word);
00289 emit_byte(word);
00290 break;
00291 case CALL:
00292 emit_byte(i);
00293 read_token(fi);
00294 if ((token2=strchr(token,'@'))!=NULL)
00295 {
00296 token2++;
00297 read_token(fi);
00298 sscanf(token, "(%x)", &word);
00299 emit_word(word);
00300 sscanf(token2,"%d",&word);
00301 }
00302 else
00303 {
00304 sscanf(token,"%x",&word);
00305 emit_word(word);
00306 read_token(fi);
00307 sscanf(token,"%d",&word);
00308 }
00309 emit_byte(word);
00310 break;
00311 case DATA_STRING:
00312 emit_byte(i);
00313 read_token(fi);
00314 label = get_label();
00315 check_data_label_16(label);
00316 emit_word(label);
00317 break;
00318 case DATA_STRING32:
00319 emit_byte(i);
00320 read_token(fi);
00321 emit_dword(get_label());
00322 break;
00323 case EXTCALL:
00324 case VARREF:
00325 emit_byte(i);
00326 read_token(fi);
00327 sscanf(token,"[%x]",&word);
00328 emit_word(word);
00329 break;
00330 case FLGREF:
00331 emit_byte(i);
00332 read_token(fi);
00333 sscanf(token,"flag:[%x]",&word);
00334 emit_word(word);
00335 break;
00336 case PUSH:
00337 read_token(fi);
00338 for (i=0;i<pushsize;i++)
00339 {
00340 if (!strcasecmp(push_table[i].mnemonic,token))
00341 {
00342 emit_byte(push_table[i].type);
00343 break;
00344 }
00345 }
00346 if (i==pushsize)
00347 {
00348 emit_byte(0x21);
00349 sscanf(token,"[%x]",&word);
00350 emit_word(word);
00351 }
00352 break;
00353 case POP:
00354 read_token(fi);
00355 for (i=0;i<popsize;i++)
00356 {
00357 if (!strcasecmp(pop_table[i].mnemonic,token))
00358 {
00359 emit_byte(pop_table[i].type);
00360 break;
00361 }
00362 }
00363 if (i==popsize)
00364 {
00365 emit_byte(0x12);
00366 sscanf(token,"[%x]",&word);
00367 emit_word(word);
00368 }
00369 break;
00370 case IMMED:
00371 emit_byte(i);
00372 read_token(fi);
00373 sscanf(token,"%x",&word);
00374 emit_word(word);
00375 break;
00376 case IMMED32:
00377 emit_byte(i);
00378 read_token(fi);
00379 sscanf(token,"%x",&word);
00380 emit_dword(word);
00381 break;
00382 case RELATIVE_JUMP:
00383 emit_byte(i);
00384 read_token(fi);
00385 if (pass==1) {
00386
00387 label = get_label() - offset - 2;
00388 check_jump_label_16(label);
00389 emit_word(label);
00390 } else
00391 emit_word(-1);
00392 break;
00393 case RELATIVE_JUMP32:
00394 emit_byte(i);
00395 read_token(fi);
00396 if (pass==1) {
00397
00398 emit_dword(get_label()-offset-4);
00399 } else
00400 emit_dword(-1);
00401 break;
00402 case IMMED_AND_RELATIVE_JUMP:
00403 emit_byte(i);
00404 read_token(fi);
00405 sscanf(token,"%x",&word);
00406 emit_word(word);
00407 read_token(fi);
00408 if (pass==1) {
00409 label = get_label() - offset - 2;
00410 check_jump_label_16(label);
00411 emit_word(label);
00412 } else
00413 emit_word(-1);
00414 break;
00415 case IMMED_RELJUMP32:
00416 emit_byte(i);
00417 read_token(fi);
00418 sscanf(token,"%x",&word);
00419 emit_word(word);
00420 read_token(fi);
00421 if (pass==1)
00422 emit_dword(get_label()-offset-4);
00423 else
00424 emit_dword(-1);
00425 break;
00426 case SLOOP:
00427 #if 0
00428 emit_byte(0x2E);
00429 if (pass == 0) {
00430 sscanf(curlabel, "%x:",&word);
00431 sprintf(token,"%04X:",word+1);
00432 printf("adding sloop label %s (curlabel=%s)\n", token, curlabel);
00433 add_label();
00434 }
00435 #endif
00436 emit_byte(0x02);
00437 read_token(fi);
00438 sscanf(token,"[%x]",&word);
00439 emit_word(word);
00440 read_token(fi);
00441 sscanf(token,"[%x]",&word);
00442 emit_word(word);
00443 read_token(fi);
00444 sscanf(token,"[%x]",&word);
00445 emit_word(word);
00446 read_token(fi);
00447 sscanf(token,"[%x]",&word);
00448 emit_word(word);
00449 read_token(fi);
00450 sscanf(token,"%x",&word);
00451 if (pass==1) {
00452 label = get_label() - offset - 2;
00453 check_jump_label_16(label);
00454 emit_word(label);
00455 } else
00456 emit_word(-1);
00457 break;
00458 case SLOOP32:
00459 #if 0
00460 emit_byte(0xAE);
00461 if (pass == 0) {
00462 sscanf(curlabel, "%x:",&word);
00463 sprintf(token,"%04X:",word+1);
00464 printf("adding sloop label %s (curlabel=%s)\n", token, curlabel);
00465 add_label();
00466 }
00467 #endif
00468 emit_byte(0x82);
00469 read_token(fi);
00470 sscanf(token,"[%x]",&word);
00471 emit_word(word);
00472 read_token(fi);
00473 sscanf(token,"[%x]",&word);
00474 emit_word(word);
00475 read_token(fi);
00476 sscanf(token,"[%x]",&word);
00477 emit_word(word);
00478 read_token(fi);
00479 sscanf(token,"[%x]",&word);
00480 emit_word(word);
00481 read_token(fi);
00482 sscanf(token,"%x",&word);
00483 if (pass==1)
00484 emit_dword(get_label()-offset-2);
00485 else
00486 emit_dword(-1);
00487 break;
00488 default:
00489 break;
00490 }
00491 }
00492 }
00493
00494 }
00495 }
00496
00497 if (extended == 0) {
00498 fseek(fo,2,SEEK_SET);
00499 indata=0;
00500 i=codesize;
00501
00502 if (codesize > 65535) {
00503 printf("Error: code size > 64Kb and not in ext32 mode!\n");
00504 }
00505 emit_word(i);
00506
00507 if (datasize > 65535) {
00508 printf("Error: data size > 64Kb and not in ext32 mode!\n");
00509 }
00510
00511 emit_word(datasize);
00512 } else {
00513 fseek(fo,4,SEEK_SET);
00514 indata=0;
00515 i=codesize;
00516 emit_dword(i);
00517 emit_dword(datasize);
00518 }
00519 fclose(fo);
00520 fclose(fi);
00521 }
00522 return 0;
00523 }