OpenCores
URL https://opencores.org/ocsvn/eco32/eco32/trunk

Subversion Repositories eco32

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /eco32/trunk
    from Rev 245 to Rev 246
    Reverse comparison

Rev 245 → Rev 246

/sim/term.h File deleted
/sim/term.c File deleted
/sim/serial.c
0,0 → 1,314
/*
* serial.c -- serial line simulation
*/
 
 
#ifdef __linux__
#define _XOPEN_SOURCE
#endif
 
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <setjmp.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <fcntl.h>
#include <termios.h>
 
#include "common.h"
#include "console.h"
#include "error.h"
#include "except.h"
#include "cpu.h"
#include "timer.h"
#include "serial.h"
 
 
/**************************************************************/
 
 
static Bool debug = false;
 
 
typedef struct {
pid_t pid;
FILE *in;
FILE *out;
Word rcvrCtrl;
Word rcvrData;
int rcvrIRQ;
Word xmtrCtrl;
Word xmtrData;
int xmtrIRQ;
} Serial;
 
 
static Serial serials[MAX_NSERIALS];
static int nSerials;
 
 
/**************************************************************/
 
 
static void rcvrCallback(int dev) {
int c;
 
if (debug) {
cPrintf("\n**** SERIAL RCVR CALLBACK ****\n");
}
timerStart(SERIAL_RCVR_USEC, rcvrCallback, dev);
c = fgetc(serials[dev].in);
if (c == EOF) {
/* no character typed */
return;
}
/* any character typed */
serials[dev].rcvrData = c & 0xFF;
serials[dev].rcvrCtrl |= SERIAL_RCVR_RDY;
if (serials[dev].rcvrCtrl & SERIAL_RCVR_IEN) {
/* raise serial line rcvr interrupt */
cpuSetInterrupt(serials[dev].rcvrIRQ);
}
}
 
 
static void xmtrCallback(int dev) {
if (debug) {
cPrintf("\n**** SERIAL XMTR CALLBACK ****\n");
}
fputc(serials[dev].xmtrData & 0xFF, serials[dev].out);
serials[dev].xmtrCtrl |= SERIAL_XMTR_RDY;
if (serials[dev].xmtrCtrl & SERIAL_XMTR_IEN) {
/* raise serial line xmtr interrupt */
cpuSetInterrupt(serials[dev].xmtrIRQ);
}
}
 
 
/**************************************************************/
 
 
Word serialRead(Word addr) {
int dev, reg;
Word data;
 
if (debug) {
cPrintf("\n**** SERIAL READ from 0x%08X", addr);
}
dev = addr >> 12;
if (dev >= nSerials) {
/* illegal device */
throwException(EXC_BUS_TIMEOUT);
}
reg = addr & 0x0FFF;
if (reg == SERIAL_RCVR_CTRL) {
data = serials[dev].rcvrCtrl;
} else
if (reg == SERIAL_RCVR_DATA) {
serials[dev].rcvrCtrl &= ~SERIAL_RCVR_RDY;
if (serials[dev].rcvrCtrl & SERIAL_RCVR_IEN) {
/* lower serial line rcvr interrupt */
cpuResetInterrupt(serials[dev].rcvrIRQ);
}
data = serials[dev].rcvrData;
} else
if (reg == SERIAL_XMTR_CTRL) {
data = serials[dev].xmtrCtrl;
} else
if (reg == SERIAL_XMTR_DATA) {
/* this register is write-only */
throwException(EXC_BUS_TIMEOUT);
} else {
/* illegal register */
throwException(EXC_BUS_TIMEOUT);
}
if (debug) {
cPrintf(", data = 0x%08X ****\n", data);
}
return data;
}
 
 
void serialWrite(Word addr, Word data) {
int dev, reg;
 
if (debug) {
cPrintf("\n**** SERIAL WRITE to 0x%08X, data = 0x%08X ****\n",
addr, data);
}
dev = addr >> 12;
if (dev >= nSerials) {
/* illegal device */
throwException(EXC_BUS_TIMEOUT);
}
reg = addr & 0x0FFF;
if (reg == SERIAL_RCVR_CTRL) {
if (data & SERIAL_RCVR_IEN) {
serials[dev].rcvrCtrl |= SERIAL_RCVR_IEN;
} else {
serials[dev].rcvrCtrl &= ~SERIAL_RCVR_IEN;
}
if (data & SERIAL_RCVR_RDY) {
serials[dev].rcvrCtrl |= SERIAL_RCVR_RDY;
} else {
serials[dev].rcvrCtrl &= ~SERIAL_RCVR_RDY;
}
if ((serials[dev].rcvrCtrl & SERIAL_RCVR_IEN) != 0 &&
(serials[dev].rcvrCtrl & SERIAL_RCVR_RDY) != 0) {
/* raise serial line rcvr interrupt */
cpuSetInterrupt(serials[dev].rcvrIRQ);
} else {
/* lower serial line rcvr interrupt */
cpuResetInterrupt(serials[dev].rcvrIRQ);
}
} else
if (reg == SERIAL_RCVR_DATA) {
/* this register is read-only */
throwException(EXC_BUS_TIMEOUT);
} else
if (reg == SERIAL_XMTR_CTRL) {
if (data & SERIAL_XMTR_IEN) {
serials[dev].xmtrCtrl |= SERIAL_XMTR_IEN;
} else {
serials[dev].xmtrCtrl &= ~SERIAL_XMTR_IEN;
}
if (data & SERIAL_XMTR_RDY) {
serials[dev].xmtrCtrl |= SERIAL_XMTR_RDY;
} else {
serials[dev].xmtrCtrl &= ~SERIAL_XMTR_RDY;
}
if ((serials[dev].xmtrCtrl & SERIAL_XMTR_IEN) != 0 &&
(serials[dev].xmtrCtrl & SERIAL_XMTR_RDY) != 0) {
/* raise serial line xmtr interrupt */
cpuSetInterrupt(serials[dev].xmtrIRQ);
} else {
/* lower serial line xmtr interrupt */
cpuResetInterrupt(serials[dev].xmtrIRQ);
}
} else
if (reg == SERIAL_XMTR_DATA) {
serials[dev].xmtrData = data & 0xFF;
serials[dev].xmtrCtrl &= ~SERIAL_XMTR_RDY;
if (serials[dev].xmtrCtrl & SERIAL_XMTR_IEN) {
/* lower serial line xmtr interrupt */
cpuResetInterrupt(serials[dev].xmtrIRQ);
}
timerStart(SERIAL_XMTR_USEC, xmtrCallback, dev);
} else {
/* illegal register */
throwException(EXC_BUS_TIMEOUT);
}
}
 
 
/**************************************************************/
 
 
void serialReset(void) {
int i;
 
cPrintf("Resetting Serial Lines...\n");
for (i = 0; i < nSerials; i++) {
serials[i].rcvrCtrl = 0;
serials[i].rcvrData = 0;
serials[i].rcvrIRQ = IRQ_SERIAL_0_RCVR + 2 * i;
timerStart(SERIAL_RCVR_USEC, rcvrCallback, i);
serials[i].xmtrCtrl = SERIAL_XMTR_RDY;
serials[i].xmtrData = 0;
serials[i].xmtrIRQ = IRQ_SERIAL_0_XMTR + 2 * i;
}
}
 
 
static void makeRaw(int fd) {
struct termios t;
 
tcgetattr(fd, &t);
t.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP|INLCR|IGNCR|ICRNL|IXON);
t.c_oflag &= ~OPOST;
t.c_lflag &= ~(ECHO|ECHONL|ICANON|ISIG|IEXTEN);
t.c_cflag &= ~(CSIZE|PARENB);
t.c_cflag |= CS8;
tcsetattr(fd, TCSANOW, &t);
}
 
 
void serialInit(int numSerials, Bool connectTerminals[]) {
int i;
int master;
char slavePath[100];
int slave;
char termTitle[100];
char termSlave[100];
 
nSerials = numSerials;
for (i = 0; i < nSerials; i++) {
/* open pseudo terminal */
master = open("/dev/ptmx", O_RDWR | O_NONBLOCK);
if (master < 0) {
error("cannot open pseudo terminal master for serial line %d", i);
}
grantpt(master);
unlockpt(master);
strcpy(slavePath, ptsname(master));
if (debug) {
cPrintf("pseudo terminal %d: master fd = %d, slave path = '%s'\n",
i, master, slavePath);
}
if (connectTerminals[i]) {
/* connect a terminal to the serial line */
/* i.e., fork and exec a new xterm process */
serials[i].pid = fork();
if (serials[i].pid < 0) {
error("cannot fork xterm process for serial line %d", i);
}
if (serials[i].pid == 0) {
/* terminal process */
setpgid(0, 0);
close(master);
/* open and configure pseudo terminal slave */
slave = open(slavePath, O_RDWR | O_NONBLOCK);
if (slave < 0) {
error("cannot open pseudo terminal slave '%s'\n", slavePath);
}
makeRaw(slave);
/* exec xterm */
sprintf(termTitle, "ECO32 Terminal %d", i);
sprintf(termSlave, "-Sab%d", slave);
execlp("xterm", "xterm", "-title", termTitle, termSlave, NULL);
error("cannot exec xterm process for serial line %d", i);
}
} else {
/* leave serial line unconnected */
serials[i].pid = 0;
cPrintf("Serial line %d can be accessed by opening device '%s'.\n",
i, slavePath);
}
fcntl(master, F_SETFL, O_NONBLOCK);
serials[i].in = fdopen(master, "r");
setvbuf(serials[i].in, NULL, _IONBF, 0);
serials[i].out = fdopen(master, "w");
setvbuf(serials[i].out, NULL, _IONBF, 0);
if (connectTerminals[i]) {
/* skip the window id written by xterm */
while (fgetc(serials[i].in) != '\n') ;
}
}
serialReset();
}
 
 
void serialExit(void) {
int i;
 
/* kill and wait for all xterm processes */
for (i = 0; i < nSerials; i++) {
if (serials[i].pid > 0) {
kill(serials[i].pid, SIGKILL);
waitpid(serials[i].pid, NULL, 0);
}
}
}
/sim/serial.h
0,0 → 1,32
/*
* serial.h -- serial line simulation
*/
 
 
#ifndef _SERIAL_H_
#define _SERIAL_H_
 
 
#define SERIAL_RCVR_CTRL 0 /* receiver control register */
#define SERIAL_RCVR_DATA 4 /* receiver data register */
#define SERIAL_XMTR_CTRL 8 /* transmitter control register */
#define SERIAL_XMTR_DATA 12 /* transmitter data register */
 
