1
0
mirror of https://github.com/aap/pdp6.git synced 2026-01-11 23:53:31 +00:00

emu: implemented basic command line interface; sav loader

This commit is contained in:
aap 2017-01-31 00:48:09 +01:00
parent 3197705f49
commit a2de61d375
9 changed files with 470 additions and 1369 deletions

View File

@ -1,4 +1,5 @@
SRC=main.c apr.c mem.c tty.c pt.c
SRC=main.c cmd.c apr.c mem.c tty.c pt.c ../tools/pdp6common.c
H=pdp6.h ../tools/pdp6common.h
# clang
#CFLAGS= -Wno-shift-op-parentheses -Wno-logical-op-parentheses \
# -Wno-bitwise-op-parentheses
@ -8,6 +9,6 @@ CFLAGS= -g -fno-diagnostics-show-caret \
LIBS= `sdl-config --libs` `pkg-config SDL_image --libs` -lpthread
pdp6: $(SRC) pdp6.h
pdp6: $(SRC) $(H)
$(CC) $(CFLAGS) $(SRC) $(LIBS) -o pdp6

View File

@ -3034,11 +3034,15 @@ nextpulse(Apr *apr, Pulse *p)
apr->nlist[apr->nnextpulses++] = p;
}
void
initapr(Apr *apr)
Apr*
makeapr(void)
{
Apr *apr;
apr = malloc(sizeof(Apr));
memset(apr, 0, sizeof(Apr));
apr->iobus.dev[CPA] = (Busdev){ apr, wake_cpa, 0 };
apr->iobus.dev[PI] = (Busdev){ apr, wake_pi, 0 };
return apr;
}
/* find out which bits were turned on */

377
emu/cmd.c Normal file
View File

@ -0,0 +1,377 @@
#include "pdp6.h"
#include "args.h"
#define MAXOPS 20
static char *lp;
static int numops;
static char *ops[MAXOPS];
/* current apr */
static Apr *apr;
static void
skipwhite(void)
{
while(isspace(*lp))
lp++;
}
static int
isdelim(char c)
{
return c && strchr(" \t\n;'\"", c) != nil;
}
/* tokenize lp into ops[numops] */
static void
splitops(void)
{
char delim;
char *p;
numops = 0;
for(; *lp; lp++){
skipwhite();
if(*lp == ';' || *lp == '\0')
return;
if(numops == MAXOPS){
fprintf(stderr, "Too many arguments, ignored <%s>\n", lp);
return;
}
if(*lp == '"' || *lp == '\''){
delim = *lp++;
ops[numops++] = p = lp;
while(*lp && *lp != delim){
if(*lp == '\\')
lp++;
*p++ = *lp++;
}
*p = '\0';
}else{
ops[numops++] = p = lp;
while(!isdelim(*lp)){
if(*lp == '\\')
lp++;
*p++ = *lp++;
}
*p = '\0';
}
}
}
/* Parse an octal, decimal or hexadecimal number.
* 0nnnn is an octal number.
* nnnn. is a decimal number.
* 0xnnnn is a hexadecimal number.
* returns ~0 on error.
*/
word
parsen(char **sp)
{
char *s;
word dec, oct, hex;
char c;
int base;
s = *sp;
base = 0;
dec = oct = hex = 0;
if(s[0] == '0'){
s++;
base = 8;
if(*s == 'x' || *s == 'X'){
s++;
base = 16;
}
}
while(c = *s++){
if(c >= '0' && c <= '9')
c -= '0';
else if(c >= 'A' && c <= 'F')
c -= 'A' + 10;
else if(c >= 'a' && c <= 'f')
c -= 'a' + 10;
else if(c == '.'){
/* decimal number, but only if . is at the end */
if(base <= 10 && *s == '\0'){
base = 10;
break;
}else
goto fail;
}else
break;
oct = oct*8 + c;
dec = dec*10 + c;
hex = hex*16 + c;
if(c >= 8){
if(base < 8)
base = 8;
else
goto fail;
}
if(c >= 10){
if(base < 10)
base = 10;
else
goto fail;
}
if(c >= 16){
if(base < 16)
base = 16;
else
goto fail;
}
}
*sp = s-1;
if(base == 16) return hex;
if(base == 10) return dec;
return oct;
fail:
printf("error: number format\n");
return ~0;
}
static int
parserange(char *s, word *start, word *end)
{
*start = *end = ~0;
*start = parsen(&s);
if(*start == ~0) return 1;
if(*s == '\0'){
*end = *start;
return 0;
}else if(*s == '-' || *s == ':'){
s++;
*end = parsen(&s);
if(*end == ~0) return 1;
}
if(*s){
*start = *end = ~0;
printf("error: address format\n");
return 1;
}
return 0;
}
enum
{
FmtOct, FmtMnem
};
static void
exam(word addr, int fastmem, int format)
{
word *p;
p = getmemref(&apr->membus, addr, fastmem);
if(p == nil){
printf("Non existent memory\n");
return;
}
printf("%06lo: ", addr);
switch(format){
case FmtOct:
default:
printf("%012lo\n", *p);
break;
case FmtMnem:
printf("%s\n", disasm(*p));
break;
}
}
static void
dep(word addr, int fastmem, word w)
{
word *p;
p = getmemref(&apr->membus, addr, fastmem);
if(p == nil){
printf("Non existent memory\n");
return;
}
*p = w;
}
/* Commands */
static void
c_ex(int argc, char *argv[])
{
char *argv0;
word start, end;
int format, fastmem;
format = FmtOct;
fastmem = 1;
ARGBEGIN{
case 's': /* shadow mode */
fastmem = 0;
break;
case 'm':
format = FmtMnem;
break;
}ARGEND;
if(argc < 1)
return;
if(parserange(argv[0], &start, &end))
return;
for(; start <= end; start++)
exam(start, fastmem, format);
}
static void
c_dep(int argc, char *argv[])
{
char *argv0;
word start, end;
word w;
int fastmem;
fastmem = 1;
ARGBEGIN{
case 's':
fastmem = 0;
break;
}ARGEND;
if(argc < 2)
return;
if(parserange(argv[0], &start, &end))
return;
w = parsen(&argv[1]);
if(w == ~0)
return;
for(; start <= end; start++)
dep(start, fastmem, w);
}
enum
{
FmtUnk, FmtSav
};
static void
loadsav(FILE *fp)
{
word iowd;
word w;
while(w = readwbak(fp), w != ~0){
if(w >> 27 == 0254){
apr->pc = right(w);
return;
}
iowd = w;
while(left(iowd) != 0){
iowd += 01000001;
w = readwbak(fp);
if(w == ~0)
return;
dep(right(iowd), 0, w);
}
}
}
static void
c_load(int argc, char *argv[])
{
FILE *fp;
int fmt;
fmt = FmtSav; // assume SAV for now
ARGBEGIN{
case 's':
fmt = FmtSav;
break;
}ARGEND;
if(argc < 1)
return;
fp = fopen(argv[0], "rb");
if(fp == nil){
printf("couldn't open file: %s\n", argv[0]);
return;
}
if(fmt == FmtSav)
loadsav(fp);
fclose(fp);
}
static void
c_show(int argc, char *argv[])
{
printf("Memory:\n");
showmem(&apr->membus);
}
static void
c_quit(int argc, char *argv[])
{
quit(0);
}
struct {
char *cmd;
void (*f)(int, char **);
} cmdtab[] = {
{ "examine", c_ex },
{ "deposit", c_dep },
{ "load", c_load },
{ "show", c_show },
{ "quit", c_quit },
{ "", nil}
};
void*
cmdthread(void *p)
{
size_t len, l;
char *line, *cmd;
int i, n;
int nfound;
apr = nil;
for(i = 0; i < 4; i++)
if(aprs[i]){
apr = aprs[i];
break;
}
for(;;){
line = nil;
len = 0;
printf("> ");
if(getline(&line, &len, stdin) < 0)
quit(0);
lp = line;
splitops();
if(numops){
nfound = 0;
for(i = 0; cmdtab[i].cmd[0]; i++){
cmd = cmdtab[i].cmd;
l = strlen(ops[0]);
if(strncmp(ops[0], cmd, l) == 0){
n = i;
nfound++;
}
}
if(nfound == 0)
printf("%s: not found\n", ops[0]);
else if(nfound == 1)
cmdtab[n].f(numops, ops);
else{
printf("Ambiguous command: %s\n", ops[0]);
for(i = 0; cmdtab[i].cmd[0]; i++){
cmd = cmdtab[i].cmd;
l = strlen(ops[0]);
if(strncmp(ops[0], cmd, l) == 0)
printf(" %s\n", cmd);
}
}
}
free(line);
}
return nil;
}

View File

@ -534,6 +534,14 @@ getms(void)
return SDL_GetTicks();
}
void
quit(int code)
{
//SDL_Quit();
putchar('\n');
exit(code);
}
void
usage(void)
{
@ -541,10 +549,7 @@ usage(void)
exit(1);
}
Apr apr;
Tty tty;
Ptr ptr;
Ptp ptp;
Apr *aprs[4];
Mem *coremems[4];
int
@ -559,8 +564,14 @@ main(int argc, char *argv[])
int delay;
int i;
int w, h;
pthread_t cmd_thread;
const char *outfile, *ttyfile;
Apr *apr;
Ptr *ptr;
Ptp *ptp;
Tty *tty;
outfile = "/dev/null";
ttyfile = "/tmp/6tty";
ARGBEGIN{
@ -670,22 +681,23 @@ main(int argc, char *argv[])
extra_l = e; e += 1;
initapr(&apr);
aprs[0] = apr = makeapr();
coremems[0] = makecoremem("mem_0");
coremems[1] = makecoremem("mem_1");
coremems[2] = makecoremem("mem_2");
coremems[3] = makecoremem("mem_3");
attachmem(makefastmem(0), 0, &apr.membus, -1);
attachmem(coremems[0], 0, &apr.membus, 0);
attachmem(coremems[1], 0, &apr.membus, 1);
attachmem(coremems[2], 0, &apr.membus, 2);
attachmem(coremems[3], 0, &apr.membus, 3);
inittty(&tty, &apr.iobus);
initptr(&ptr, &apr.iobus);
initptp(&ptp, &apr.iobus);
attachmem(makefastmem(0), 0, &apr->membus, -1);
attachmem(coremems[0], 0, &apr->membus, 0);
attachmem(coremems[1], 0, &apr->membus, 1);
attachmem(coremems[2], 0, &apr->membus, 2);
attachmem(coremems[3], 0, &apr->membus, 3);
tty = maketty(&apr->iobus);
ptr = makeptr(&apr->iobus);
ptp = makeptp(&apr->iobus);
if(ttyfile)
attachdevtty(&tty, ttyfile);
showmem(&apr.membus);
attachdevtty(tty, ttyfile);
pthread_create(&cmd_thread, nil, cmdthread, nil);
for(;;){
start = SDL_GetTicks();
@ -701,13 +713,12 @@ main(int argc, char *argv[])
mouse(mbev->button, mbev->state, mbev->x, mbev->y);
break;
case SDL_QUIT:
SDL_Quit();
return 0;
quit(0);
}
updateapr(&apr, &ptr);
updatetty(&tty);
updatept(&ptp, &ptr);
updateapr(apr, ptr);
updatetty(tty);
updatept(ptp, ptr);
SDL_FillRect(screen, nil, SDL_MapRGBA(screen->format, 0xe6, 0xe6, 0xe6, 0xff));
SDL_BlitSurface(indpanel1.surf, nil, screen, &indpanel1.pos);
@ -717,11 +728,11 @@ main(int argc, char *argv[])
SDL_BlitSurface(oppanel.surf, nil, screen, &oppanel.pos);
for(i = 0, e = lamps; i < nelem(lamps); i++, e++)
drawelement(screen, e, apr.sw_power);
drawelement(screen, e, apr->sw_power);
for(i = 0, e = keys; i < nelem(keys); i++, e++)
drawelement(screen, e, apr.sw_power);
drawelement(screen, e, apr->sw_power);
for(i = 0, e = switches; i < nelem(switches); i++, e++)
drawelement(screen, e, apr.sw_power);
drawelement(screen, e, apr->sw_power);
// SDL_LockSurface(screen);
// drawgrid(&opgrid1, screen, 0xFFFFFF00);

View File

@ -239,6 +239,7 @@ makecoremem(const char *file)
Mem *mem;
core = malloc(sizeof(CMem));
memset(core, 0, sizeof(CMem));
core->filename = file;
pthread_mutex_init(&core->mutex, nil);
@ -303,6 +304,23 @@ showmem(Membus *bus)
for(i = 0; i < 16; i++)
if(bus->cmem[i]){
core = bus->cmem[i]->module;
printf("%06o %06o %s\n", i<<14, (i+1 << 14)-1, core->filename);
printf("%s: %06o %06o\n", core->filename, i<<14, (i+1 << 14)-1);
}
}
word*
getmemref(Membus *bus, hword addr, int fastmem)
{
CMem *core;
FMem *ff;
if(fastmem && addr < 020 && bus->fmem){
ff = bus->fmem->module;
return &ff->ff[addr];
}
if(bus->cmem[addr>>14]){
core = bus->cmem[addr>>14]->module;
return &core->core[addr & 037777];
}
return nil;
}

