home *** CD-ROM | disk | FTP | other *** search
Wrap
/* SIM1.C: A SATURN TO C CONVERTER... copyright (1990) by Peter Hawkins This programme is hereby placed in the public domain. Not to be sold in whole or part for financial gain. No liability will be accepted by the author. Do not remove this copyright notice. Parts of it are not-too-well written, and it produces messy code, but I don't really care! Peter Hawkins: apm279l@vaxc.cc.monash.edu.au Suggestions/comments/additions welcome. Flames to: bush@whitehouse.gov This version: Long is assumed to be four-byte, so all registers are 2-longs. a,b,c,d,d1,d0,st and p are all 64 bit, but only the relevant nybbles are used. The return-to-RPL address, stack pointer, d and b are used, but are initially set to arbitrary values. A jump to RPL is detected. Other jumps to memory are processed by the routine in labels.h (this allows you to add a table of "known" addresses of ROM subroutines.) The routine will warn you if you jump to RPL without restoring D,B D1 or D0. If you write to memory, this *is not* done, instead, a message is displayed to say what was written and where. Similarly, You are prompted for memory contents when you read from memory *unless* the routine in labels.h detects a read from a "known" location (eg stack). The commands sethex and setdec are not implemented yet - all operations are in HEX at this stage. If someone extends this send me a copy. I'd also like copies of any other extensions including additions to the labels.h file. I don't have time to do this stuff myself. The hardware status registors are not implemented, nor is IN or OUT; opcodes which use them are ignored. The opcodes used are Alonzo's improved set, with one additional command: "show_re[gisters]" which causes the contents of all registers to be printed whenever the programme reaches that point. If you select the "printout" mode at the prompt, the source code will behave like a (crudish) debugger. You can step through the "pseudo opcodes" one at a time, or several at a time, alter register contents, and the registors are displayed after each step. You've got some self-modifying code? bad luck; won't work sorry - this is a crude debugger - I don't think it's worth allowing for every eventuality at this stage. You may want to add to labels.h. Also, the screen functions are set up for a VT100, if you use another sort of terminal, just change the escape sequences (first routines in sim1.h) */ #include <stdio.h> #include <string.h> FILE *infd, *outfd; int inptr = 0,min,max,i,digit,bufptr,dotpos,ret_count=0,print_mode=0 ; char ch,field[4],r1[19],r2[4],buffer[50],label[20]; getbuff() { char ch1; bufptr = 0; buffer[bufptr] = 0; /* in case blank line or comment only */ dotpos = 0; while ( (!feof(infd)) && ((ch1=fgetc(infd)) != 10)) { if (ch1 == 59) { while (fgetc(infd) != 10); if (bufptr) break; } else { if ((ch1 > 31) || (ch1 == 9)) buffer[bufptr++] = ch1; if (ch1 == '.') dotpos = bufptr; if( ch1 == ':' ) { fprintf(outfd,"\n"); buffer[bufptr] = 0; fprintf(outfd,"%s\n",buffer); if (print_mode) fprintf(outfd,"printf(%c%s\\n%c);\n",34,buffer,34); bufptr = 0; dotpos = 0; } } } while ((bufptr > 0)&&(buffer[bufptr-1] < 33)) bufptr--; /*strip trailing junk */ buffer[bufptr] = 0; /* terminate string */ bufptr = 0; } char gtchar() /* finds & returns to next non-junk char, or end of string */ { char ch1; ch1 = 1; while ( (ch1 != 0) && ((ch1=buffer[bufptr++]) < 33 )); return ch1; } int get_token() { #define num_3_tokens 18 static char token_table3[num_3_tokens][3] = { "pop","clr","inc","dec","add","sub","and","rln","rrn", "srn","srb","sln","neg","not","nop","brz","ret","or." }; #define num_4_tokens 19 static char token_table4[num_4_tokens][4] = { "move","swap","push","clrb","setb","call","jump","breq", "brne","brgt","brlt","brge","brle","brbc","brbs","brcc", "brcs","brnz","retz"}; #define num_5_tokens 11 static char token_table5[num_5_tokens][5] = { "reteq","retne","retgt","retlt","retge","retle","retbc", "retbs","retcc","retcs","retnz"}; #define num_7_tokens 3 static char token_table7[num_7_tokens][7] = { "retsetc","retclrc","show_re"}; int pos1,token,i; pos1 = bufptr; if (dotpos) { bufptr = dotpos; for (i = 0; i < 4; ++i) field[i] = 0; field[0]=buffer[bufptr++]; if ((buffer[bufptr] > 31) && (field[0] < 58) && (buffer[bufptr] < 58)) field[1] = buffer[bufptr++]; else if (((field[0] == 'w') && (buffer[bufptr] == 'p')) || ((field[0] == 'x') && (buffer[bufptr] == 's'))) field[1] = buffer[bufptr++]; else if (field[0] == 'p') { i = 1; while (buffer[bufptr] > 31) field[i++] = buffer[bufptr++]; } } else strcpy(field,"def"); token = -1; for (i = 0; i < num_7_tokens; ++i) { if (!strncmp(&buffer[pos1],&token_table7[i][0],7)) token =i+num_5_tokens +num_4_tokens+num_3_tokens; } if (token >= 0) { if (!dotpos) bufptr += 7; return (token); } for (i = 0; i < num_5_tokens; ++i) { if (!strncmp(&buffer[pos1],&token_table5[i][0],5)) token =i+num_4_tokens +num_3_tokens; } if (token >= 0) { if (!dotpos) bufptr += 5; return (token); } for (i = 0; i < num_4_tokens; ++i) { if (!strncmp(&buffer[pos1],&token_table4[i][0],4)) token =i+num_3_tokens; } if (token >= 0) { if (!dotpos) bufptr += 4; return (token); } token = 99; for (i = 0; i < num_3_tokens; ++i) { if (!strncmp(&buffer[pos1],&token_table3[i][0],3)) token = i; } if (!dotpos) bufptr += 3; return (token); } main() { char filenm[20],pr_ans; int tokn; printf("Input file name> "); scanf("%s",filenm); if(!(infd = fopen(filenm,"r"))) { printf("error opening %s as input\n",filenm); exit(0); } printf("Output file name> "); scanf("%s",filenm); outfd = fdopen(creat(filenm,0),"w"); printf("Do you want %s to step through? n/y:",filenm); scanf("%s",&pr_ans); if (pr_ans == 'y' || pr_ans == 'Y') print_mode=1; fprintf(outfd,"#include %csim1.h%c\n\nmain()\n{\n\n#include%clabels.h%c\nset_pmasks();\n\ncls();\n\n",34,34,34,34); while (!feof(infd)) { getbuff(); if (gtchar()) { bufptr--; if (print_mode) fprintf(outfd,"getstep(%c%s%c);\n",34,buffer,34); switch (tokn = get_token()) { case 0: {fprintf(outfd,"pop();"); break;} case 1: {getr1(); fprintf(outfd,"clr(mask_%s,%s);",field,r1); break;} case 2: {getr1(); fprintf(outfd,"inc(mask_%s,%s);",field,r1); break;} case 3: {getr1(); fprintf(outfd,"dec(mask_%s,%s);",field,r1); break;} case 4: {getr1r2(); fprintf(outfd,"add(mask_%s,%s,%s);",field,r1,r2); break;} case 5: {getr1r2(); fprintf(outfd,"sub(mask_%s,%s,%s);",field,r1,r2); break;} case 6: {getr1r2(); fprintf(outfd,"and(mask_%s,%s,%s);",field,r1,r2); break;} case 7: {getr1(); fprintf(outfd,"rln(mask_%s,%s);",field,r1); break;} case 8: {getr1(); fprintf(outfd,"rrn(mask_%s,%s);",field,r1); break;} case 9: {getr1(); fprintf(outfd,"srn(mask_%s,%s);",field,r1); break;} case 10: {getr1(); fprintf(outfd,"srb(mask_%s,%s);",field,r1); break;} case 11: {getr1(); fprintf(outfd,"sln(mask_%s,%s);",field,r1); break;} case 12: {getr1(); fprintf(outfd,"neg(mask_%s,%s);",field,r1); break;} case 13: {getr1(); fprintf(outfd,"not(mask_%s,%s);",field,r1); break;} case 14: break; case 15: {getr1(); getlbl(); fprintf(outfd,"if (!(%s[0] & mask_%s[0]) ||(!(%s[1] & mask_%s[1]))) {carry=1; goto %s;} else carry=0;\n",r1,field,r1,field,label); break;} case 16: {fprintf(outfd,"goto goreturn;"); break;} case 17: {getr1r2(); fprintf(outfd,"or(mask_%s,%s,%s);",field,r1,r2); break;} case 18: { getr1r2(); if (!strcmp(r2,"pc")) fprintf(outfd,"return_flag=0;tmp[1]=%s[1]&mask_a[1]; goto jump_mem;",r1); else { if (r1[0] == '@') fprintf(outfd,"input(%c%s%c,mask_%s,%s,%s);",34, field,34,field,&r1[1],r2); else if (r2[0] == '@') fprintf(outfd,"output(%c%s%c,mask_%s,%s,%s);",34,field,34,field,r1,&r2[1]); else fprintf(outfd,"move(mask_%s,%s,%s);",field,r1,r2); } break; } case 19: { getr1r2(); if (r1[0] == '@') { fprintf(outfd,"input(%c%s%c,mask_%s,%s,tmp);",34,field,34,field,&r1[1]); strcpy(r1,"tmp"); } if (r2[0] == '@') { fprintf(outfd,"input(%c%s%c,mask_%s,tmp,%s);",34,field,34,field,&r2[1]); strcpy(r2,"tmp"); } fprintf(outfd,"swap(mask_%s,%s,%s);",field,r1,r2); break; } case 20: {fprintf(outfd,"push();"); break;} case 21: {getr1r2();fprintf(outfd,"%s[1]=%s[1]&(~(1L<<(%s[1]&mask_1[1])));",r2,r2,r1); break;} case 22: {getr1r2();fprintf(outfd,"%s[1]=%s[1]|(1L<<(%s[1]&mask_1[1]));",r2,r2,r1); break;} case 23: {getlbl(); fprintf(outfd,"stack[stkptr--] = 0X%05X; goto%s; ret_%05X:",ret_count,label,ret_count); ret_count++; break;} case 24: {getlbl(); fprintf(outfd,"goto %s;",label); break;} case 25: {getr1r2(); getlbl(); branch("==",label); break;} case 26: {getr1r2(); getlbl(); branch("!=",label); break;} case 27: {getr1r2(); getlbl(); branch("> ",label); break;} case 28: {getr1r2(); getlbl(); branch("< ",label); break;} case 29: {getr1r2(); getlbl(); branch(">=",label); break;} case 30: {getr1r2(); getlbl(); branch("<=",label); break;} case 31: {getr1r2(); getlbl(); fprintf(outfd,"if((~%s[1])&(1L<<(%s[1]&mask_1[1]))) {carry=1; goto %s;} else carry=0;",r2,r1,label); break;} case 32: {getr1r2(); getlbl(); fprintf(outfd,"if(%s[1]&(1L<<(%s[1]&mask_1[1]))) {carry=1; goto %s;} else carry=0;",r2,r1,label); break;} case 33: {getlbl(); fprintf(outfd,"if (!carry) goto %s;",label);break;} case 34: {getlbl(); fprintf(outfd,"if (carry) goto %s;",label); break;} case 35: {getr1(); getlbl(); fprintf(outfd,"if((%s[0]&mask_%s[0])||(%s[1]&mask_%s[1])) {carry=1; goto %s;} else carry=0;",r1,field,r1,field,label); break;} case 36: {getr1(); fprintf(outfd,"if (!(%s[0] & mask_%s[0]) ||!(%s[1] & mask_%s[1]))) {carry=1; goto %s;} else carry=0;",r1,field,r1,field); break;} case 37: {getr1r2(); branch("==","goreturn"); break;} case 38: {getr1r2(); branch("!=","goreturn"); break;} case 39: {getr1r2(); branch("> ","goreturn"); break;} case 40: {getr1r2(); branch("< ","goreturn"); break;} case 41: {getr1r2(); branch(">=","goreturn"); break;} case 42: {getr1r2(); branch("<=","goreturn"); break;} case 43: {getr1r2(); fprintf(outfd,"if((~%s[1])&(1L<<(%s[1]&mask_1[1]))) {carry=1; goto goreturn;} else carry=0;",r2,r1); break;} case 44: {getr1r2(); fprintf(outfd,"if(%s[1]&(1L<<(%s[1]&mask_1[1]))) {carry=1; goto goreturn;} else carry=0;",r2,r1); break;} case 45: {fprintf(outfd,"if (!carry) goto goreturn;"); break;} case 46: {fprintf(outfd,"if (carry) goto goreturn;"); break;} case 47: {getr1(); fprintf(outfd,"if ((%s[0] &mask_%s[0])||(%s[1] & mask_%s[1])) {carry=1; goto goreturn;} else carry=0;",r1,field,r1,field); break;} case 48: {fprintf(outfd,"carry=1; goto goreturn;"); break;} case 49: {fprintf(outfd,"carry=0; goto goreturn;"); break;} case 50: {fprintf(outfd,"printf(%c\\n%c); show_regs();",34,34); break;}default: fprintf(outfd,"printf(%cUnknown operation:%s\\n%c);",34,buffer,34);}if (!print_mode) fprintf(outfd,"%c/* %s */\n",9,buffer);}} if (ret_count){fprintf(outfd,"\n\ngoreturn: switch(stack[++stkptr] & mask_a[1])\n{\n"); for (i = 0;i < ret_count; ++i) fprintf(outfd," case 0X%05X: goto ret_%05X;\n",i,i);fprintf(outfd," case 0xfffff: {printf(%cERROR: you'vepushed/popped return stack\\n%c); exit(0);}\n",34,34); fprintf(outfd," }\n\n"); } fprintf(outfd,"}\n"); fflush(outfd); fclose(outfd); fclose(infd); } getr1() { int j; char ch1; for (j = 0; j < 4; j++) r1[j] = 0; ch1=gtchar(); for (j = 0; ((ch1 != ',') && (j < 3)); j++) {r1[j] = ch1; ch1=gtchar();} } getr1r2() { int j,k; char ch1; for (j = 0; j < 19; j++) r1[j] = 0; for (j = 0; j < 4 ; j++) r2[j] = 0; ch1=gtchar(); for (j = 0; ch1 != ','; j++) {r1[j] = ch1; ch1=gtchar();} if (r1[0] < 58) /* constant (not register) */ { if ( (r1[0] == '$') || (r1[0] == '#') )fprintf(outfd,"constmp(mask_%s,0x%sL); ",field,&r1[1]); else fprintf(outfd,"constmp(mask_%s,%sL); ",field,r1); strcpy(r1,"tmp"); r1[3] = 0; } ch1=gtchar(); for (j = 0; ((ch1 > 0) && (ch1 != ',') && (j < 3)); j++) {r2[j] = ch1;ch1=gtchar();}} getlbl() { int lblptr; char ch1; if ((ch1 = gtchar()) == 64) { strcpy(label,"_at_"); lblptr = 4; } else { lblptr = 0; bufptr--; } strcpy(&label[lblptr],&buffer[bufptr]); } branch( char *condit, char *lbl) { if (!strcmp(condit,"==")) { fprintf(outfd,"if(((%s[0]&mask_%s[0])%s(%s[0]&mask_%s[0]))&&",r1,field,condit,r2,field); fprintf(outfd,"((%s[1]&mask_%s[1])%s(%s[1]&mask_%s[1])))",r1,field,condit,r2,field);} else if (!strcmp(condit,"!=")) { fprintf(outfd,"if(((%s[0]&mask_%s[0])%s(%s[0]&mask_%s[0]))||",r1,field,condit,r2,field); fprintf(outfd,"((%s[1]&mask_%s[1])%s(%s[1]&mask_%s[1])))",r1,field,condit,r2,field);} else if ((!strcmp(condit,">="))||(!strcmp(condit,"<="))) { /* ruddy heck!! what a test!! any better ideas???? */ fprintf(outfd,"if ((((mask_%s[0]) && ((%s[0]&mask_%s[0])%1s(%s[0]&mask_%s[0])))||",field,r1,field,condit,r2,field);fprintf(outfd,"((!mask_%s[0]) &&((%s[1]&mask_%s[1])%1s(%s[1]&mask_%s[1]))))",field,r1,field,condit,r2,field); fprintf(outfd,"||(((%s[0]&mask_%s[0])==(%s[0]&mask_%s[0]))&&",r1,field,r2,field); fprintf(outfd,"((%s[1]&mask_%s[1])==(%s[1]&mask_%s[1]))))",r1,field,r2,field); } else { fprintf(outfd,"if (((mask_%s[0]) && ((%s[0]&mask_%s[0])%s(%s[0]&mask_%s[0])))||",field,r1,field,condit,r2,field); fprintf(outfd,"((!mask_%s[0]) && ((%s[1]&mask_%s[1])%s(%s[1]&mask_%s[1]))))",field,r1,field,condit,r2,field); } fprintf(outfd,"{carry=1; goto %s;} else carry=0;",lbl); }