Commit 6cbb2ffa authored by Martin Ruckert's avatar Martin Ruckert
Browse files

First version running with the plain configuration under unix

parent 08806ef4
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 \
libdump.c liblibfinal.c libmmput.c libshowline.c \
libfetch.c liblibinit.c libperform.c libsoption.c \
libarith.h libtype.h
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
LIBH= libarith.h libtype.h mmix-io.h
LIBOBJ= $(LIBSIM:.c=.o) mmix-arith.o libmmixal.o
LIBSRC= libname.c libbase.c
LIBOBJ= $(LIBSIM:.c=.o) $(LIBSRC:.c=.o) mmix-arith.o mmix-io.o libmmixal.o
CC= gcc
CFLAGS= -Wall
CFLAGS= -Wall -ggdb -O0
AR = ar
ARFLAGS = cru
RANLIB = ranlib
all: libmmix.a mmix-sim.c
all: libmmix.a mmix-sim.c mmixal.c
libbase.o: libbase.c libbase.h libconfig.h
%.o : %.c abstime.h mmixlib.h
......@@ -33,11 +36,14 @@ mmix/abstime.h: mmix/abstime
mmix-arith.c: boilerplate.w mmix/mmix-arith.w
ctangle mmix/mmix-arith.w
libmmixal.c:
ctangle mmix/mmixal.w libmixal.ch libmmixal.c
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
ctangle mmix/mmixal.w mmixallib.ch
$(LIBSIM) mmix-sim.c: boilerplate.w mmix/mmix-sim.w mmixlib.ch libconfig.h
$(LIBSIM) $(LIBH) mmix-sim.c: boilerplate.w mmix/mmix-sim.w mmixlib.ch libconfig.h
ctangle mmix/mmix-sim.w mmixlib.ch
......@@ -46,10 +52,12 @@ libmmix.a: $(LIBSIM) $(LIBOBJ)
$(AR) $(ARFLAGS) $@ $(LIBOBJ)
$(RANLIB) $@
mmix-sim: libmmix.a mmix-sim.c
$(CC) $(CFLAGS) mmix-sim.c -L. -lmmix -o mmix-sim
clean:
rm -f *.o
rm -f $(LIBSIM) mmix-arith.c libmmixal.c
rm -f *~
rm -f libmmix.a
rm -f mmix-sim.c
rm -f $(LIBSIM) $(LIBH) mmix-arith.c libmmixal.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 "mmix-internals.h"
#include "vmb.h"
#include "mmixlib.h"
#include "libconfig.h"
#include "libbase.h"
static void free_sym(sym_node *sym)
{ if (((unsigned long long int)sym&~0x3)==0) return;
......@@ -38,4 +41,4 @@ void free_file_info(void)
}
ybyte2file_no[i]=-1;
}
}
\ No newline at end of file
}
typedef struct ternary_trie_struct{
unsigned short ch;
struct ternary_trie_struct*left,*mid,*right;
struct sym_tab_struct*sym;
}trie_node;
typedef struct sym_tab_struct{
int file_no;
int line_no;
int serial;
struct sym_tab_struct*link;
octa equiv;
}sym_node;
......@@ -5,17 +5,15 @@
#pragma warning(disable : 4996)
#endif
/* this is the error exit function */
#define panic(m) (fprintf(stderr,"Panic: %s!\n",m), exit(-1))
#define store_octa(val,addr) (ll=mem_find(addr),ll->tet=(val).h,(ll+1)->tet=(val).l,true)
#define store_tetra(val,addr) (ll=mem_find(addr),ll->tet=(val).l,true)
#define store_wyde(val,addr) (ll=mem_find(addr),ll->tet=(ll->tet&~0xFFFF)|((val).l&0xFFFF),true)
#define store_byte(val,addr) (ll=mem_find(addr),ll->tet=(ll->tet&~0xFF)|((val).l&0xFF),true)
#define store_wyde(val,addr) (ll=mem_find(addr),ll->tet=(ll->tet&(~(0xFFFF<<((1-((addr).l&0x1))<<4))))|(((val).l&0xFFFF)<<((1-((addr).l&0x1))<<4)),true)
#define store_byte(val,addr) (ll=mem_find(addr),ll->tet=(ll->tet&(~(0xFF<<((3-((addr).l&0x3))<<3))))|(((val).l&0xFF)<<((3-((addr).l&0x3))<<3)),true)
#define load_octa(val,addr) (ll=mem_find(addr),(val)->h=ll->tet,(val)->l=(ll+1)->tet,true)
#define load_tetra(val,addr) (ll=mem_find(addr),(val)->h=0,(val)->l=ll->tet,true)
#define load_byte(val,addr) (ll=mem_find(addr),(val)->h=0,(val)->l=(ll->tet>>(8*((addr).l&3)))&0xFF,true)
#define load_wyde(val,addr) (ll=mem_find(addr),(val)->h=0,(val)->l=(ll->tet>>(16*(1-((addr).l&1))))&0xFFFF,true)
#define load_byte(val,addr) (ll=mem_find(addr),(val)->h=0,(val)->l=(ll->tet>>(8*(3-((addr).l&3))))&0xFF,true)
#define store_octa_uncached(val,addr) store_octa(val,addr)
#define load_octa_uncached(val,addr) load_octa(val,addr)
......@@ -65,14 +63,26 @@ extern int mmix_fputc(int c, FILE *f);
#define MMIX_USAGE if (!*cur_arg) scan_option("?",true) /* exit with usage note */
#define MMIX_BREAK_LOOP false
/* give a condition to break from the inner loop */
#define MMIX_BREAK_LOOP false
/* give a condition to test for a reboot inside the inner loop */
#define MMIX_REBOOT false
#define MMIX_BOOT false
/* define this to get the real TRAP implementation not the MMIXWARE fake TRAPS */
#undef MMIX_TRAP
#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))
#define MMIX_OPTION_STRING
/* define this if you need the tetra inside the mem_node */
#define MEM_NODE_TET tetra tet; /* the tetrabyte of simulated memory */
#define MMIX_MEM_TET tetra tet; /* the tetrabyte of simulated memory */
#define write_all_data_cache()
#define clear_all_instruction_cache()
......@@ -86,14 +96,6 @@ extern int mmix_fputc(int c, FILE *f);
#define delete_data_cache(w,xx)
#define delete_instruction_cache(w,xx)
// do we need this always ?
//include <setjmp.h>
//include "mmixlib.h"
//extern int ybyte2file_no[256]; /* mapping internal to external files */
//define YBYTE2FILENO(ybyte) ybyte2file_no[ybyte]
//define NAME2FILENO(name,ybyte) (ybyte2file_no[ybyte]=filename2file(name,ybyte))
#include <time.h>
#include "libtype.h"
#include "libglobals.h"
......
......@@ -9,21 +9,21 @@ to declare the extern library interface.
@<Preprocessor definitions@>=
@y
@<Sub...@>=
#ifdef MMIXLIB
#include "mmixlib.h"
#include "libname.h"
#endif
@ @<Global...@>=
static jmp_buf error_exit;
@ @<Preprocessor definitions@>=
#include <setjmp.h>
#ifdef MMIX_PRINT
extern int mmix_printf(char *format,...);
#define printf(...) mmix_printf(__VA_ARGS__)
#ifdef MMIX_PRINT
extern int mmix_printf(char *format,...);
#define printf(...) mmix_printf(__VA_ARGS__)
#endif
#ifdef WIN32
#pragma warning(disable : 4996)
#endif
#define _MMIXAL_
@z
......@@ -31,9 +31,9 @@ We change error messages that handle errors in the command line
(there is none). Errors are no longer written to stderr.
@x
fprintf(stderr,
"(say `-b <number>' to increase the length of my input buffer)\n");
@y
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");
@z
......@@ -51,39 +51,39 @@ Whenever we enter a new filename, we look up
the external file number for it.
@x
filename_count++;
filename_count++;
@y
file_no[filename_count]=filename2file(filename[filename_count],filename_count);
filename_count++;
file_no[filename_count]=filename2file(filename[filename_count],filename_count);
filename_count++;
@z
Next we change the way errors are reported:
@x
if (message[0]=='*')
fprintf(stderr,"\"%s\", line %d warning: %s\n",
filename[cur_file],line_no,message+1);
else if (message[0]=='!')
fprintf(stderr,"\"%s\", line %d fatal error: %s\n",
filename[cur_file],line_no,message+1);
else {
fprintf(stderr,"\"%s\", line %d: %s!\n",
filename[cur_file],line_no,message);
err_count++;
}
@x
if (message[0]=='*')
fprintf(stderr,"\"%s\", line %d warning: %s\n",
filename[cur_file],line_no,message+1);
else if (message[0]=='!')
fprintf(stderr,"\"%s\", line %d fatal error: %s\n",
filename[cur_file],line_no,message+1);
else {
fprintf(stderr,"\"%s\", line %d: %s!\n",
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 (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;
}
@z
......@@ -97,10 +97,10 @@ The error exit is redirected using a longjmp.
longjmp(error_exit,-2);
@z
@x
int err_count; /* this many errors were found */
@y
int err_count; /* negativ for fatal erros else (erros<<16)+warnings */
@x
int err_count; /* this many errors were found */
@y
int err_count; /* negativ for fatal erros else (erros<<16)+warnings */
@z
In the assemble subroutine, we have the
......@@ -108,7 +108,7 @@ opportunity to gain some information about
the association of lines and locations.
@x
for (j=0;j<k;j++) {
for (j=0;j<k;j++) {
@y
add_line_loc(file_no[cur_file], line_no, cur_loc);
for (j=0;j<k;j++) {
......@@ -117,46 +117,46 @@ the association of lines and locations.
We allocate tree nodes node by node so that we can free them again.
@x
register trie_node *t=next_trie_node;
if (t==last_trie_node) {
t=(trie_node*)calloc(1000,sizeof(trie_node));
if (!t) panic("Capacity exceeded: Out of trie memory");
@.Capacity exceeded...@>
last_trie_node=t+1000;
}
next_trie_node=t+1;
register trie_node *t=next_trie_node;
if (t==last_trie_node) {
t=(trie_node*)calloc(1000,sizeof(trie_node));
if (!t) panic("Capacity exceeded: Out of trie memory");
@.Capacity exceeded...@>
last_trie_node=t+1000;
}
next_trie_node=t+1;
return t;
@y
trie_node *t=(trie_node*)calloc(1,sizeof(trie_node));
if (!t) panic("Capacity exceeded: Out of trie memory");
trie_node *t=(trie_node*)calloc(1,sizeof(trie_node));
if (!t) panic("Capacity exceeded: Out of trie memory");
return t;
@z
We need extra information in the symbol table.
@x
typedef struct sym_tab_struct {
typedef struct sym_tab_struct {
@y
typedef struct sym_tab_struct {
int file_no;
int line_no;
typedef struct sym_tab_struct {
int file_no;
int line_no;
@z
We allocat single sym nodes to be able to free them.
@x
p=next_sym_node;
if (p==last_sym_node) {
p=(sym_node*)calloc(1000,sizeof(sym_node));
if (!p) panic("Capacity exceeded: Out of symbol memory");
@.Capacity exceeded...@>
last_sym_node=p+1000;
}
next_sym_node=p+1;
@y
p=(sym_node*)calloc(1,sizeof(sym_node));
if (!p) panic("Capacity exceeded: Out of symbol memory");
@z
p=next_sym_node;
if (p==last_sym_node) {
p=(sym_node*)calloc(1000,sizeof(sym_node));
if (!p) panic("Capacity exceeded: Out of symbol memory");
@.Capacity exceeded...@>
last_sym_node=p+1000;
}
next_sym_node=p+1;
@y
p=(sym_node*)calloc(1,sizeof(sym_node));
if (!p) panic("Capacity exceeded: Out of symbol memory");
@z
The special names are already defined in mmix-sim.w
......@@ -173,24 +173,24 @@ Errors generated at the end of the assembly should use the
normal error reporting macros.
@x
fprintf(stderr,"undefined symbol: %s\n",sym_buf+1);
@.undefined symbol@>
err_count++;
fprintf(stderr,"undefined symbol: %s\n",sym_buf+1);
@.undefined symbol@>
err_count++;
@y
sprintf(err_buf,"undefined symbol: %s",sym_buf+1);
sprintf(err_buf,"undefined symbol: %s",sym_buf+1);
report_error(err_buf);
@.undefined symbol@>
err_count+=0x10000;
@.undefined symbol@>
err_count+=0x10000;
@z
when a sym_node becomes DEFINED, we record file and line.
@x
@<Find the symbol table node, |pp|@>;
@y
@<Find the symbol table node, |pp|@>;
pp->file_no=file_no[cur_file];
pp->line_no=line_no;
@<Find the symbol table node, |pp|@>;
@y
@<Find the symbol table node, |pp|@>;
pp->file_no=file_no[cur_file];
pp->line_no=line_no;
@z
......@@ -208,20 +208,78 @@ static tetra z,y,x,yz,xyz; /* pieces for assembly */
The main() program becomes mmixal().
@x
@c
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#include <time.h>
@#
@<Preprocessor definitions@>@;
@<Type definitions@>@;
@<Global variables@>@;
@<Subroutines@>@;
@#
int main(argc,argv)
int argc;@+
char *argv[];
@y
int mmixal(char *mms_name, char *mmo_name, char *mml_name, int x_option, int b_option)
@z
There is no commandline to process,
instead we handle the function parameters and
install the return point for
a global error exit. Further, we have to initialize global variables.
@x
{
register int j,k; /* all-purpose integers */
@<Local variables@>;
@<Process the command line@>;
@<Initialize everything@>;
while(1) {
@<Get the next line of input text, or |break| if the input has ended@>;
while(1) {
@<Process the next \MMIXAL\ instruction or comment@>;
if (!*buf_ptr) break;
}
if (listing_file) {
if (listing_bits) listing_clear();
else if (!line_listed) flush_listing_line(" ");
}
}
@<Finish the assembly@>;
}
@y
@c
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#include <time.h>
@#
@<Preprocessor definitions@>@;
@<Type definitions@>@;
@#
int main(argc,argv)
int argc;@+
char *argv[];
{
register int j,k; /* all-purpose integers */
@<Local variables@>;
@<Process the command line@>;
return mmixal(mms_name, mmo_name, mml_name, x_option, b_option);
}
@ @(libmmixal.c@>=
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#include <time.h>
@#
@h
@<Preprocessor definitions@>@;
@<Type definitions@>@;
@<Global variables@>@;
@<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);
if (err_count!=0){
prune(trie_root);
......@@ -240,88 +298,100 @@ a global error exit. Further, we have to initialize global variables.
strncpy(listing_name,mml_name,FILENAME_MAX);
expanding = x_option;
buf_size = b_option;
cur_file=0;
line_no=0;
long_warning_given=0;
cur_loc.h=cur_loc.l=0;
listing_loc.h=listing_loc.l=0;
spec_mode= 0;
spec_mode_loc= 0;
mmo_ptr=0;
err_count=0;
serial_number=0;
filename_count=0;
for (j=0;j<10;j++)
{ forward_local[j].link=0;
backward_local[j].link=0;
}
greg= 255;
cur_file=0;
line_no=0;
long_warning_given=0;
cur_loc.h=cur_loc.l=0;
listing_loc.h=listing_loc.l=0;
spec_mode= 0;
spec_mode_loc= 0;
mmo_ptr=0;
err_count=0;
serial_number=0;
filename_count=0;
for (j=0;j<10;j++)
{ forward_local[j].link=0;
backward_local[j].link=0;
}
greg= 255;
lreg= 32;
@<Initialize everything@>;
while(1) {
@<Get the next line of input text, or |break| if the input has ended@>;
while(1) {
@<Process the next \MMIXAL\ instruction or comment@>;
if (!*buf_ptr) break;
}
if (listing_file) {
if (listing_bits) listing_clear();
else if (!line_listed) flush_listing_line(" ");
}
}
@<Finish the assembly@>;
}
@z
We assign the source file to filename[0]
and set also file_no[0]
@x
filename[0]=src_file_name;
filename[0]=src_file_name;
filename_count=1;
@y
filename[0]=src_file_name;
file_no[0]=filename2file(src_file_name,0);
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
if (err_count) {
if (err_count>1) fprintf(stderr,"(%d errors were found.)\n",err_count);
else fprintf(stderr,"(One error was found.)\n");
}
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);
}
clean_up:
if (listing_file!=NULL)
{ fclose(listing_file);
listing_file=NULL;
}
if (obj_file!=NULL)
{ fclose(obj_file);
obj_file=NULL;
}
if (src_file!=NULL)
{ fclose(src_file);
src_file=NULL;
}
cur_file=0;
line_no=0;
long_warning_given=0;
cur_loc.h=cur_loc.l=0;
listing_loc.h=listing_loc.l=0;
spec_mode= 0;
spec_mode_loc= 0;
serial_number=0;
free(buffer); buffer=NULL;
free(lab_field); lab_field=NULL;
free(op_field); op_field=NULL;
free(operand_list); operand_list=NULL;
free(err_buf);err_buf=NULL;
free(op_stack); op_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;
if (err_count) {
if (err_count>1) fprintf(stderr,"(%d errors were found.)\n",err_count);
else fprintf(stderr,"(One error was found.)\n");
}
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);
}
clean_up:
if (listing_file!=NULL)
{ fclose(listing_file);
listing_file=NULL;
}
if (obj_file!=NULL)
{ fclose(obj_file);
obj_file=NULL;
}
if (src_file!=NULL)
{ fclose(src_file);
src_file=NULL;
}
cur_file=0;
line_no=0;
long_warning_given=0;
cur_loc.h=cur_loc.l=0;
listing_loc.h=listing_loc.l=0;
spec_mode= 0;
spec_mode_loc= 0;
serial_number=0;
free(buffer); buffer=NULL;
free(lab_field); lab_field=NULL;
free(op_field); op_field=NULL;
free(operand_list); operand_list=NULL;
free(err_buf);err_buf=NULL;
free(op_stack); op_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;