View File

@ -3,16 +3,16 @@
#include <stdint.h>
#include <stdarg.h>
#include <string.h>
#include <ctype.h>
#include <assert.h>
#include <pthread.h>
#include "../tools/pdp6common.h"
#define nelem(a) (sizeof(a)/sizeof(a[0]))
#define nil NULL
#define print printf
#define fprint fprintf
typedef uint64_t word;
typedef uint32_t hword;
typedef uint32_t u32;
typedef uint16_t u16;
typedef int8_t i8;
@ -25,6 +25,9 @@ extern int dotrace;
void trace(char *fmt, ...);
void debug(char *fmt, ...);
void quit(int code);
void *cmdthread(void *);
enum {
MAXPULSE = 5
};
@ -203,6 +206,7 @@ Mem *makecoremem(const char *file);
void attachmem(Mem *mem, int p, Membus *bus, int n);
void readmem(const char *file, word *mem, word size);
void showmem(Membus *bus);
word *getmemref(Membus *bus, hword addr, int fastmem);
/*
* IO bus
@ -395,7 +399,8 @@ struct Apr
Pulse **clist, **nlist;
int ncurpulses, nnextpulses;
};
void initapr(Apr *apr);
extern Apr *aprs[4];
Apr *makeapr(void);
void curpulse(Apr *apr, Pulse *p);
void nextpulse(Apr *apr, Pulse *p);
void *aprmain(void *p);
@ -414,7 +419,7 @@ struct Ptp
FILE *fp;
int waitdatao;
};
void initptp(Ptp *ptp, IOBus *bus);
Ptp *makeptp(IOBus *bus);
/* Paper tape reader 760 */
@ -431,7 +436,7 @@ struct Ptr
FILE *fp;
};
void initptr(Ptr *ptr, IOBus *bus);
Ptr *makeptr(IOBus *bus);
void ptr_setmotor(Ptr *ptr, int m);
@ -447,7 +452,7 @@ struct Tty
int pia;
int fd;
};
void inittty(Tty *tty, IOBus *bus);
Tty *maketty(IOBus *bus);
void attachdevtty(Tty *tty, const char *path);

View File

@ -190,21 +190,30 @@ ptr_setmotor(Ptr *ptr, int m)
recalc_ptr_req(ptr);
}
void
initptp(Ptp *ptp, IOBus *bus)
Ptp*
makeptp(IOBus *bus)
{
pthread_t thread_id;
Ptp *ptp;
ptp = malloc(sizeof(Ptp));
memset(ptp, 0, sizeof(Ptp));
ptp->bus = bus;
bus->dev[PTP] = (Busdev){ ptp, wake_ptp, 0 };
pthread_create(&thread_id, nil, ptpthread, ptp);
ptp->fp = fopen("../code/ptp.out", "wb");
return ptp;
}
void
initptr(Ptr *ptr, IOBus *bus)
Ptr*
makeptr(IOBus *bus)
{
pthread_t thread_id;
Ptr *ptr;
ptr = malloc(sizeof(Ptr));
memset(ptr, 0, sizeof(Ptr));
ptr->bus = bus;
bus->dev[PTR] = (Busdev){ ptr, wake_ptr, 0 };
pthread_create(&thread_id, nil, ptrthread, ptr);

View File

@ -120,12 +120,17 @@ fail:
fprintf(stderr, "couldn't open tty %s\n", path);
}
void
inittty(Tty *tty, IOBus *bus)
Tty*
maketty(IOBus *bus)
{
pthread_t thread_id;
Tty *tty;
tty = malloc(sizeof(Tty));
memset(tty, 0, sizeof(Tty));
tty->fd = -1;
tty->bus = bus;
bus->dev[TTY] = (Busdev){ tty, wake_tty, 0 };
pthread_create(&thread_id, nil, ttythread, tty);
return tty;
}

1329
misc/as6.c

File diff suppressed because it is too large Load Diff