#define SERIAL_RCVR_RDY 0x01 /* receiver has a character */
#define SERIAL_RCVR_IEN 0x02 /* enable receiver interrupt */
#define SERIAL_RCVR_USEC 2000 /* input checking interval */
 
#define SERIAL_XMTR_RDY 0x01 /* transmitter accepts a character */
#define SERIAL_XMTR_IEN 0x02 /* enable transmitter interrupt */
#define SERIAL_XMTR_USEC 1042 /* output speed */
 
 
Word serialRead(Word addr);
void serialWrite(Word addr, Word data);
 
void serialReset(void);
void serialInit(int numSerials, Bool connectTerminals[]);
void serialExit(void);
 
 
#endif /* _SERIAL_H_ */
/sim/error.c
16,7 → 16,7
#include "memory.h"
#include "timer.h"
#include "dspkbd.h"
#include "term.h"
#include "serial.h"
#include "disk.h"
#include "output.h"
#include "shutdown.h"
32,7 → 32,7
timerExit();
displayExit();
keyboardExit();
termExit();
serialExit();
diskExit();
outputExit();
shutdownExit();
/sim/cpu.h
7,14 → 7,14
#define _CPU_H_
 
 
#define IRQ_TIMER_1 15 /* timer 1 interrupt */
#define IRQ_TIMER_0 14 /* timer 0 interrupt */
#define IRQ_DISK 8 /* disk interrupt */
#define IRQ_KEYBOARD 4 /* keyboard interrupt */
#define IRQ_TERM_1_RCVR 3 /* terminal 1 receiver interrupt */
#define IRQ_TERM_1_XMTR 2 /* terminal 1 transmitter interrupt */
#define IRQ_TERM_0_RCVR 1 /* terminal 0 receiver interrupt */
#define IRQ_TERM_0_XMTR 0 /* terminal 0 transmitter interrupt */
#define IRQ_TIMER_1 15 /* timer 1 interrupt */
#define IRQ_TIMER_0 14 /* timer 0 interrupt */
#define IRQ_DISK 8 /* disk interrupt */
#define IRQ_KEYBOARD 4 /* keyboard interrupt */
#define IRQ_SERIAL_1_RCVR 3 /* line 1 receiver interrupt */
#define IRQ_SERIAL_1_XMTR 2 /* line 1 transmitter interrupt */
#define IRQ_SERIAL_0_RCVR 1 /* line 0 receiver interrupt */
#define IRQ_SERIAL_0_XMTR 0 /* line 0 transmitter interrupt */
 
