2.12.2021, 9:00 - 11:00: Due to updates GitLab may be unavailable for some minutes between 09:00 and 11:00.

Commit 1ae8d6ca authored by Martin Ruckert's avatar Martin Ruckert
Browse files

first version of mmixvd with assembler and trace

parent a806d7c6
...@@ -3,11 +3,8 @@ ...@@ -3,11 +3,8 @@
@<Stuff for \CEE/ preprocessor@>@; @<Stuff for \CEE/ preprocessor@>@;
@y @y
@<Stuff for \CEE/ preprocessor@>@; @<Stuff for \CEE/ preprocessor@>@;
#include "libconfig.h"
#include "libimport.h"
#pragma warning(disable : 4146 4018 4244 4267) #pragma warning(disable : 4146 4018 4244 4267)
#ifdef MMIX_PRINT
extern int mmix_printf(char *format,...);
#define printf(...) mmix_printf(__VA_ARGS__)
#endif
@z @z
...@@ -2,37 +2,45 @@ ...@@ -2,37 +2,45 @@
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include <setjmp.h> #include <setjmp.h>
#include "libconfig.h"
#include <time.h> #include <time.h>
#include "libconfig.h"
#include "libtype.h" #include "libtype.h"
#include "libglobals.h" #include "libglobals.h"
#include <setjmp.h> #include <setjmp.h>
#include "libname.h" #include "libname.h"
extern jmp_buf mmix_exit; extern jmp_buf mmix_exit;
/* simple implementation of the identity mapping */ /* simple implementation of the identity mapping */
#define NUM_FILES 0x100
static char *filenames[NUM_FILES]={NULL};
static char file_no_bound= 0;
int filename2file(char *filename, int c) int filename2file(char *filename)
{ if (file_info[c].name==NULL)/* the usual case */ { int file_no;
{ file_info[c].name = filename; file_no=0;
return c; while(file_no<file_no_bound)
{ if (filenames[file_no]!=NULL && strcmp(filenames[file_no],filename)==0)
return file_no;
file_no++;
}
if (file_no>=NUM_FILES)
{ MMIX_ERROR("Too many open files (%s)!\n",filename);
return -1;
} }
else if (strcmp(file_info[c].name,filename)==0) /* the other usual case */ filenames[file_no]=malloc(strlen(filename)+1);
{ free(filename); if (filenames[file_no]==NULL)
return c; { MMIX_ERROR("Out of memory for filename (%s)!\n",filename);
return -1;
} }
MMIX_ERROR("ybyte does not match filename %s!\n",filename); strcpy(filenames[file_no],filename);
free(filename); if (file_no>=file_no_bound) file_no_bound= file_no+1;
longjmp(mmix_exit,-6); return file_no;
return 0;
} }
/* convert a ybyte to a valid index into file_info, char *file2filename(int file_no)
return -1; if there is no valid file_info entry for this ybyte */ {
int ybyte2file(int c) if (file_no<0 || file_no>=NUM_FILES)
{ if (file_info[c].name) return NULL;
return c; else
else return filenames[file_no];
return -1; }
} \ No newline at end of file
extern int filename2file(char *filename, int c); extern int filename2file(char *filename);
extern int ybyte2file(int c); extern char *file2filename(int file_no);
...@@ -25,7 +25,6 @@ jmp_buf mmixal_exit; ...@@ -25,7 +25,6 @@ jmp_buf mmixal_exit;
#ifdef WIN32 #ifdef WIN32
#pragma warning(disable : 4996) #pragma warning(disable : 4996)
#endif #endif
#define _MMIXAL_
@z @z
We change error messages that handle errors in the command line We change error messages that handle errors in the command line
...@@ -43,9 +42,44 @@ The filenames in mmixal are considered local. ...@@ -43,9 +42,44 @@ The filenames in mmixal are considered local.
@x @x
Char *filename[257]; Char *filename[257];
@y @y
static Char *filename[257];
@z @z
@x
if (!filename[filename_count]) {
filename[filename_count]=(Char*)calloc(FILENAME_MAX+1,sizeof(Char));
if (!filename[filename_count])
panic("Capacity exceeded: Out of filename memory");
@.Capacity exceeded...@>
}
for (p++,k=0;*p && *p!='\"' && k<FILENAME_MAX; p++,k++)
filename[filename_count][k]=*p;
@y
Char filename[FILENAME_MAX+1];
for (p++,k=0;*p && *p!='\"' && k<FILENAME_MAX; p++,k++)
filename[k]=*p;
@z
@x
filename[filename_count][k]='\0';
for (k=0;strcmp(filename[k],filename[filename_count])!=0;k++);
if (k==filename_count) {
if (filename_count==256)
panic("Capacity exceeded: More than 256 file names");
filename_count++;
}
cur_file=k;
@y
filename[k]='\0';
cur_file= filename2file(filename);
if (cur_file<0) panic("Capacity exceeded: More than 256 file names");
@z
The error reporting goes into a separate file, because we might want The error reporting goes into a separate file, because we might want
to change it. to change it.
...@@ -59,14 +93,14 @@ to change it. ...@@ -59,14 +93,14 @@ to change it.
@d dpanic(m,p) {@+err_buf[0]='!';@+sprintf(err_buf+1,m,p);@+ @d dpanic(m,p) {@+err_buf[0]='!';@+sprintf(err_buf+1,m,p);@+
report_error(err_buf);@+} report_error(err_buf);@+}
@y @y
@d err(m) {@+report_error(m,filename[cur_file],line_no);@+if (m[0]!='*') goto bypass;@+} @d err(m) {@+report_error(m,cur_file,line_no);@+if (m[0]!='*') goto bypass;@+}
@d derr(m,p) {@+sprintf(err_buf,m,p); @d derr(m,p) {@+sprintf(err_buf,m,p);
report_error(err_buf,filename[cur_file],line_no);@+if (err_buf[0]!='*') goto bypass;@+} report_error(err_buf,cur_file,line_no);@+if (err_buf[0]!='*') goto bypass;@+}
@d dderr(m,p,q) {@+sprintf(err_buf,m,p,q); @d dderr(m,p,q) {@+sprintf(err_buf,m,p,q);
report_error(err_buf,filename[cur_file],line_no);@+if (err_buf[0]!='*') goto bypass;@+} report_error(err_buf,cur_file,line_no);@+if (err_buf[0]!='*') goto bypass;@+}
@d panic(m) {@+sprintf(err_buf,"!%s",m);@+report_error(err_buf,filename[cur_file],line_no);@+} @d panic(m) {@+sprintf(err_buf,"!%s",m);@+report_error(err_buf,cur_file,line_no);@+}
@d dpanic(m,p) {@+err_buf[0]='!';@+sprintf(err_buf+1,m,p);@+ @d dpanic(m,p) {@+err_buf[0]='!';@+sprintf(err_buf+1,m,p);@+
report_error(err_buf,filename[cur_file],line_no);@+} report_error(err_buf,cur_file,line_no);@+}
@z @z
...@@ -104,6 +138,7 @@ void report_error(message) ...@@ -104,6 +138,7 @@ void report_error(message)
#include <stdlib.h> #include <stdlib.h>
#include <stdio.h> #include <stdio.h>
#include <setjmp.h> #include <setjmp.h>
#define _MMIXAL_
int err_count; int err_count;
extern FILE *listing_file; extern FILE *listing_file;
...@@ -112,8 +147,9 @@ typedef enum{false,true}bool; ...@@ -112,8 +147,9 @@ typedef enum{false,true}bool;
extern bool line_listed; extern bool line_listed;
extern jmp_buf mmixal_exit; extern jmp_buf mmixal_exit;
void report_error(char *message,char *filename,int line_no) void report_error(char *message,int file_no,int line_no)
{ { char *filename;
filename=file2name(file_no);
if (!filename) filename="(nofile)"; if (!filename) filename="(nofile)";
if (message[0]=='*') if (message[0]=='*')
fprintf(stderr,"\"%s\", line %d warning: %s\n", fprintf(stderr,"\"%s\", line %d warning: %s\n",
...@@ -139,6 +175,46 @@ void report_error(char *message,char *filename,int line_no) ...@@ -139,6 +175,46 @@ void report_error(char *message,char *filename,int line_no)
} }
@z @z
in mmo sync we map global file numbers
to local filenumbers that go into the mmo file.
First files that have already been passed. The
local file number is in filename_passed.
@x
if (filename_passed[cur_file]) mmo_lop(lop_file,cur_file,0);
@y
if (filename_passed[cur_file]>=0) mmo_lop(lop_file,filename_passed[cur_file],0);
@z
@x
mmo_lop(lop_file,cur_file,(strlen(filename[cur_file])+3)>>2);
for (j=0,p=filename[cur_file];*p;p++,j=(j+1)&3) {
mmo_buf[j]=*p;
if (j==3) mmo_out();
}
if (j) {
for (;j<4;j++) mmo_buf[j]=0;
mmo_out();
}
filename_passed[cur_file]=1;
@y
Char *filename;
if (filename_count>=256)
panic("Capacity exceeded: More than 256 file names");
filename_passed[cur_file]=filename_count;
filename_count++;
filename=file2filename(cur_file);
if (filename==NULL) panic("Unknown file name");
mmo_lop(lop_file,filename_passed[cur_file],(strlen(filename)+3)>>2);
for (j=0,p=filename;*p;p++,j=(j+1)&3) {
mmo_buf[j]=*p;
if (j==3) mmo_out();
}
if (j) {
for (;j<4;j++) mmo_buf[j]=0;
mmo_out();
}
@z
In the assemble subroutine, we have the In the assemble subroutine, we have the
opportunity to gain some information about opportunity to gain some information about
the association of lines and locations. the association of lines and locations.
...@@ -213,7 +289,7 @@ normal error reporting function. ...@@ -213,7 +289,7 @@ normal error reporting function.
err_count++; err_count++;
@y @y
sprintf(err_buf,"undefined symbol: %s",sym_buf+1); sprintf(err_buf,"undefined symbol: %s",sym_buf+1);
report_error(err_buf,filename[cur_file],line_no); report_error(err_buf,cur_file,line_no);
@z @z
when a sym_node becomes DEFINED, we record file and line. when a sym_node becomes DEFINED, we record file and line.
...@@ -222,7 +298,7 @@ when a sym_node becomes DEFINED, we record file and line. ...@@ -222,7 +298,7 @@ when a sym_node becomes DEFINED, we record file and line.
@<Find the symbol table node, |pp|@>; @<Find the symbol table node, |pp|@>;
@y @y
@<Find the symbol table node, |pp|@>; @<Find the symbol table node, |pp|@>;
pp->file_no=MMIX_FILE_NO(cur_file); pp->file_no=cur_file;
pp->line_no=line_no; pp->line_no=line_no;
@z @z
...@@ -279,6 +355,9 @@ int main(argc,argv) ...@@ -279,6 +355,9 @@ int main(argc,argv)
#include <stdlib.h> #include <stdlib.h>
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#define _MMIXAL_
#include "libconfig.h"
#include "mmixlib.h"
@# @#
extern int expanding; extern int expanding;
...@@ -287,7 +366,7 @@ extern char*src_file_name; ...@@ -287,7 +366,7 @@ extern char*src_file_name;
extern char obj_file_name[FILENAME_MAX+1]; extern char obj_file_name[FILENAME_MAX+1];
extern char listing_name[FILENAME_MAX+1]; extern char listing_name[FILENAME_MAX+1];
extern void report_error(char * message, char *filename, int line_no); extern void report_error(char * message, int file_no, int line_no);
extern int mmixal(char *mms_name, char *mmo_name, char *mml_name, int x_option, int b_option); extern int mmixal(char *mms_name, char *mmo_name, char *mml_name, int x_option, int b_option);
@# @#
int main(argc,argv) int main(argc,argv)
...@@ -307,17 +386,21 @@ int main(argc,argv) ...@@ -307,17 +386,21 @@ int main(argc,argv)
#include <string.h> #include <string.h>
#include <time.h> #include <time.h>
#include <setjmp.h> #include <setjmp.h>
#define _MMIXAL_
#include "libconfig.h" #include "libconfig.h"
#include "libimport.h" #include "libimport.h"
@# @#
@h @h
@<Preprocessor definitions@>@; @<Preprocessor definitions@>@;
@<Type definitions@>@; @<Type definitions@>@;
@<Global variables@>@; @<Global variables@>@;
extern void report_error(char * message, char *filename, int line_no); extern void report_error(char * message, int file_no, int line_no);
extern jmp_buf mmixal_exit; extern jmp_buf mmixal_exit;
extern char *file2filename(int file_no);
extern int filename2file(char *filename);
@<Subroutines@>@; @<Subroutines@>@;
@# @#
...@@ -354,6 +437,7 @@ int mmixal(char *mms_name, char *mmo_name, char *mml_name, int x_option, int b_o ...@@ -354,6 +437,7 @@ int mmixal(char *mms_name, char *mmo_name, char *mml_name, int x_option, int b_o
mmo_ptr=0; mmo_ptr=0;
err_count=0; err_count=0;
serial_number=0; serial_number=0;
for (j=0;j<256;j++) filename_passed[j]=-1;
filename_count=0; filename_count=0;
for (j=0;j<10;j++) for (j=0;j<10;j++)
{ forward_local[j].link=0; { forward_local[j].link=0;
...@@ -377,6 +461,15 @@ int mmixal(char *mms_name, char *mmo_name, char *mml_name, int x_option, int b_o ...@@ -377,6 +461,15 @@ int mmixal(char *mms_name, char *mmo_name, char *mml_name, int x_option, int b_o
} }
@z @z
@x
filename[0]=src_file_name;
filename_count=1;
@y
cur_file=filename2file(src_file_name);
filename_count=0;
@z
We end with return or longjmp instead of exit. We end with return or longjmp instead of exit.
@x @x
...@@ -389,7 +482,7 @@ exit(err_count); ...@@ -389,7 +482,7 @@ exit(err_count);
if (err_count>0){ if (err_count>0){
if (err_count>1) sprintf(err_buf,"(%d errors were found.)",err_count); if (err_count>1) sprintf(err_buf,"(%d errors were found.)",err_count);
else sprintf(err_buf,"(One error was found.)"); else sprintf(err_buf,"(One error was found.)");
report_error(err_buf,filename[cur_file],line_no); report_error(err_buf,cur_file,line_no);
} }
clean_up: clean_up:
if (listing_file!=NULL) if (listing_file!=NULL)
...@@ -419,13 +512,7 @@ clean_up: ...@@ -419,13 +512,7 @@ clean_up:
free(err_buf);err_buf=NULL; free(err_buf);err_buf=NULL;
free(op_stack); op_stack=NULL; free(op_stack); op_stack=NULL;
free(val_stack);val_stack=NULL; free(val_stack);val_stack=NULL;
filename[0]=NULL;
filename_passed[0]=0;
for (j=1;j<filename_count;j++)
{ free(filename[j]);
filename[j]=NULL;
filename_passed[j]=0;
}
filename_count=0; filename_count=0;
return err_count; return err_count;
...@@ -439,6 +526,6 @@ usual error reporting. ...@@ -439,6 +526,6 @@ usual error reporting.
err_count++,fprintf(stderr,"undefined local symbol %dF\n",j); err_count++,fprintf(stderr,"undefined local symbol %dF\n",j);
@y @y
{ sprintf(err_buf,"undefined local symbol %dF",j); { sprintf(err_buf,"undefined local symbol %dF",j);
report_error(err_buf,filename[cur_file],line_no); report_error(err_buf,cur_file,line_no);
} }
@z @z
...@@ -293,9 +293,9 @@ case lop_file:@+if (file_info[ybyte].name) { ...@@ -293,9 +293,9 @@ case lop_file:@+if (file_info[ybyte].name) {
cur_file=ybyte; cur_file=ybyte;
@y @y
case lop_file: case lop_file:
if (ybyte2file(ybyte)>=0) { if (ybyte2file[ybyte]>=0) {
if (zbyte) mmo_err; if (zbyte) mmo_err;
cur_file=ybyte2file(ybyte); cur_file=ybyte2file[ybyte];
@z @z
Now we handle new files. Now we handle new files.
...@@ -316,17 +316,14 @@ Now we handle new files. ...@@ -316,17 +316,14 @@ Now we handle new files.
} }
@y @y
}@+else { }@+else {
char *name;
if (!zbyte) mmo_err; if (!zbyte) mmo_err;
name=(char*)calloc(4*zbyte+1,1); if (4*zbyte+1>FILENAME_MAX) mmo_err;
if (!name) { for (j=zbyte,p=filename; j>0; j--,p+=4) {
MMIX_ERROR("%s","No room to store the file name!\n");@+longjmp(mmix_exit,-5);
}
for (j=zbyte,p=name; j>0; j--,p+=4) {
read_tet(); read_tet();
*p=buf[0];@+*(p+1)=buf[1];@+*(p+2)=buf[2];@+*(p+3)=buf[3]; *p=buf[0];@+*(p+1)=buf[1];@+*(p+2)=buf[2];@+*(p+3)=buf[3];
} }
cur_file=filename2file(name,ybyte); cur_file=filename2file(filename);
ybyte2file[ybyte]=cur_file;
} }
@z @z
...@@ -1289,7 +1286,7 @@ case SWYM: ...@@ -1289,7 +1286,7 @@ case SWYM:
n=mmgetchars((unsigned char *)buf,256,b,0); n=mmgetchars((unsigned char *)buf,256,b,0);
buf[n]=0; buf[n]=0;
if (n>6 && strncmp(buf,"DEBUG ",6)==0) if (n>6 && strncmp(buf,"DEBUG ",6)==0)
{ fprintf(stdout,"\n%s!\n",buf+6); { printf("\n%s!\n",buf+6);
sprintf(rhs,"rF=#%08X%08X\n",g[rF].h, g[rF].l); sprintf(rhs,"rF=#%08X%08X\n",g[rF].h, g[rF].l);
tracing= true; tracing= true;
} }
...@@ -2077,7 +2074,11 @@ int mmix_load_file(char *mmo_file_name) ...@@ -2077,7 +2074,11 @@ int mmix_load_file(char *mmo_file_name)
{ int j; /* miscellaneous indices */ { int j; /* miscellaneous indices */
mem_tetra *ll; /* current place in the simulated memory */ mem_tetra *ll; /* current place in the simulated memory */
char *p; /* current place in a string */ char *p; /* current place in a string */
static char filename[FILENAME_MAX];
static int ybyte2file[256];
free_file_info(); free_file_info();
for (j=0;j<256;j++) ybyte2file[j]=-1;
postamble=0;
if (mmo_file_name!=NULL && mmo_file_name[0]!=0) if (mmo_file_name!=NULL && mmo_file_name[0]!=0)
{ {
@<Load object file@>; @<Load object file@>;
......
...@@ -179,7 +179,7 @@ extern void mmix_profile(void); ...@@ -179,7 +179,7 @@ extern void mmix_profile(void);
extern void show_stats(bool verbose); extern void show_stats(bool verbose);
/* show statistics */ /* show statistics */
extern int mmix_printf(char *format,...); extern int mmix_printf(FILE *f, char *format,...);
/* printf replacement */ /* printf replacement */
extern int mmix_fputc(int c, FILE *f); extern int mmix_fputc(int c, FILE *f);
/* fputc replacement */ /* fputc replacement */
...@@ -242,7 +242,7 @@ extern int mmixal(char *mms_name, char *mmo_name, char *mml_name, int x_option, ...@@ -242,7 +242,7 @@ extern int mmixal(char *mms_name, char *mmo_name, char *mml_name, int x_option,
otherwise the number of errors found in the input otherwise the number of errors found in the input
*/ */
extern void report_error(char *message, char *filename, int line_no); extern void report_error(char *message, int file_no, int line_no);
/* report an error in the given file and line. /* report an error in the given file and line.
*/ */
...@@ -261,4 +261,7 @@ extern int buf_size; /* maximum number of characters per line of input */ ...@@ -261,4 +261,7 @@ extern int buf_size; /* maximum number of characters per line of input */
extern int mmixal(char *mms_name, char *mmo_name, char *mml_name, int x_option, int b_option); extern int mmixal(char *mms_name, char *mmo_name, char *mml_name, int x_option, int b_option);
extern int err_count; /* the error count */ extern int err_count; /* the error count */
extern void flush_listing_line(char*line); extern void flush_listing_line(char*line);
extern char *file2filename(int file_no);
extern int filename2file(char *filename);
#endif #endif
\ No newline at end of file
...@@ -688,6 +688,10 @@ ...@@ -688,6 +688,10 @@
RelativePath=".\libimport.h" RelativePath=".\libimport.h"
> >
</File> </File>
<File
RelativePath=".\libname.h"
>
</File>
<File <File
RelativePath=".\libtype.h" RelativePath=".\libtype.h"
> >
...@@ -720,6 +724,7 @@ ...@@ -720,6 +724,7 @@
Name="VCCustomBuildTool" Name="VCCustomBuildTool"
Description="ctangle mmix-arith with arith-win changefile" Description="ctangle mmix-arith with arith-win changefile"
CommandLine="ctangle mmixware\mmix-arith.w arith-win.ch&#x0D;&#x0A;" CommandLine="ctangle mmixware\mmix-arith.w arith-win.ch&#x0D;&#x0A;"
AdditionalDependencies="mmix-arith.ch"
Outputs="mmix-arith.c" Outputs="mmix-arith.c"
/> />
</FileConfiguration> </FileConfiguration>
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment