Commit c7dc5eb3 authored by Martin Ruckert's avatar Martin Ruckert
Browse files

getting mmixal to compile and run

parent 69af242f
......@@ -2,13 +2,15 @@ LIBSIM= libboot.c libfinal.c libload.c libprint.c libstats.c \
libcommand.c libinit.c libmem.c libprofile.c libtrace.c \
libdtrap.c libinteract.c libmmget.c libshowbreaks.c libglobals.c \
libdump.c liblibfinal.c libmmput.c libshowline.c libstdin.c \
libfetch.c liblibinit.c libperform.c libsoption.c
libfetch.c liblibinit.c libperform.c libsoption.c
LIBH= libarith.h libtype.h mmix-io.h
LIBAL= libmmixal.c libalerror.c
LIBH= libarith.h libtype.h mmix-io.h
LIBSRC= libname.c libbase.c
LIBOBJ= $(LIBSIM:.c=.o) $(LIBSRC:.c=.o) mmix-arith.o mmix-io.o libmmixal.o
LIBOBJ= $(LIBSIM:.c=.o) $(LIBAL:.c=.o) $(LIBSRC:.c=.o) mmix-arith.o mmix-io.o
CC= gcc
......@@ -21,7 +23,7 @@ all: libmmix.a mmix-sim.c mmixal.c
libbase.o: libbase.c libbase.h libconfig.h
%.o : %.c abstime.h mmixlib.h
%.o : %.c abstime.h mmixlib.h $(LIBH)
boilerplate.w: mmix/boilerplate.w
cp $< $@
......@@ -39,7 +41,7 @@ mmix-arith.c: boilerplate.w mmix/mmix-arith.w
mmix-io.c: boilerplate.w mmix/mmix-io.w
ctangle mmix/mmix-io.w
libmmixal.c mmixal.c: boilerplate.w mmix/mmixal.w mmixallib.ch
$(LIBAL): boilerplate.w mmix/mmixal.w mmixallib.ch
ctangle mmix/mmixal.w mmixallib.ch
......@@ -47,7 +49,7 @@ $(LIBSIM) $(LIBH) mmix-sim.c: boilerplate.w mmix/mmix-sim.w mmixlib.ch libconfig
ctangle mmix/mmix-sim.w mmixlib.ch
libmmix.a: $(LIBSIM) $(LIBOBJ)
libmmix.a: $(LIBOBJ)
rm -f $@
$(AR) $(ARFLAGS) $@ $(LIBOBJ)
$(RANLIB) $@
......@@ -55,9 +57,12 @@ libmmix.a: $(LIBSIM) $(LIBOBJ)
mmix-sim: libmmix.a mmix-sim.c
$(CC) $(CFLAGS) mmix-sim.c -L. -lmmix -o mmix-sim
mmixal: libmmix.a mmixal.c
$(CC) $(CFLAGS) mmixal.c -L. -lmmix -o mmixal
clean:
rm -f *.o
rm -f $(LIBSIM) $(LIBH) mmix-arith.c libmmixal.c mmix-io.c
rm -f $(LIBSIM) $(LIBH) $(LIBAL) mmix-arith.c mmix-io.c
rm -f *~ *.tmp
rm -f libmmix.a mmix-sim
rm -f mmix-sim.c mmixal.c
#include <stdlib.h>
#include <stdio.h>
#include "libconfig.h"
#include "libtype.h"
#include "libglobals.h"
#include "libbase.h"
......
......@@ -24,17 +24,14 @@
#define store_data_translation(virt,phys)
#ifdef WIN32
#define MMIX_DELAY(ms,d) Sleep(ms); d=ms
#define MMIX_DELAY(ms,d) (Sleep(ms), d=(ms))
#else
#define MMIX_DELAY(ms,d) usleep(1000*ms); d=ms
#define MMIX_DELAY(ms,d) (usleep(1000*(ms)), d=(ms))
#endif
/* define this to check for external asynchronous ineterrupts*/
#define MMIX_GET_INTERRUPT
/*convert filenames to file numbers */
#define filename2file(filename, c) (c)
/* this code is executed after processing the commandline */
#define MMIX_AFTER_COMMANDLINE
......@@ -74,16 +71,15 @@ extern int mmix_fputc(int c, FILE *f);
#define MMIX_END halted
#define MMIX_EXIT(i) exit(i)
/* this is the error exit function */
#define panic(m) (fprintf(stderr,"Panic: %s!\n",m), MMIX_EXIT(-1))
/* this is the error display function */
#define MMIX_ERROR(f,m) fprintf(stderr,f,m)
#define MMIX_OPTION_STRING
/* define this if you need the tetra inside the mem_node */
#define MMIX_MEM_TET tetra tet; /* the tetrabyte of simulated memory */
/* these are the functions for the instructions not implemented in the basic mmix simulator */
#define write_all_data_cache()
#define clear_all_instruction_cache()
#define clear_all_data_cache()
......@@ -96,10 +92,13 @@ extern int mmix_fputc(int c, FILE *f);
#define delete_data_cache(w,xx)
#define delete_instruction_cache(w,xx)
#include <time.h>
#include "libtype.h"
#include "libglobals.h"
#include "mmixlib.h"
#define MMXIAL_LINE_TRUNCATED fprintf(stderr,"(say `-b <number>' to increase the length of my input buffer)\n");
/* MMIXAL has its own notion of file numbers as embedded in the mmo file
we might want to convert this to a global file number */
#define MMIX_FILE_NO(file_no) (file_no)
/* define this to record file line and location associations while assembling */
#define MMIXAL_LINE_LOC(file_no,line_no,cur_loc)
#endif
\ No newline at end of file
/* simple implementation of the identity mapping */
//extern int ybyte2file_no[256];
extern int filename2file(char *filename, char c);
extern int ybyte2file(char ybyte);
......@@ -5,22 +5,22 @@ about deprecated functions, like strcpy or sprintf, and
include mmixlib.h at the start of the sybroutines
to declare the extern library interface.
We prepare for the elimination
of the exit() function, which must be replaced by a return from
the subroutine.
@x
@<Preprocessor definitions@>=
@y
@<Sub...@>=
#include "mmixlib.h"
#include "libname.h"
@ @<Global...@>=
static jmp_buf error_exit;
#include <setjmp.h>
jmp_buf mmixal_exit;
@ @<Preprocessor definitions@>=
#include <setjmp.h>
#ifdef MMIX_PRINT
extern int mmix_printf(char *format,...);
#define printf(...) mmix_printf(__VA_ARGS__)
#endif
#ifdef WIN32
#pragma warning(disable : 4996)
#endif
......@@ -34,33 +34,48 @@ We change error messages that handle errors in the command line
fprintf(stderr,
"(say `-b <number>' to increase the length of my input buffer)\n");
@y
err("*use the Options dialog to increase the length of my input buffer");
MMXIAL_LINE_TRUNCATED
@z
Besides filenames, we need to keep track
of external file numbers.
The filenames in mmixal are considered local.
@x
Char *filename[257];
@y
Char *filename[257];
static int file_no[257];
static Char *filename[257];
@z
Whenever we enter a new filename, we look up
the external file number for it.
The error reporting goes into a separate file, because we might want
to change it.
@x
filename_count++;
@d err(m) {@+report_error(m);@+if (m[0]!='*') goto bypass;@+}
@d derr(m,p) {@+sprintf(err_buf,m,p);
report_error(err_buf);@+if (err_buf[0]!='*') goto bypass;@+}
@d dderr(m,p,q) {@+sprintf(err_buf,m,p,q);
report_error(err_buf);@+if (err_buf[0]!='*') goto bypass;@+}
@d panic(m) {@+sprintf(err_buf,"!%s",m);@+report_error(err_buf);@+}
@d dpanic(m,p) {@+err_buf[0]='!';@+sprintf(err_buf+1,m,p);@+
report_error(err_buf);@+}
@y
file_no[filename_count]=filename2file(filename[filename_count],filename_count);
filename_count++;
@d err(m) {@+report_error(m,filename[cur_file],line_no);@+if (m[0]!='*') goto bypass;@+}
@d derr(m,p) {@+sprintf(err_buf,m,p);
report_error(err_buf,filename[cur_file],line_no);@+if (err_buf[0]!='*') goto bypass;@+}
@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;@+}
@d panic(m) {@+sprintf(err_buf,"!%s",m);@+report_error(err_buf,filename[cur_file],line_no);@+}
@d dpanic(m,p) {@+err_buf[0]='!';@+sprintf(err_buf+1,m,p);@+
report_error(err_buf,filename[cur_file],line_no);@+}
@z
Next we change the way errors are reported:
@x
@<Sub...@>=
void report_error @,@,@[ARGS((char*))@];@+@t}\6{@>
void report_error(message)
char *message;
{
if (!filename[cur_file]) filename[cur_file]="(nofile)";
if (message[0]=='*')
fprintf(stderr,"\"%s\", line %d warning: %s\n",
filename[cur_file],line_no,message+1);
......@@ -72,35 +87,55 @@ Next we change the way errors are reported:
filename[cur_file],line_no,message);
err_count++;
}
@y
if (message[0]=='*'){
mmixal_error(message+1,file_no[cur_file],line_no,1);
err_count+=0x1;
}
else if (message[0]=='!') {
mmixal_error(message+1,file_no[cur_file],line_no,-1);
err_count=-2;
}
else {
mmixal_error(message,file_no[cur_file],line_no,0);
err_count+=0x10000;
if (listing_file) {
if (!line_listed) flush_listing_line("****************** ");
if (message[0]=='*') fprintf(listing_file,
"************ warning: %s\n",message+1);
else if (message[0]=='!') fprintf(listing_file,
"******** fatal error: %s!\n",message+1);
else fprintf(listing_file,
"********** error: %s!\n",message);
}
@z
The error exit is redirected using a longjmp.
@x
if (message[0]=='!') exit(-2);
}
@y
if (message[0]=='!')
longjmp(error_exit,-2);
@z
@(libalerror.c@>=
#include <stdlib.h>
#include <stdio.h>
#include <setjmp.h>
@x
int err_count; /* this many errors were found */
@y
int err_count; /* negativ for fatal erros else (erros<<16)+warnings */
extern int err_count;
extern FILE *listing_file;
extern void flush_listing_line(char*line);
typedef enum{false,true}bool;
extern bool line_listed;
extern jmp_buf mmixal_exit;
void report_error(char *message,char *filename,int line_no)
{
if (!filename) filename="(nofile)";
if (message[0]=='*')
fprintf(stderr,"\"%s\", line %d warning: %s\n",
filename,line_no,message+1);
else if (message[0]=='!')
fprintf(stderr,"\"%s\", line %d fatal error: %s\n",
filename,line_no,message+1);
else {
fprintf(stderr,"\"%s\", line %d: %s!\n",
filename,line_no,message);
err_count++;
}
if (listing_file) {
if (!line_listed) flush_listing_line("****************** ");
if (message[0]=='*') fprintf(listing_file,
"************ warning: %s\n",message+1);
else if (message[0]=='!') fprintf(listing_file,
"******** fatal error: %s!\n",message+1);
else fprintf(listing_file,
"********** error: %s!\n",message);
}
if (message[0]=='!') longjmp(mmixal_exit,-2);
}
@z
In the assemble subroutine, we have the
......@@ -110,7 +145,7 @@ the association of lines and locations.
@x
for (j=0;j<k;j++) {
@y
add_line_loc(file_no[cur_file], line_no, cur_loc);
MMIXAL_LINE_LOC(cur_file, line_no, cur_loc);
for (j=0;j<k;j++) {
@z
......@@ -166,11 +201,10 @@ Char *special_name[32]={"rB","rD","rE","rH","rJ","rM","rR","rBB",
"rA","rF","rP","rW","rX","rY","rZ","rWW","rXX","rYY","rZZ"};
@y
extern Char *special_name[32];
@z
Errors generated at the end of the assembly should use the
normal error reporting macros.
normal error reporting function.
@x
fprintf(stderr,"undefined symbol: %s\n",sym_buf+1);
......@@ -178,9 +212,7 @@ normal error reporting macros.
err_count++;
@y
sprintf(err_buf,"undefined symbol: %s",sym_buf+1);
report_error(err_buf);
@.undefined symbol@>
err_count+=0x10000;
report_error(err_buf,filename[cur_file],line_no);
@z
when a sym_node becomes DEFINED, we record file and line.
......@@ -189,7 +221,7 @@ when a sym_node becomes DEFINED, we record file and line.
@<Find the symbol table node, |pp|@>;
@y
@<Find the symbol table node, |pp|@>;
pp->file_no=file_no[cur_file];
pp->file_no=MMIX_FILE_NO(cur_file);
pp->line_no=line_no;
@z
......@@ -248,18 +280,28 @@ int main(argc,argv)
#include <ctype.h>
#include <string.h>
#include <time.h>
#include "libconfig.h"
@#
@<Preprocessor definitions@>@;
@<Type definitions@>@;
extern int expanding;
extern int buf_size;
extern char*src_file_name;
extern char obj_file_name[FILENAME_MAX+1];
extern char listing_name[FILENAME_MAX+1];
extern void report_error(char * message, char *filename, int line_no);
extern int mmixal(char *mms_name, char *mmo_name, char *mml_name, int x_option, int b_option);
@#
int main(argc,argv)
int argc;@+
char *argv[];
{
register int j,k; /* all-purpose integers */
@<Local variables@>;
register int j; /* all-purpose integers */
@<Process the command line@>;
return mmixal(mms_name, mmo_name, mml_name, x_option, b_option);
return mmixal(src_file_name, obj_file_name, listing_name, expanding, buf_size);
}
@ @(libmmixal.c@>=
......@@ -267,20 +309,25 @@ int main(argc,argv)
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#include <time.h>
#include <time.h>
#include "libconfig.h"
@#
@h
@<Preprocessor definitions@>@;
@<Type definitions@>@;
@<Global variables@>@;
extern void report_error(char * message, char *filename, int line_no);
@<Subroutines@>@;
@#
int mmixal(char *mms_name, char *mmo_name, char *mml_name, int x_option, int b_option)
{
register int j,k; /* all-purpose integers */
@<Local variables@>;
/* instead of processing the commandline */
err_count=setjmp(error_exit);
err_count=setjmp(mmixal_exit);
if (err_count!=0){
prune(trie_root);
goto clean_up;
......@@ -331,17 +378,6 @@ int mmixal(char *mms_name, char *mmo_name, char *mml_name, int x_option, int b_o
}
@z
We assign the source file to filename[0]
and set also file_no[0]
@x
filename[0]=src_file_name;
filename_count=1;
@y
filename[0]=src_file_name;
file_no[0]=filename2file(src_file_name,0);
filename_count=1;
@z
We end with return instead of exit.
@x
......@@ -352,8 +388,9 @@ if (err_count) {
exit(err_count);
@y
if (err_count>0){
sprintf(err_buf,"%d errors and %d warnings were found.",err_count>>16, err_count&0xFFFF);
report_error(err_buf);
if (err_count>1) sprintf(err_buf,"(%d errors were found.)",err_count);
else sprintf(err_buf,"(One error was found.)");
report_error(err_buf,filename[cur_file],line_no);
}
clean_up:
if (listing_file!=NULL)
......@@ -388,7 +425,7 @@ clean_up:
for (j=1;j<filename_count;j++)
{ free(filename[j]);
filename[j]=NULL;
filename_passed[j]=0;
filename_passed[j]=0;
}
filename_count=0;
......@@ -401,8 +438,7 @@ usual error reporting.
@x
err_count++,fprintf(stderr,"undefined local symbol %dF\n",j);
@y
{ err_count+=0x10000;
sprintf(err_buf,"undefined local symbol %dF\n",j);
report_error(err_buf);
{ sprintf(err_buf,"undefined local symbol %dF",j);
report_error(err_buf,filename[cur_file],line_no);
}
@z
......@@ -19,6 +19,11 @@ void print_hex @,@,@[ARGS((octa))@];@+@t}\6{@>
@ @(libprint.c@>=
#include <stdio.h>
#include "libconfig.h"
#include <time.h>
#include "libtype.h"
#include "libglobals.h"
#include "mmixlib.h"
#include "libarith.h"
void print_hex @,@,@[ARGS((octa))@];@+@t}\6{@>
......@@ -26,7 +31,7 @@ void print_hex @,@,@[ARGS((octa))@];@+@t}\6{@>
The external definitions of mmix-arith
should also go int a header file.
should also go into a header file.
@x
@<Sub...@>=
......@@ -41,6 +46,7 @@ Fatal errors need to be handled but panic moves to libconfig.h
@x
@d panic(m) {@+fprintf(stderr,"Panic: %s!\n",m);@+exit(-2);@+}
@y
@d panic(m) {@+MMIX_ERROR("Panic: %s!\n",m);@+longjmp(mmix_exit,-2);@+}
@z
@x
......@@ -67,6 +73,14 @@ mem_node* new_mem @,@,@[ARGS((void))@];@+@t}\6{@>
#include <stdlib.h>
#include <stdio.h>
#include "libconfig.h"
#include <time.h>
#include "libtype.h"
#include "libglobals.h"
#include "mmixlib.h"
#include <setjmp.h>
extern jmp_buf mmix_exit;
mem_node* new_mem @,@,@[ARGS((void))@];@+@t}\6{@>
@z
......@@ -138,7 +152,16 @@ void read_tet @,@,@[ARGS((void))@];@+@t}\6{@>
#include <stdio.h>
#include <string.h>
#include "libconfig.h"
#include <time.h>
#include "libtype.h"
#include "libglobals.h"
#include "mmixlib.h"
#include "libarith.h"
#include "libname.h"
#include <setjmp.h>
extern jmp_buf mmix_exit;
@<Loading subroutines@>@;
......@@ -361,6 +384,13 @@ void make_map @,@,@[ARGS((void))@];@+@t}\6{@>
#include <sys/types.h>
#include <sys/stat.h>
#include "libconfig.h"
#include <time.h>
#include "libtype.h"
#include "libglobals.h"
#include "mmixlib.h"
#include <setjmp.h>
extern jmp_buf mmix_exit;
void make_map @,@,@[ARGS((void))@];@+@t}\6{@>
@z
......@@ -405,6 +435,10 @@ void print_freqs @,@,@[ARGS((mem_node*))@];@+@t}\6{@>
@(libprofile.c@>=
#include <stdio.h>
#include "libconfig.h"
#include <time.h>
#include "libtype.h"
#include "libglobals.h"
#include "mmixlib.h"
#include "libarith.h"
void print_freqs @,@,@[ARGS((mem_node*))@];@+@t}\6{@>
......@@ -502,8 +536,8 @@ register tetra f; /* properties of the current |op| */
@y
@ @<Glob...@>=
mmix_opcode op; /* operation code of the current instruction */
tetra f; /* properties of the current |op| */
int xx,yy,zz,yz; /* operand fields of the current instruction */
tetra f; /* properties of the current |op| */
@ @<Local...@>=
@z
......@@ -1363,6 +1397,10 @@ int mmgetchars(buf,size,addr,stop)
@(libmmget.c@>=
#include <stdio.h>
#include "libconfig.h"
#include <time.h>
#include "libtype.h"
#include "libglobals.h"
#include "mmixlib.h"
#include "libarith.h"
int mmgetchars(buf,size,addr,stop)
......@@ -1469,6 +1507,10 @@ into the simulated memory starting at address |addr|.
@(libmmput.c@>=
#include <stdio.h>
#include "libconfig.h"
#include <time.h>
#include "libtype.h"
#include "libglobals.h"
#include "mmixlib.h"
#include "libarith.h"
void mmputchars(unsigned char *buf,int size,octa addr)
......@@ -1527,6 +1569,13 @@ char stdin_chr @,@,@[ARGS((void))@];@+@t}\6{@>
#include <stdlib.h>
#include <stdio.h>
#include "libconfig.h"
#include <time.h>
#include "libtype.h"
#include "libglobals.h"
#include "mmixlib.h"
#include <setjmp.h>
extern jmp_buf mmix_exit;
char stdin_chr @,@,@[ARGS((void))@];@+@t}\6{@>
@z
......@@ -1790,6 +1839,10 @@ void trace_print @,@,@[ARGS((octa))@];@+@t}\6{@>
@ @(libtrace.c@>=
#include <stdio.h>
#include "libconfig.h"
#include <time.h>
#include "libtype.h"
#include "libglobals.h"
#include "mmixlib.h"
#include "libarith.h"
static fmt_style style;
......@@ -1818,6 +1871,10 @@ void show_stats @,@,@[ARGS((bool))@];@+@t}\6{@>
@ @(libstats.c@>=
#include <stdio.h>
#include "libconfig.h"
#include <time.h>
#include "libtype.h"
#include "libglobals.h"
#include "mmixlib.h"
#include "libarith.h"
void show_stats @,@,@[ARGS((bool))@];@+@t}\6{@>
......@@ -1873,6 +1930,11 @@ a working simulator to separate files of a library.
#include <stdlib.h>
#include <stdio.h>
#include "libconfig.h"
#include <time.h>
#include "libtype.h"
#include "libglobals.h"
#include "mmixlib.h"
#ifndef MMIX_TRAP
#include "mmix-io.h"
#endif
......@@ -1891,6 +1953,10 @@ int mmix_lib_initialize(void)
#include <stdio.h>
#include <signal.h>
#include "libconfig.h"
#include <time.h>
#include "libtype.h"
#include "libglobals.h"
#include "mmixlib.h"
#include "libarith.h"
#ifdef WIN32
......@@ -1901,6 +1967,9 @@ BOOL CtrlHandler(DWORD fdwCtrlType);
void catchint(int n);
#endif
#include <setjmp.h>
extern jmp_buf mmix_exit;
int mmix_initialize(void)
{
@<Initialize everything@>;
......@@ -1912,10 +1981,16 @@ int mmix_initialize(void)
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <setjmp.h>
#include "abstime.h"
#include "libconfig.h"
#include <time.h>
#include "libtype.h"
#include "libglobals.h"
#include "mmixlib.h"
#include "libarith.h"
extern jmp_buf mmix_exit;
extern void dump(mem_node *p);
extern void dump_tet(tetra t);
......@@ -1953,6 +2028,10 @@ int mmix_load_file(char *mmo_file_name)
#include <stdio.h>
#include <string.h>
#include "libconfig.h"
#include <time.h>
#include "libtype.h"
#include "libglobals.h"
#include "mmixlib.h"
#include "libarith.h"
int mmix_commandline(int argc, char *argv[])
......@@ -1968,6 +2047,10 @@ int mmix_commandline(int argc, char *argv[])
#include <string.h>
#include <ctype.h>
#include "libconfig.h"
#include <time.h>
#include "libtype.h"
#include "libglobals.h"
#include "mmixlib.h"
#include "libarith.h"
static octa scan_hex(char *s, octa offset);
......@@ -1987,6 +2070,10 @@ end_simulation:
#include <stdio.h>
#include <string.h>
#include "libconfig.h"
#include <time.h>
#include "libtype.h"
#include "libglobals.h"