#define PSW_V 0x08000000 /* interrupt vector bit in PSW */
#define PSW_UM 0x04000000 /* user mode enable bit in PSW */
/sim/Makefile
11,8 → 11,8
 
SRCS = main.c console.c error.c except.c command.c \
instr.c asm.c disasm.c cpu.c mmu.c memory.c \
timer.c dspkbd.c term.c disk.c output.c shutdown.c \
graph.c
timer.c dspkbd.c serial.c disk.c output.c \
shutdown.c graph.c
OBJS = $(patsubst %.c,%.o,$(SRCS))
BIN = sim
 
/sim/memory.c
16,7 → 16,7
#include "memory.h"
#include "timer.h"
#include "dspkbd.h"
#include "term.h"
#include "serial.h"
#include "disk.h"
#include "output.h"
#include "shutdown.h"
63,8 → 63,8
data = keyboardRead(pAddr & IO_REG_MASK);
return data;
}
if ((pAddr & IO_DEV_MASK) == TERM_BASE) {
data = termRead(pAddr & IO_REG_MASK);
if ((pAddr & IO_DEV_MASK) == SERIAL_BASE) {
data = serialRead(pAddr & IO_REG_MASK);
return data;
}
if ((pAddr & IO_DEV_MASK) == DISK_BASE) {
153,8 → 153,8
keyboardWrite(pAddr & IO_REG_MASK, data);
return;
}
if ((pAddr & IO_DEV_MASK) == TERM_BASE) {
termWrite(pAddr & IO_REG_MASK, data);
if ((pAddr & IO_DEV_MASK) == SERIAL_BASE) {
serialWrite(pAddr & IO_REG_MASK, data);
return;
}
if ((pAddr & IO_DEV_MASK) == DISK_BASE) {
/sim/shutdown.c
15,7 → 15,7
#include "memory.h"
#include "timer.h"
#include "dspkbd.h"
#include "term.h"
#include "serial.h"
#include "disk.h"
#include "output.h"
#include "shutdown.h"
36,7 → 36,7
timerExit();
displayExit();
keyboardExit();
termExit();
serialExit();
diskExit();
outputExit();
shutdownExit();
/sim/command.c
20,7 → 20,7
#include "memory.h"
#include "timer.h"
#include "dspkbd.h"
#include "term.h"
#include "serial.h"
#include "disk.h"
#include "output.h"
#include "shutdown.h"
855,7 → 855,7
timerReset();
displayReset();
keyboardReset();
termReset();
serialReset();
diskReset();
outputReset();
shutdownReset();
/sim/main.c
17,7 → 17,7
#include "memory.h"
#include "timer.h"
#include "dspkbd.h"
#include "term.h"
#include "serial.h"
#include "disk.h"
#include "output.h"
#include "shutdown.h"
34,9 → 34,9
fprintf(stderr, " [-r <rom>] set ROM image file name\n");
fprintf(stderr, " [-d <disk>] set disk image file name\n");
fprintf(stderr, " [-s <n>] install n serial lines (0-%d)\n",
MAX_NTERMS);
MAX_NSERIALS);
fprintf(stderr, " [-t <k>] connect terminal to line k (0-%d)\n",
MAX_NTERMS - 1);
MAX_NSERIALS - 1);
fprintf(stderr, " [-g] install graphics controller\n");
fprintf(stderr, " [-c] install console\n");
fprintf(stderr, " [-o <file>] bind output device to file\n");
58,8 → 58,8
unsigned int loadAddr;
char *romName;
char *diskName;
int numTerms;
Bool hasTerm[MAX_NTERMS];
int numSerials;
Bool connectTerminals[MAX_NSERIALS];
Bool graphics;
Bool console;
char *outputName;
73,9 → 73,9
loadAddr = 0;
romName = NULL;
diskName = NULL;
numTerms = 0;
for (j = 0; j < MAX_NTERMS; j++) {
hasTerm[j] = false;
numSerials = 0;
for (j = 0; j < MAX_NSERIALS; j++) {
connectTerminals[j] = false;
}
graphics = false;
console = false;
132,10 → 132,10
if (i == argc - 1) {
usage(argv[0]);
}
numTerms = strtol(argv[++i], &endp, 10);
numSerials = strtol(argv[++i], &endp, 10);
if (*endp != '\0' ||
numTerms < 0 ||
numTerms > MAX_NTERMS) {
numSerials < 0 ||
numSerials > MAX_NSERIALS) {
usage(argv[0]);
}
break;
146,10 → 146,10
j = strtol(argv[++i], &endp, 10);
if (*endp != '\0' ||
j < 0 ||
j > MAX_NTERMS - 1) {
j > MAX_NSERIALS - 1) {
usage(argv[0]);
}
hasTerm[j] = true;
connectTerminals[j] = true;
break;
case 'g':
graphics = true;
180,7 → 180,7
displayInit();
keyboardInit();
}
termInit(numTerms, hasTerm);
serialInit(numSerials, connectTerminals);
diskInit(diskName);
outputInit(outputName);
shutdownInit();
217,7 → 217,7
timerExit();
displayExit();
keyboardExit();
termExit();
serialExit();
diskExit();
outputExit();
shutdownExit();
/sim/common.h
26,8 → 26,8
#define TIMER_BASE 0x30000000 /* physical timer base address */
#define DISPLAY_BASE 0x30100000 /* physical display base address */
#define KEYBOARD_BASE 0x30200000 /* physical keyboard base address */
#define TERM_BASE 0x30300000 /* physical terminal base address */
#define MAX_NTERMS 2 /* max number of terminals */
#define SERIAL_BASE 0x30300000 /* physical serial line base address */
#define MAX_NSERIALS 2 /* max number of serial lines */
#define DISK_BASE 0x30400000 /* physical disk base address */
#define OUTPUT_BASE 0x3F000000 /* physical output device address */
#define SHUTDOWN_BASE 0x3F100000 /* physical shutdown device address */

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.