# You will need gcc if you choose the optimised compile below
CC?=gcc
+# Set this to either PDP11 or Z180
+CPU=Z180
+
# Set the CFLAGS, LDFLAGS for speed or debugging. If you don't want 2.11BSD
# emulation, then remove the -DEMU211 flag.
# Set up the LIBS if required for your system
#APOUT_OPTIONS?= -DEMU211 -DEMUV1 -DNATIVES -DRUN_V1_RAW \
-DDEBUG -DZERO_MEMORY -DWRITEBASE
# These flags should be fine for most cases
-APOUT_OPTIONS?= -DEMU211 -DEMUv1 -DNATIVES -DDEBUG
+APOUT_OPTIONS?= -DNATIVES -DDEBUG
+ifeq ($(CPU),PDP11)
+APOUT_OPTIONS+= -DEMU211 -DEMUv1
+endif
# These flags for speed
#CFLAGS+= -DEMU211 -DNATIVES -DINLINE=inline -O2 -Winline -Wall \
#LDFLAGS?=
# Assemble CFLAGS
-CFLAGS?= -O2 -I. -DINLINE=inline -finline-functions -fomit-frame-pointer
+CFLAGS?= -O2 -I. -DINLINE=inline -DCPU_$(CPU) -finline-functions \
+-fomit-frame-pointer
CFLAGS+=-Winline -Wunused-result # silence warnings
CFLAGS+= $(APOUT_OPTIONS)
bsdtrap.h bsd_ioctl.c bsd_signal.c magic.c v1trap.c v1trap.h
PDP11_SRCS= pdp11/cpu.c pdp11/branch.c pdp11/double.c pdp11/ea.c pdp11/itab.c \
pdp11/ke11a.c pdp11/single.c pdp11/fp.c pdp11/debug.c
+Z180_SRCS= z180/cpu.c
OBJS= aout.o bsd_ioctl.o bsd_signal.o bsdtrap.o \
- magic.o main.o v1trap.o \
+ magic.o main.o \
v7trap.o
-PDP11_OBJS= pdp11/branch.o pdp11/cpu.o pdp11/debug.o \
+ifeq ($(CPU),PDP11)
+OBJS+= v1trap.o pdp11/branch.o pdp11/cpu.o pdp11/debug.o \
pdp11/double.o pdp11/ea.o pdp11/fp.o pdp11/itab.o pdp11/ke11a.o \
pdp11/single.o
+else ($(CPU),Z180)
+OBJS+= z180/cpu.o
+endif
-
-apout: $(OBJS) $(PDP11_OBJS)
- $(CC) $(LDFLAGS) $(OBJS) $(PDP11_OBJS) -o apout $(LIBS)
+apout: $(OBJS)
+ $(CC) $(LDFLAGS) $(OBJS) -o apout $(LIBS)
install: apout apout.1
cp apout $(BINDIR)
chmod 644 $(MANDIR)/apout.1
clean:
- rm -rf apout *core $(OBJS) $(PDP11_OBJS) *.dbg $(VERSION) $(VERSION).tar.gz apout.0
+ rm -rf apout *core $(OBJS) *.dbg $(VERSION) $(VERSION).tar.gz apout.0
apout.0: apout.1
nroff -man apout.1 > apout.0
-indent: $(SRCS)
- astyle --style=kr $(SRCS)
+indent: $(SRCS) $(PDP11_SRCS)
+ astyle --style=kr $(SRCS) $(PDP11_SRCS)
disttar: clean apout.0
- mkdir $(VERSION)
cp $(SRCS) $(VERSION)
+ cp $(PDP11_SRCS) $(VERSION)/pdp11
+ cp $(Z180_SRCS) $(VERSION)/z180
chmod -R go+rX $(VERSION)
chmod -R u+w $(VERSION)
chown -R wkt $(VERSION)
tar vzcf $(VERSION).tar.gz $(VERSION)
# Dependencies for object files
-aout.o: aout.c defines.h pdp11/pdp11.h aout.h Makefile
-pdp11/branch.o: pdp11/branch.c defines.h pdp11/pdp11.h Makefile
-bsd_ioctl.o: bsd_ioctl.c defines.h pdp11/pdp11.h Makefile
-bsd_signal.o: bsd_signal.c defines.h pdp11/pdp11.h bsdtrap.h Makefile
-bsdtrap.o: bsdtrap.c bsdtrap.h defines.h pdp11/pdp11.h Makefile
-pdp11/cpu.o: pdp11/cpu.c defines.h pdp11/pdp11.h Makefile
-pdp11/debug.o: pdp11/debug.c defines.h pdp11/pdp11.h Makefile
-pdp11/double.o: pdp11/double.c defines.h pdp11/pdp11.h Makefile
-pdp11/ea.o: pdp11/ea.c defines.h pdp11/pdp11.h Makefile
-pdp11/fp.o: pdp11/fp.c defines.h pdp11/pdp11.h Makefile
-pdp11/itab.o: pdp11/itab.c defines.h pdp11/pdp11.h Makefile
-pdp11/ke11a.o: pdp11/ke11a.c defines.h pdp11/pdp11.h Makefile
-magic.o: magic.c defines.h pdp11/pdp11.h Makefile
-main.o: main.c defines.h pdp11/pdp11.h Makefile
-pdp11/single.o: pdp11/single.c defines.h pdp11/pdp11.h Makefile
-v1trap.o: v1trap.c v1trap.h defines.h pdp11/pdp11.h Makefile
-v7trap.o: v7trap.c v7trap.h defines.h pdp11/pdp11.h Makefile
+aout.o: aout.c defines.h pdp11/cpu.h z180/cpu.h aout.h Makefile
+pdp11/branch.o: pdp11/branch.c defines.h pdp11/cpu.h Makefile
+bsd_ioctl.o: bsd_ioctl.c defines.h pdp11/cpu.h z180/cpu.h Makefile
+bsd_signal.o: bsd_signal.c defines.h pdp11/cpu.h z180/cpu.h bsdtrap.h Makefile
+bsdtrap.o: bsdtrap.c bsdtrap.h defines.h pdp11/cpu.h z180/cpu.h Makefile
+pdp11/cpu.o: pdp11/cpu.c defines.h pdp11/cpu.h Makefile
+pdp11/debug.o: pdp11/debug.c defines.h pdp11/cpu.h Makefile
+pdp11/double.o: pdp11/double.c defines.h pdp11/cpu.h Makefile
+pdp11/ea.o: pdp11/ea.c defines.h pdp11/cpu.h Makefile
+pdp11/fp.o: pdp11/fp.c defines.h pdp11/cpu.h Makefile
+pdp11/itab.o: pdp11/itab.c defines.h pdp11/cpu.h Makefile
+pdp11/ke11a.o: pdp11/ke11a.c defines.h pdp11/cpu.h Makefile
+magic.o: magic.c defines.h pdp11/cpu.h z180/cpu.h Makefile
+main.o: main.c defines.h pdp11/cpu.h z180/cpu.h Makefile
+pdp11/single.o: pdp11/single.c defines.h pdp11/cpu.h Makefile
+v1trap.o: v1trap.c v1trap.h defines.h pdp11/cpu.h z180/cpu.h Makefile
+v7trap.o: v7trap.c v7trap.h defines.h pdp11/cpu.h z180/cpu.h Makefile
+z180/cpu.o: z180/cpu.c defines.h z180/cpu.h z180/cpu.h Makefile
* $Revision: 1.51 $
* $Date: 2008/05/19 13:42:39 $
*/
+#include <assert.h>
+#include <stdbool.h>
#include "defines.h"
#include "aout.h"
/* Array of 64K for data and instruction space */
+u_int8_t *ispace, *dspace; /* Instruction and Data spaces */
static u_int8_t darray[PDP_MEM_SIZE], iarray[PDP_MEM_SIZE];
#ifdef EMU211
*/
int load_a_out(const char *file, const char *origpath, int want_env)
{
+#ifdef CPU_PDP11
/* @globals errno,stdout,stderr; @ */
#define V12_MEMBASE 16384 /* Offset for V1/V2 binaries load */
FILE *zin;
}
set_arg_env(want_env);
return (0);
+#else
+ assert(false);
+#endif
}
/*
*/
static void set_arg_env(int want_env)
{
+#ifdef CPU_PDP11
int i, posn, len;
int eposn[MAX_ARGS];
int aposn[MAX_ARGS];
posn -= 2;
sl_word(posn, (u_int16_t) Argc); /* Save the count of args */
regs[SP] = (u_int16_t) posn; /* and initialise the SP */
+#else
+ assert(false);
+#endif
}
#define sigismember(set, signo) ((*(set) & (1L << ((signo) - 1))) != 0)
#endif /* 0 */
+
+/* the following used to be in pdp11/cpu.c but moved here as it's generic */
+
+struct our_siglist *Sighead = NULL; /* List of pending signals */
+struct our_siglist *Sigtail = NULL; /* List of pending signals */
+void (*sigrunner) (void) = NULL; /* F'n that will run the signal */
+
+/* This is the generic function which catches
+ * a signal, and appends it to the queue.
+ */
+void sigcatcher(int sig)
+{
+ struct our_siglist *this;
+
+ this = (struct our_siglist *) malloc(sizeof(struct our_siglist));
+ if (this == NULL)
+ return;
+
+ TrapDebug((dbg_file, "Caught signal %d\n", sig));
+
+ this->sig = sig;
+ this->next = NULL;
+ if (Sighead == NULL) {
+ Sighead = Sigtail = this;
+ } else {
+ Sigtail->next = this;
+ Sigtail = this;
+ }
+}
#endif
#define MAX_ARGS 200 /* Max cmd-line args per process */
+#define PDP_MEM_SIZE 65536 /* Size of inst-space and data-space */
+extern u_int8_t *ispace, *dspace;
/* The following array holds the FILE pointers
* that correspond to open file descriptors.
void v1trap P((void));
/* bsdtrap.c */
-#ifdef EMU211
+#if 1 //def EMU211
void bsdtrap P((void)) /*@globals errno,stdout,stderr; @ */ ;
/* bsd_ioctl.h */
/* bsd_signal.c */
void set_bsdsig_dfl P((void));
int do_sigaction P((int sig, int a, int oa));
+void sigcatcher P((int sig));
#endif
#undef P
-#include "pdp11/pdp11.h"
+#ifdef CPU_PDP11
+#include "pdp11/cpu.h"
+#endif
+#ifdef CPU_Z180
+#include "z180/cpu.h"
+#endif
#include "defines.h"
#include <unistd.h>
-u_int8_t *ispace, *dspace; /* Instruction and Data spaces */
u_int16_t dwrite_base = 2; /* Lowest addr where dspace writes can occur */
u_int16_t regs[8]; /* general registers */
u_int8_t dstbyte; /* function calls */
u_int8_t srcbyte;
u_int8_t tmpbyte;
-struct our_siglist *Sighead = NULL; /* List of pending signals */
-struct our_siglist *Sigtail = NULL; /* List of pending signals */
-void (*sigrunner) (void) = NULL; /* F'n that will run the signal */
#ifdef DEBUG
extern char *iname[1024];
(int) getpid(), regs[PC]));
exit(EXIT_FAILURE);
}
-
-/* This is the generic function which catches
- * a signal, and appends it to the queue.
- */
-void sigcatcher(int sig)
-{
- struct our_siglist *this;
-
- this = (struct our_siglist *) malloc(sizeof(struct our_siglist));
- if (this == NULL)
- return;
-
- TrapDebug((dbg_file, "Caught signal %d\n", sig));
-
- this->sig = sig;
- this->next = NULL;
- if (Sighead == NULL) {
- Sighead = Sigtail = this;
- } else {
- Sigtail->next = this;
- Sigtail = this;
- }
-}
-#ifndef _PDP11_H
-#define _PDP11_H
+#ifndef _PDP11_CPU_H
+#define _PDP11_CPU_H
/* Set up prototype macro for
* both K&R and ANSI C platforms
#define CC_VBIT 02
#define CC_CBIT 01
-#define PDP_MEM_SIZE 65536 /* Size of inst-space and data-space */
-
/* Global variables. */
extern int INTMODE; /* 0 = integers, 1 = longs */
extern u_int16_t ea_addr; /* stored address for dest modifying insts */
-extern u_int8_t *ispace, *dspace;
extern u_int16_t dwrite_base; /* Lowest addr where dspace writes can occur */
extern u_int16_t dstword; /* These globals are used in the effective */
void mtpd P((void));
void trap P((void));
void bad_FP_reg P((void));
-void sigcatcher P((int sig));
/* ea.c */
void load_ea P((void));
* $Revision: 1.50 $
* $Date: 2008/05/19 13:45:58 $
*/
+#include <assert.h>
+#include <stdbool.h>
#include "defines.h"
#include <sys/stat.h>
#include <sys/time.h>
+#ifdef CPU_PDP11
/* Work out the actual trap number, and */
/* shift the PC up past any arguments */
/* to the syscall. Calculate base of args */
V7A.uarg[i] = regs[i];
for (; i < v7arg[trapnum].nwords; i++, argbase += 2)
ll_word(argbase, V7A.uarg[i]);
+#else
+ assert(false);
+#endif
TrapDebug((dbg_file, "pid %d %s: ", (int) getpid(),
v7trap_name[trapnum]));
i = v7signal(uarg1, uarg2);
break;
case S_EXIT:
+#ifdef CPU_PDP11
exit(regs[0]);
+#else
+ assert(false);
+#endif
i = -1;
errno = EPERM;
break;
case S_NICE:
+#ifdef CPU_PDP11
i = nice(regs[0]);
+#else
+ assert(false);
+#endif
break;
case S_PAUSE:
i = pause();
if ((Binary == IS_A68 || Binary == IS_V6) || (Binary == IS_V5)) {
fixv6time(&tim); /* Fix annoying bug in V5/V6 ctime() */
}
+#ifdef CPU_PDP11
regs[1] = tim & 0xffff;
+#else
+ assert(false);
+#endif
i = tim >> 16;
break;
case S_ALARM:
i = 0;
break;
}
+#ifdef CPU_PDP11
regs[1] = i & 0xffff;
+#else
+ assert(false);
+#endif
i = i >> 16;
break;
case S_READ:
}
#endif
i = pfd[0];
+#ifdef CPU_PDP11
regs[1] = pfd[1];
+#else
+ assert(false);
+#endif
break;
case S_CHROOT:
buf = xlate_filename((char *) &dspace[uarg1]);
i = wait(&pid);
if (i == -1)
break;
+#ifdef CPU_PDP11
regs[1] = pid;
+#else
+ assert(false);
+#endif
break;
case S_FORK:
pid = getpid();
break;
/* Parent: Skip child `bf', pid into r0 */
default:
+#ifdef CPU_PDP11
regs[PC] += 2;
+#else
+ assert(false);
+#endif
}
break;
case S_GETUID:
i = geteuid();
+#ifdef CPU_PDP11
regs[1] = i;
+#else
+ assert(false);
+#endif
i = getuid();
break;
case S_GETPID:
break;
case S_GETGID:
i = getegid();
+#ifdef CPU_PDP11
regs[1] = i;
+#else
+ assert(false);
+#endif
i = getgid();
break;
case S_SETUID:
break;
default:
if (trapnum > S_CHROOT) {
+#ifdef CPU_PDP11
fprintf(stderr, "Apout - unknown syscall %d at PC 0%o\n",
trapnum, regs[PC]);
+#else
+ assert(false);
+#endif
} else {
fprintf(stderr,
"Apout - the %s syscall is not yet implemented\n",
/* and clear/set C bit */
if (i == -1) {
+#ifdef CPU_PDP11
SET_CC_C();
+#else
+ assert(false);
+#endif
TrapDebug((dbg_file, "errno is %s\n", strerror(errno)));
} else {
+#ifdef CPU_PDP11
CLR_CC_C();
regs[0] = i;
+#else
+ assert(false);
+#endif
#ifdef DEBUG
if (trap_debug) {
fprintf(dbg_file, "return %d\n", i);
i = tcgetattr(fd, &tios);
if (i == -1)
return i;
+#ifdef CPU_PDP11
CLR_CC_C();
+#else
+ assert(false);
+#endif
sgtb = (struct tr_sgttyb *) &dspace[ucnt];
sgtb->sg_ispeed = cfgetispeed(&tios); /* tios.c_ispeed; --gray */
sgtb->sg_ospeed = cfgetospeed(&tios); /* tios.c_ospeed; --gray */
--- /dev/null
+/* cpu.c - this holds the main loop for the emulator, plus generic
+ * functions to deal with exceptional instructions and events
+ *
+ * $Revision: 1.26 $
+ * $Date: 2008/05/15 07:52:45 $
+ */
+#include <assert.h>
+#include <stdbool.h>
+#include "defines.h"
+#include <unistd.h>
+
+u_int16_t *adptr; /* used in memory access macros */
+
+void run(void) {
+ assert(false);
+}
--- /dev/null
+#ifndef _Z180_CPU_H
+#define _Z180_CPU_H
+
+/* Macros to read and write loctions in
+ * main memory.
+ */
+
+extern u_int16_t *adptr;
+
+#define copylong(to,from) \
+ buf = (char *) &(to); buf2 = (char *) &(from); \
+ buf[0]=buf2[2]; buf[1]=buf2[3]; buf[2]=buf2[0]; buf[3]=buf2[1]
+
+/* lli_word() - Load a word from the given ispace logical address. */
+#define lli_word(addr, word) \
+ { adptr= (u_int16_t *)&(ispace[addr]); word= *adptr; }
+
+/* ll_word() - Load a word from the given logical address. */
+#define ll_word(addr, word) \
+ { adptr= (u_int16_t *)&(dspace[addr]); word= *adptr; }
+
+/* sl_word() - Store a word at the given logical address. */
+#ifdef WRITEBASE
+#define sl_word(addr, word) \
+ { if ((u_int16_t)addr < dwrite_base) seg_fault(); \
+ adptr= (u_int16_t *)&(dspace[addr]); *adptr= word; }
+#else
+#define sl_word(addr, word) \
+ { adptr= (u_int16_t *)&(dspace[addr]); *adptr= word; }
+#endif
+
+/* lli_byte() - Load a byte from the given logical ispace address. */
+#define lli_byte(addr, byte) \
+ byte = ispace[addr];
+
+/* ll_byte() - Load a byte from the given logical address. */
+#define ll_byte(addr, byte) \
+ byte = dspace[addr];
+
+/* sl_byte() - Store a byte at the given logical address. */
+#ifdef WRITEBASE
+#define sl_byte(addr, byte) \
+ { if (addr < dwrite_base) seg_fault(); \
+ dspace[addr]= byte; }
+#else
+#define sl_byte(addr, byte) \
+ { dspace[addr]= byte; }
+#endif
+
+void run(void);
+
+#endif