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:
parent
3197705f49
commit
a2de61d375
@ -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
|
||||
|
||||
|
||||
@ -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
377
emu/cmd.c
Normal 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;
|
||||
}
|
||||
57
emu/main.c
57
emu/main.c
@ -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);
|
||||
|
||||
20
emu/mem.c
20
emu/mem.c
@ -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;
|
||||
}
|
||||
|
||||
17
emu/pdp6.h
17
emu/pdp6.h
@ -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);
|
||||
|
||||
|
||||
|
||||
17
emu/pt.c
17
emu/pt.c
@ -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);
|
||||
|
||||
@ -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
1329
misc/as6.c
File diff suppressed because it is too large
Load Diff
Loading…
x
Reference in New Issue
Block a user