mirror of
https://git.FreeBSD.org/src.git
synced 2025-01-28 16:43:09 +00:00
- First shot at PIC emulation;
- better 8250 emulation; - fake vertical retrace bit in Input Status #1 register (this was lost in the VGA emu rewrite). Submitted by: Igor Serikov <bt@turtle.pangeatech.com>
This commit is contained in:
parent
4238458ba2
commit
1a63d7e08e
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=84361
@ -61,7 +61,7 @@
|
||||
static fd_set fdset; /* File Descriptors to select on */
|
||||
|
||||
typedef struct {
|
||||
void (*func)(void *, regcontext_t *);
|
||||
void (*func)(int, int, void *, regcontext_t *);
|
||||
/* Function to call on data arrival */
|
||||
void (*failure)(void *); /* Function to call on failure */
|
||||
void *arg; /* Argument to above functions */
|
||||
@ -71,17 +71,13 @@ typedef struct {
|
||||
} Async;
|
||||
|
||||
static Async handlers[OPEN_MAX];
|
||||
static int in_handler = 0;
|
||||
|
||||
static void CleanIO(void);
|
||||
static void HandleIO(struct sigframe *sf);
|
||||
|
||||
void
|
||||
_RegisterIO(fd, func, arg, failure)
|
||||
int fd;
|
||||
void (*func)(void *, regcontext_t *);
|
||||
void *arg;
|
||||
void (*failure)(void *);
|
||||
_RegisterIO(int fd, void (*func)(int, int, void *, regcontext_t *),
|
||||
void *arg, void (*failure)(void *))
|
||||
{
|
||||
static int firsttime = 1;
|
||||
Async *as;
|
||||
@ -167,181 +163,99 @@ printf("Closed file descriptor %d\n", x);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
HandleIO(struct sigframe *sf)
|
||||
static void HandleIO(struct sigframe *sf)
|
||||
{
|
||||
++in_handler;
|
||||
static struct timeval tv;
|
||||
fd_set readset, writeset;
|
||||
int x, fd;
|
||||
|
||||
for (;;) {
|
||||
static struct timeval tv;
|
||||
fd_set readset;
|
||||
int x;
|
||||
int fd;
|
||||
again:
|
||||
readset = writeset = fdset;
|
||||
if ((x = select(FD_SETSIZE, &readset, &writeset, 0, &tv)) < 0) {
|
||||
/*
|
||||
* If we failed because of a BADFiledes, go find
|
||||
* which one(s), fail them out and then try a
|
||||
* new select to see if any of the good ones are
|
||||
* okay.
|
||||
*/
|
||||
if (errno == EBADF) {
|
||||
CleanIO();
|
||||
if (FD_ISZERO(&fdset))
|
||||
return;
|
||||
goto again;
|
||||
}
|
||||
perror("select");
|
||||
return;
|
||||
}
|
||||
|
||||
readset = fdset;
|
||||
if ((x = select(FD_SETSIZE, &readset, 0, 0, &tv)) < 0) {
|
||||
/*
|
||||
* If we failed becuase of a BADFiledes, go find
|
||||
* which one(s), fail them out and then try a
|
||||
* new select to see if any of the good ones are
|
||||
* okay.
|
||||
*/
|
||||
if (errno == EBADF) {
|
||||
CleanIO();
|
||||
if (FD_ISZERO(&fdset))
|
||||
break;
|
||||
continue;
|
||||
}
|
||||
perror("select");
|
||||
break;
|
||||
/*
|
||||
* If we run out of fds to look at, break out of the loop
|
||||
* and exit the handler.
|
||||
*/
|
||||
if (x == 0)
|
||||
return;
|
||||
|
||||
/*
|
||||
* If there is at least 1 fd saying it has something for
|
||||
* us, then loop through the sets looking for those
|
||||
* bits, stopping when we have handleed the number it has
|
||||
* asked for.
|
||||
*/
|
||||
for (fd = 0; x && fd < OPEN_MAX; fd ++) {
|
||||
Async *as;
|
||||
int cond;
|
||||
|
||||
cond = 0;
|
||||
|
||||
if (FD_ISSET(fd, &readset)) {
|
||||
cond |= AS_RD;
|
||||
x --;
|
||||
}
|
||||
if (FD_ISSET(fd, &writeset)) {
|
||||
cond |= AS_WR;
|
||||
x --;
|
||||
}
|
||||
|
||||
/*
|
||||
* If we run out of fds to look at, break out of the loop
|
||||
* and exit the handler.
|
||||
*/
|
||||
if (!x)
|
||||
break;
|
||||
if (cond == 0)
|
||||
continue;
|
||||
|
||||
/*
|
||||
* If there is at least 1 fd saying it has something for
|
||||
* us, then loop through the sets looking for those
|
||||
* bits, stopping when we have handleed the number it has
|
||||
* asked for.
|
||||
* Is suppose it is possible that one of the previous
|
||||
* I/O requests changed the fdset.
|
||||
* We do know that SIGIO is turned off right now,
|
||||
* so it is safe to checkit.
|
||||
*/
|
||||
for (fd = 0; x && fd < OPEN_MAX; ++fd) {
|
||||
Async *as;
|
||||
|
||||
if (!FD_ISSET(fd, &readset)) {
|
||||
continue;
|
||||
}
|
||||
--x;
|
||||
|
||||
/*
|
||||
* Is suppose it is possible that one of the previous
|
||||
* io requests changed the fdset.
|
||||
* We do know that SIGIO is turned off right now,
|
||||
* so it is safe to checkit.
|
||||
*/
|
||||
if (!FD_ISSET(fd, &fdset)) {
|
||||
continue;
|
||||
}
|
||||
as = &handlers[fd];
|
||||
|
||||
/*
|
||||
* as in above, maybe someone locked us...
|
||||
* we are in dangerous water now if we are
|
||||
* multi-tasked
|
||||
*/
|
||||
if (as->lockcnt) {
|
||||
/*@*/ fprintf(stderr, "Selected IO on locked %d\n",fd);
|
||||
continue;
|
||||
}
|
||||
/*
|
||||
* Okay, now if there exists a handler, we should
|
||||
* call it. We must turn back on SIGIO if there
|
||||
* are possibly other people waiting for it.
|
||||
*/
|
||||
if (as->func) {
|
||||
int afd;
|
||||
Async *aas;
|
||||
|
||||
/*
|
||||
* STEP 1: Lock out all "members"
|
||||
*/
|
||||
aas = handlers;
|
||||
if (0)
|
||||
for (afd = 0; afd < OPEN_MAX; ++afd, ++aas) {
|
||||
if (FD_ISSET(afd, &as->members)) {
|
||||
if (aas->func) {
|
||||
if (as->lockcnt++ == 0) {
|
||||
FD_CLR(afd, &fdset);
|
||||
CLRASYNC(afd);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* STEP 2: Renable SIGIO so other FDs can
|
||||
* use a hit.
|
||||
_UnblockIO();
|
||||
*/
|
||||
|
||||
/*
|
||||
* STEP 3: Call the handler
|
||||
*/
|
||||
(*handlers[fd].func)(handlers[fd].arg,
|
||||
(regcontext_t *)&sf->sf_uc);
|
||||
|
||||
/*
|
||||
* STEP 4: Just turn SIGIO off. No check.
|
||||
_BlockIO();
|
||||
*/
|
||||
|
||||
/*
|
||||
* STEP 5: Unlock all "members"
|
||||
*/
|
||||
aas = handlers;
|
||||
if (0)
|
||||
for (afd = 0; afd < OPEN_MAX; ++afd, ++aas) {
|
||||
if (FD_ISSET(afd, &as->members)) {
|
||||
if (aas->func) {
|
||||
if (--as->lockcnt == 0) {
|
||||
FD_SET(afd, &fdset);
|
||||
SETASYNC(afd);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/*
|
||||
* Otherwise deregister this guy.
|
||||
*/
|
||||
_RegisterIO(fd, 0, 0, 0);
|
||||
}
|
||||
if (!FD_ISSET(fd, &fdset)) {
|
||||
continue;
|
||||
}
|
||||
as = &handlers[fd];
|
||||
|
||||
/*
|
||||
* as in above, maybe someone locked us...
|
||||
* we are in dangerous water now if we are
|
||||
* multi-tasked
|
||||
*/
|
||||
if (as->lockcnt) {
|
||||
fprintf(stderr, "Selected IO on locked %d\n",fd);
|
||||
continue;
|
||||
}
|
||||
/*
|
||||
* If we did not process all the fd's, then we should
|
||||
* break out of the probable infinite loop.
|
||||
* Okay, now if there exists a handler, we should
|
||||
* call it. We must turn back on SIGIO if there
|
||||
* are possibly other people waiting for it.
|
||||
*/
|
||||
if (x) {
|
||||
break;
|
||||
if (as->func) {
|
||||
(*handlers[fd].func)(fd, cond, handlers[fd].arg,
|
||||
(regcontext_t*)&sf->sf_uc);
|
||||
} else {
|
||||
/*
|
||||
* Otherwise deregister this guy.
|
||||
*/
|
||||
_RegisterIO(fd, 0, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
--in_handler;
|
||||
}
|
||||
|
||||
static int stackp = 0;
|
||||
|
||||
void
|
||||
_BlockIO()
|
||||
{
|
||||
sigset_t set;
|
||||
|
||||
if (stackp >= 64) {
|
||||
fprintf(stderr, "Signal stack count too deep\n");
|
||||
abort();
|
||||
}
|
||||
if (stackp++ == 0) {
|
||||
sigaddset(&set, SIGIO);
|
||||
sigprocmask(SIG_BLOCK, &set, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
_UnblockIO()
|
||||
{
|
||||
sigset_t set;
|
||||
|
||||
if (stackp <= 0) {
|
||||
fprintf(stderr, "Negative signal stack count\n");
|
||||
abort();
|
||||
}
|
||||
if (--stackp == 0) {
|
||||
sigaddset(&set, SIGIO);
|
||||
sigprocmask(SIG_UNBLOCK, &set, 0);
|
||||
}
|
||||
/*
|
||||
* If we did not process all the fd's, then we should
|
||||
* break out of the probable infinite loop.
|
||||
*/
|
||||
}
|
||||
|
@ -35,17 +35,13 @@
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
void _RegisterIO(int, void (*)(void *, regcontext_t *),
|
||||
void *, void (*)(void *));
|
||||
void _AssociateIO(int, int);
|
||||
void _DeAssociateIO(int, int);
|
||||
void _LockIO(int);
|
||||
int _UnlockIO(int);
|
||||
int _LevelIO(int);
|
||||
int _DetachIO(int);
|
||||
int _EndIO(int, int);
|
||||
void _BlockIO(void);
|
||||
void _UnblockIO(void);
|
||||
enum {
|
||||
AS_RD = 1,
|
||||
AS_WR = 2
|
||||
};
|
||||
|
||||
void _RegisterIO(int, void (*)(int, int, void *, regcontext_t *),
|
||||
void *, void (*)(void *));
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
@ -34,13 +34,11 @@
|
||||
|
||||
/* com.h for doscmd int14.c */
|
||||
|
||||
#define BUFSIZE 1024
|
||||
|
||||
/* NS16550A register definitions */
|
||||
|
||||
/* interrupt enable register */
|
||||
|
||||
#define IE_NOP 0xF0 /* not used */
|
||||
#define IE_NOP 0xF0 /* Not used */
|
||||
#define IE_MODEM_STAT 0x08 /* modem status int. */
|
||||
#define IE_LINE_STAT 0x04 /* receiver-line status int. */
|
||||
#define IE_TRANS_HLD 0x02 /* transmitter holding register empty int. */
|
||||
@ -49,12 +47,13 @@
|
||||
/* interrupt identification register */
|
||||
|
||||
#define II_FIFOS_EN 0xC0 /* if FIFOs are enabled */
|
||||
#define II_NOP 0x38 /* not used */
|
||||
#define II_INT_ID 0x06 /* mask: bits see below */
|
||||
#define II_NOP 0x30 /* not used */
|
||||
#define II_INT_ID 0x0E /* mask: bits see below */
|
||||
#define II_PEND_INT 0x01 /* 1=no interrupt pending */
|
||||
|
||||
/* bit masks for II_INT_ID */
|
||||
|
||||
#define II_TO 0x0C
|
||||
#define II_LINE_STAT 0x06
|
||||
#define II_RCV_DATA 0x04
|
||||
#define II_TRANS_HLD 0x02
|
||||
@ -62,6 +61,13 @@
|
||||
|
||||
/* FIFO control reg */
|
||||
|
||||
#define FC_FIFO_SZ_MASK 0xC0
|
||||
#define FC_FIFO_1B 0x80
|
||||
#define FC_FIFO_4B 0x40
|
||||
#define FC_FIFO_8B 0x80
|
||||
#define FC_FIFO_14B 0xC0
|
||||
#define FC_FIFO_CTR 0x04
|
||||
#define FC_FIFO_CRV 0x02
|
||||
#define FC_FIFO_EN 0x01
|
||||
|
||||
/* line control register */
|
||||
@ -77,8 +83,8 @@
|
||||
/* line status register */
|
||||
|
||||
#define LS_NOP 0x80 /* not used */
|
||||
#define LS_X_SHFT_E 0x40 /* 0=data transfer, 1=transmitter idle */
|
||||
#define LS_X_HOLD_E 0x20 /* 0=ready, 1=transferring character */
|
||||
#define LS_X_DATA_E 0x40 /* 1=empty */
|
||||
#define LS_X_HOLD_E 0x20 /* 1=empty */
|
||||
#define LS_BREAK 0x10 /* break received */
|
||||
#define LS_FRM_ERR 0x08 /* framing error */
|
||||
#define LS_PAR_ERR 0x04 /* parity error */
|
||||
@ -96,31 +102,6 @@
|
||||
#define MS_DELTA_DSR 0x02 /* Data Set Ready changed state */
|
||||
#define MS_DELTA_CTS 0x01 /* Clear To Send changed state */
|
||||
|
||||
/* data structure definitions */
|
||||
|
||||
#define N_OF_COM_REGS 8
|
||||
|
||||
struct com_data_struct {
|
||||
int fd; /* BSD/386 file descriptor */
|
||||
char *path; /* BSD/386 pathname */
|
||||
int addr; /* ISA I/O address */
|
||||
unsigned char irq; /* ISA IRQ */
|
||||
unsigned char flags; /* some general software flags */
|
||||
|
||||
struct queue *com_queue; /* XXX DEBUG obsolete MCL? */
|
||||
|
||||
unsigned char div_latch[2]; /* mirror of 16550 R0':R1' read/write */
|
||||
unsigned char last_char_read; /* mirror of 16550 R0 read only */
|
||||
unsigned char int_enable; /* mirror of 16550 R1 read/write */
|
||||
unsigned char int_id; /* mirror of 16550 R2 read only */
|
||||
unsigned char fifo_ctrl; /* mirror of 16550 R2 write only */
|
||||
unsigned char line_ctrl; /* mirror of 16550 R3 read/write */
|
||||
unsigned char modem_ctrl; /* mirror of 16550 R4 read/write */
|
||||
unsigned char line_stat; /* mirror of 16550 R5 read/write */
|
||||
unsigned char modem_stat; /* mirror of 16550 R6 read/write */
|
||||
unsigned char uart_spare; /* mirror of 16550 R7 read/write */
|
||||
};
|
||||
|
||||
/* DOS definitions -- parameters */
|
||||
|
||||
#define BITRATE_110 0x00
|
||||
@ -139,25 +120,15 @@ struct com_data_struct {
|
||||
#define TXLEN_7BITS 0x02
|
||||
#define TXLEN_8BITS 0x03
|
||||
|
||||
#define N_OF_COM_REGS 8
|
||||
|
||||
/* DOS definitions -- return codes */
|
||||
|
||||
#define LS_SW_TIME_OUT LS_NOP /* return value used by DOS */
|
||||
|
||||
/* miscellaneous definitions */
|
||||
|
||||
#define DIV_LATCH_LOW 0
|
||||
#define DIV_LATCH_HIGH 1
|
||||
|
||||
#define DIV_LATCH_LOW_WRITTEN 0x01
|
||||
#define DIV_LATCH_HIGH_WRITTEN 0x02
|
||||
#define DIV_LATCH_BOTH_WRITTEN 0x03
|
||||
|
||||
/* routine declarations */
|
||||
|
||||
void int14(regcontext_t *REGS);
|
||||
void com_set_line(struct com_data_struct *, unsigned char, unsigned char);
|
||||
void init_com(int, char *, int, unsigned char);
|
||||
u_char com_port_in(int);
|
||||
void com_port_out(int, unsigned char);
|
||||
|
||||
/* end of file com.h */
|
||||
|
@ -221,8 +221,8 @@ read_config(FILE *fp)
|
||||
errno = 0;
|
||||
irq = (unsigned char)strtol(av[4], '\0', 0);
|
||||
/* XXX DEBUG ISA-specific */
|
||||
if ((errno != 0) || (irq < 1) || (irq > 15)) {
|
||||
fprintf(stderr, "Usage: assign com[1-4] path addr irq\n");
|
||||
if ((errno != 0) || (irq < 2) || (irq > 7)) {
|
||||
fprintf(stderr, "Usage: assign com[1-4] path addr irq[2-7]\n");
|
||||
quit(1);
|
||||
}
|
||||
init_com(port, av[2], addr, irq);
|
||||
|
@ -69,9 +69,6 @@ int timer_disable = 0;
|
||||
struct timeval boot_time;
|
||||
unsigned long *ivec = (unsigned long *)0;
|
||||
|
||||
u_long pending[256]; /* pending interrupts */
|
||||
int n_pending;
|
||||
|
||||
#ifndef USE_VM86
|
||||
#define PRB_V86_FORMAT 0x4242
|
||||
|
||||
@ -118,6 +115,14 @@ main(int argc, char **argv)
|
||||
regcontext_t *REGS = (regcontext_t *)&uc.uc_mcontext;
|
||||
int fd;
|
||||
int i;
|
||||
sigset_t sigset;
|
||||
|
||||
sigemptyset(&sigset);
|
||||
sigaddset(&sigset, SIGIO);
|
||||
sigaddset(&sigset, SIGALRM);
|
||||
sigprocmask(SIG_BLOCK, &sigset, 0);
|
||||
|
||||
init_ints();
|
||||
|
||||
debugf = stderr;
|
||||
/* XXX should only be for tty mode */
|
||||
@ -194,9 +199,6 @@ main(int argc, char **argv)
|
||||
}
|
||||
}
|
||||
#endif
|
||||
for (i = 0; i < 256; i++)
|
||||
pending[i] = 0;
|
||||
n_pending = 0;
|
||||
|
||||
if (booting) { /* are we booting? */
|
||||
setup_boot(REGS);
|
||||
|
@ -202,11 +202,14 @@ extern int i386dis(unsigned short, unsigned short,
|
||||
unsigned char *, char *, int);
|
||||
|
||||
/* int.c */
|
||||
extern void softint(int intnum);
|
||||
extern void hardint(int intnum);
|
||||
|
||||
extern void delay_interrupt(int intnum, void (*func)(int));
|
||||
extern void resume_interrupt(void);
|
||||
void init_ints(void);
|
||||
int isinhardint(int);
|
||||
void softint(int);
|
||||
void hardint(int);
|
||||
void resume_interrupt(void);
|
||||
void unpend(int);
|
||||
void send_eoi(void);
|
||||
void set_eoir(int, void (*)(void *), void *);
|
||||
|
||||
/* int10.c */
|
||||
extern void int10(regcontext_t *);
|
||||
@ -300,9 +303,4 @@ extern void initHMA(void);
|
||||
extern void xms_init(void);
|
||||
extern u_long xms_maxsize;
|
||||
|
||||
/****************************** dirty below here *****************************/
|
||||
|
||||
extern u_long pending[]; /* pending interrupts */
|
||||
extern int n_pending;
|
||||
|
||||
extern int nmice;
|
||||
/****************************** dirty below here *****************************/extern int nmice;
|
||||
|
@ -3,8 +3,199 @@
|
||||
**
|
||||
** $FreeBSD$
|
||||
*/
|
||||
|
||||
/*
|
||||
* Notes:
|
||||
* 1) Second PIC is not implemented.
|
||||
* 2) Interrupt priority management is not implemented.
|
||||
* 3) What should be read from port 0x20?
|
||||
*
|
||||
* "within interrupt processing" means the following is true:
|
||||
* 1) Hardware interrupt <irql> is delivered by hardint().
|
||||
* 2) Next interrupt <irql> is not possible yet by either:
|
||||
* a) V_IF;
|
||||
* b) Interrupt mask;
|
||||
* c) Current irql.
|
||||
*
|
||||
* Related functions:
|
||||
* int isinhardint(int irql)
|
||||
* void set_eoir(int irql, void(*eoir)(void*), void* arg);
|
||||
*
|
||||
*/
|
||||
|
||||
#include "doscmd.h"
|
||||
|
||||
struct IRQ {
|
||||
int pending;
|
||||
int busy;
|
||||
int within;
|
||||
void (*eoir) (void* arg);
|
||||
void* arg;
|
||||
};
|
||||
|
||||
static unsigned char IM;
|
||||
static int Irql;
|
||||
static struct IRQ Irqs[8];
|
||||
|
||||
#define int_allowed(n) ((IM & 1 << (n)) == 0 && Irql > (n))
|
||||
|
||||
void
|
||||
set_eoir(int irql, void(*eoir)(void*), void* arg)
|
||||
{
|
||||
Irqs [irql].eoir = eoir;
|
||||
Irqs [irql].arg = arg;
|
||||
}
|
||||
|
||||
int
|
||||
isinhardint(int irql)
|
||||
{
|
||||
return Irqs[irql].within;
|
||||
}
|
||||
|
||||
static void
|
||||
set_vip(void)
|
||||
{
|
||||
regcontext_t *REGS = saved_regcontext;
|
||||
int irql;
|
||||
|
||||
if (R_EFLAGS & PSL_VIF) {
|
||||
R_EFLAGS &= ~PSL_VIP;
|
||||
return;
|
||||
}
|
||||
|
||||
for (irql = 0; irql < 8; irql ++)
|
||||
if (int_allowed(irql) && (Irqs[irql].within || Irqs[irql].pending)) {
|
||||
R_EFLAGS |= PSL_VIP;
|
||||
return;
|
||||
}
|
||||
|
||||
R_EFLAGS &= ~PSL_VIP;
|
||||
}
|
||||
|
||||
void
|
||||
resume_interrupt(void)
|
||||
{
|
||||
regcontext_t *REGS = saved_regcontext;
|
||||
int irql;
|
||||
|
||||
if (R_EFLAGS & PSL_VIF) {
|
||||
for (irql = 0; irql < 8; irql ++)
|
||||
if (Irqs[irql].within && int_allowed(irql)) {
|
||||
Irqs[irql].within = 0;
|
||||
if (Irqs[irql].eoir)
|
||||
Irqs[irql].eoir(Irqs[irql].arg);
|
||||
}
|
||||
|
||||
for (irql = 0; irql < 8; irql ++)
|
||||
if (Irqs[irql].pending && int_allowed(irql)) {
|
||||
Irqs[irql].pending = 0;
|
||||
hardint(irql);
|
||||
break;
|
||||
}
|
||||
}
|
||||
set_vip();
|
||||
}
|
||||
|
||||
void
|
||||
send_eoi(void)
|
||||
{
|
||||
if (Irql >= 8)
|
||||
return;
|
||||
|
||||
Irqs[Irql].busy = 0;
|
||||
|
||||
while (++Irql < 8)
|
||||
if (Irqs [Irql].busy)
|
||||
break;
|
||||
|
||||
resume_interrupt();
|
||||
}
|
||||
|
||||
/*
|
||||
** Cause a hardware interrupt to happen immediately after
|
||||
** we return to vm86 mode
|
||||
*/
|
||||
void
|
||||
hardint(int irql)
|
||||
{
|
||||
regcontext_t *REGS = saved_regcontext;
|
||||
u_long vec = ivec[8 + irql];
|
||||
|
||||
/*
|
||||
** if we're dead, or there's no vector, or the saved registers
|
||||
** are invalid
|
||||
*/
|
||||
if (dead || !saved_valid || vec == 0)
|
||||
return;
|
||||
|
||||
/*
|
||||
** if the vector points into the BIOS, or the handler at the
|
||||
** other end is just an IRET, don't bother
|
||||
*/
|
||||
if ((vec >> 16) == 0xf000 || *(u_char *)VECPTR(vec) == 0xcf)
|
||||
return;
|
||||
|
||||
if (!int_allowed (irql)) {
|
||||
Irqs[irql].pending = 1;
|
||||
return;
|
||||
}
|
||||
|
||||
if ((R_EFLAGS & PSL_VIF) == 0) {
|
||||
Irqs[irql].pending = 1;
|
||||
R_EFLAGS |= PSL_VIP;
|
||||
return;
|
||||
}
|
||||
|
||||
debug(D_TRAPS | (8 + irql), "Int%02x [%04lx:%04lx]\n",
|
||||
8 + irql, vec >> 16, vec & 0xffff);
|
||||
|
||||
Irql = irql;
|
||||
Irqs[Irql].busy = 1;
|
||||
if (Irqs[Irql].eoir)
|
||||
Irqs[Irql].within = 1;
|
||||
|
||||
PUSH((R_FLAGS & ~PSL_I) | (R_EFLAGS & PSL_VIF ? PSL_I : 0), REGS);
|
||||
PUSH(R_CS, REGS);
|
||||
PUSH(R_IP, REGS);
|
||||
R_EFLAGS &= ~PSL_VIF; /* XXX disable interrupts */
|
||||
PUTVEC(R_CS, R_IP, vec);
|
||||
}
|
||||
|
||||
void
|
||||
unpend(int irql)
|
||||
{
|
||||
if (!Irqs[irql].pending)
|
||||
return;
|
||||
Irqs[irql].pending = 0;
|
||||
set_vip();
|
||||
}
|
||||
|
||||
static unsigned char
|
||||
irqc_in(int port)
|
||||
{
|
||||
return 0x60; /* What should be here? */
|
||||
}
|
||||
|
||||
static void
|
||||
irqc_out(int port, unsigned char val)
|
||||
{
|
||||
if (val == 0x20)
|
||||
send_eoi();
|
||||
}
|
||||
|
||||
static unsigned char
|
||||
imr_in(int port)
|
||||
{
|
||||
return IM;
|
||||
}
|
||||
|
||||
static void
|
||||
imr_out(int port, unsigned char val)
|
||||
{
|
||||
IM = val;
|
||||
resume_interrupt();
|
||||
}
|
||||
|
||||
/*
|
||||
** Cause a software interrupt to happen immediately after we
|
||||
** return to vm86 mode
|
||||
@ -29,111 +220,32 @@ softint(int intnum)
|
||||
if ((vec >> 16) == 0xf000 || *(u_char *)VECPTR(vec) == 0xcf)
|
||||
return;
|
||||
|
||||
#if 0
|
||||
/*
|
||||
* software interrupts are always taken
|
||||
*/
|
||||
if ((R_EFLAGS & PSL_VIF) == 0) {
|
||||
delay_interrupt(intnum, softint);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
debug(D_TRAPS|intnum, "INT%x [%04lx:%04lx]\n",
|
||||
debug(D_TRAPS | intnum, "INT %02x [%04lx:%04lx]\n",
|
||||
intnum, vec >> 16, vec & 0xffff);
|
||||
|
||||
PUSH((R_FLAGS & ~PSL_I) | (R_EFLAGS & PSL_VIF ? PSL_I : 0), REGS);
|
||||
PUSH(R_CS, REGS);
|
||||
PUSH(R_IP, REGS);
|
||||
#if 1
|
||||
R_EFLAGS &= ~PSL_VIF; /* XXX disable interrupts? */
|
||||
#else
|
||||
R_EFLAGS |= PSL_VIF;
|
||||
#endif
|
||||
PUTVEC(R_CS, R_IP, vec);
|
||||
}
|
||||
|
||||
/*
|
||||
** Cause a hardware interrupt to happen immediately after
|
||||
** we return to vm86 mode
|
||||
*/
|
||||
void
|
||||
hardint(int intnum)
|
||||
{
|
||||
regcontext_t *REGS = saved_regcontext;
|
||||
u_long vec = ivec[intnum];
|
||||
|
||||
/*
|
||||
* XXXXX
|
||||
* We should simulate the IRQ mask in the PIC.
|
||||
*/
|
||||
|
||||
/*
|
||||
** if we're dead, or there's no vector, or the saved registers
|
||||
** are invalid
|
||||
*/
|
||||
if (dead || !saved_valid || vec == 0)
|
||||
return;
|
||||
|
||||
/*
|
||||
** if the vector points into the BIOS, or the handler at the
|
||||
** other end is just an IRET, don't bother
|
||||
*/
|
||||
if ((vec >> 16) == 0xf000 || *(u_char *)VECPTR(vec) == 0xcf)
|
||||
return;
|
||||
|
||||
if ((R_EFLAGS & PSL_VIF) == 0) {
|
||||
delay_interrupt(intnum, hardint);
|
||||
return;
|
||||
}
|
||||
|
||||
debug(D_TRAPS|intnum, "INT%x [%04lx:%04lx]\n",
|
||||
intnum, vec >> 16, vec & 0xffff);
|
||||
|
||||
PUSH((R_FLAGS & ~PSL_I) | (R_EFLAGS & PSL_VIF ? PSL_I : 0), REGS);
|
||||
PUSH(R_CS, REGS);
|
||||
PUSH(R_IP, REGS);
|
||||
#if 1
|
||||
R_EFLAGS &= ~PSL_VIF; /* XXX disable interrupts */
|
||||
#else
|
||||
R_EFLAGS |= PSL_VIF;
|
||||
#endif
|
||||
PUTVEC(R_CS, R_IP, vec);
|
||||
}
|
||||
|
||||
typedef void (*foo_t)(int);
|
||||
|
||||
void
|
||||
resume_interrupt(void)
|
||||
init_ints(void)
|
||||
{
|
||||
int i;
|
||||
regcontext_t *REGS = saved_regcontext;
|
||||
|
||||
n_pending--;
|
||||
if (n_pending == 0)
|
||||
R_EFLAGS &= ~PSL_VIP;
|
||||
|
||||
for (i = 0; i < 256; i++) {
|
||||
if (pending[i]) {
|
||||
((foo_t)(pending[i]))(i);
|
||||
pending[i] = 0;
|
||||
break;
|
||||
}
|
||||
for (i = 0; i < 8; i++) {
|
||||
Irqs[i].busy = 0;
|
||||
Irqs[i].pending = 0;
|
||||
Irqs[i].within = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
delay_interrupt(int intnum, void (*func)(int))
|
||||
{
|
||||
regcontext_t *REGS = saved_regcontext;
|
||||
|
||||
#if 0
|
||||
printf("DELAY [%x/%d]\n", intnum, n_pending);
|
||||
#endif
|
||||
if (pending[intnum] == 0) {
|
||||
pending[intnum] = (u_long)func;
|
||||
n_pending++;
|
||||
}
|
||||
R_EFLAGS |= PSL_VIP;
|
||||
}
|
||||
|
||||
IM = 0x00;
|
||||
Irql = 8;
|
||||
|
||||
define_input_port_handler(0x20, irqc_in);
|
||||
define_output_port_handler(0x20, irqc_out);
|
||||
define_input_port_handler(0x21, imr_in);
|
||||
define_output_port_handler(0x21, imr_out);
|
||||
}
|
||||
|
@ -42,44 +42,221 @@
|
||||
#include <unistd.h>
|
||||
|
||||
#include "doscmd.h"
|
||||
#include "AsyncIO.h"
|
||||
#include "com.h"
|
||||
|
||||
#define N_BYTES 1024
|
||||
|
||||
struct com_data_struct {
|
||||
int fd; /* BSD/386 file descriptor */
|
||||
char *path; /* BSD/386 pathname */
|
||||
int addr; /* ISA I/O address */
|
||||
unsigned char irq; /* ISA IRQ */
|
||||
unsigned char inbuf[N_BYTES]; /* input buffer */
|
||||
unsigned char outbuf[N_BYTES];/* output buffer */
|
||||
int ids; /* input data size */
|
||||
int ods; /* output data size */
|
||||
int emptyint;
|
||||
struct termios tty;
|
||||
unsigned char div_latch[2]; /* mirror of 16550 R0':R1'
|
||||
read/write */
|
||||
unsigned char int_enable; /* mirror of 16550 R1 read/write */
|
||||
unsigned char fifo_ctrl; /* mirror of 16550 R2 write only */
|
||||
unsigned char line_ctrl; /* mirror of 16550 R3 read/write */
|
||||
unsigned char modem_ctrl; /* mirror of 16550 R4 read/write */
|
||||
unsigned char modem_stat; /* mirror of 16550 R6 read/write */
|
||||
unsigned char uart_spare; /* mirror of 16550 R7 read/write */
|
||||
};
|
||||
|
||||
#define DIV_LATCH_LOW 0
|
||||
#define DIV_LATCH_HIGH 1
|
||||
|
||||
struct com_data_struct com_data[N_COMS_MAX];
|
||||
|
||||
/* XXX where does struct queue come from? */
|
||||
static struct queue *create_queue(unsigned char);
|
||||
static int queue_not_empty(struct queue *);
|
||||
static int reset_irq_request(unsigned char);
|
||||
static int set_irq_request(unsigned char);
|
||||
static int test_irq_request(unsigned char);
|
||||
static int write_div_latches(struct com_data_struct *);
|
||||
|
||||
static struct queue *
|
||||
create_queue(unsigned char irq) { return NULL; }
|
||||
|
||||
static unsigned char com_port_in(int port);
|
||||
static void com_port_out(int port, unsigned char val);
|
||||
static void com_set_line(struct com_data_struct *cdsp,
|
||||
unsigned char port, unsigned char param);
|
||||
|
||||
static void
|
||||
manage_int(struct com_data_struct *cdsp)
|
||||
{
|
||||
if ((cdsp->int_enable & IE_RCV_DATA) && cdsp->ids > 0) {
|
||||
hardint(cdsp->irq);
|
||||
debug(D_PORT, "manage_int: hardint rd\n");
|
||||
return;
|
||||
}
|
||||
if ((cdsp->int_enable & IE_TRANS_HLD) && cdsp->emptyint) {
|
||||
hardint(cdsp->irq);
|
||||
debug(D_PORT, "manage_int: hardint wr\n");
|
||||
return;
|
||||
}
|
||||
unpend (cdsp->irq);
|
||||
}
|
||||
|
||||
static int
|
||||
queue_not_empty(struct queue *qp) {return 0;}
|
||||
|
||||
has_enough_data(struct com_data_struct *cdsp)
|
||||
{
|
||||
switch (cdsp->fifo_ctrl & (FC_FIFO_EN | FC_FIFO_SZ_MASK)) {
|
||||
case FC_FIFO_EN | FC_FIFO_4B:
|
||||
return cdsp->ids >= 4;
|
||||
case FC_FIFO_EN | FC_FIFO_8B:
|
||||
return cdsp->ids >= 8;
|
||||
case FC_FIFO_EN | FC_FIFO_14B:
|
||||
return cdsp->ids >= 14;
|
||||
}
|
||||
return cdsp->ids;
|
||||
}
|
||||
|
||||
static void
|
||||
input(struct com_data_struct *cdsp, int force_read)
|
||||
{
|
||||
int nbytes;
|
||||
|
||||
if (cdsp->ids < N_BYTES && (force_read || !has_enough_data(cdsp))) {
|
||||
nbytes = read(cdsp->fd, &cdsp->inbuf[cdsp->ids],
|
||||
N_BYTES - cdsp->ids);
|
||||
debug(D_PORT, "read of fd %d on '%s' returned %d (%s)\n",
|
||||
cdsp->fd, cdsp->path, nbytes,
|
||||
nbytes == -1 ? strerror(errno) : "");
|
||||
if (nbytes != -1)
|
||||
cdsp->ids += nbytes;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
output(struct com_data_struct *cdsp)
|
||||
{
|
||||
int nbytes;
|
||||
|
||||
if (cdsp->ods > 0) {
|
||||
nbytes = write(cdsp->fd, &cdsp->outbuf[0], cdsp->ods);
|
||||
debug(D_PORT, "write of fd %d on '%s' returned %d (%s)\n",
|
||||
cdsp->fd, cdsp->path, nbytes,
|
||||
nbytes == -1 ? strerror(errno) : "");
|
||||
if (nbytes != -1) {
|
||||
cdsp->ods -= nbytes;
|
||||
memmove (&cdsp->outbuf[0],
|
||||
&cdsp->outbuf[nbytes], cdsp->ods);
|
||||
if ((cdsp->int_enable & IE_TRANS_HLD)
|
||||
&& cdsp->ods == 0)
|
||||
cdsp->emptyint = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
flush_out(void* arg)
|
||||
{
|
||||
struct com_data_struct *cdsp = (struct com_data_struct*)arg;
|
||||
output(cdsp);
|
||||
manage_int(cdsp);
|
||||
}
|
||||
|
||||
/*
|
||||
* We postponed flush till the end of interrupt processing
|
||||
* (see int.c).
|
||||
*/
|
||||
static int
|
||||
reset_irq_request(unsigned char irq) {return 0;}
|
||||
|
||||
write_char(struct com_data_struct *cdsp, char c)
|
||||
{
|
||||
int r = 0;
|
||||
cdsp->emptyint = 0;
|
||||
if (cdsp->ods >= N_BYTES)
|
||||
output(cdsp);
|
||||
if (cdsp->ods < N_BYTES) {
|
||||
cdsp->outbuf[cdsp->ods ++] = c;
|
||||
if (!isinhardint(cdsp->irq))
|
||||
output(cdsp);
|
||||
r = 1;
|
||||
}
|
||||
manage_int(cdsp);
|
||||
return r;
|
||||
}
|
||||
|
||||
static int
|
||||
set_irq_request(unsigned char irq) {return 0;}
|
||||
|
||||
static int
|
||||
test_irq_request(unsigned char irq) {return 0;}
|
||||
|
||||
static int
|
||||
write_div_latches(struct com_data_struct *cdsp) {return 0;}
|
||||
read_char(struct com_data_struct *cdsp)
|
||||
{
|
||||
int c = -1;
|
||||
|
||||
input(cdsp, 0);
|
||||
|
||||
if (cdsp->ids > 0) {
|
||||
c = cdsp->inbuf[0];
|
||||
cdsp->ids --;
|
||||
memmove(&cdsp->inbuf[0], &cdsp->inbuf[1], cdsp->ids);
|
||||
}
|
||||
|
||||
manage_int(cdsp);
|
||||
|
||||
debug(D_PORT, "read_char: %x\n", c);
|
||||
return c;
|
||||
}
|
||||
|
||||
static void
|
||||
new_ii(struct com_data_struct *cdsp)
|
||||
{
|
||||
if ((cdsp->int_enable & IE_TRANS_HLD) && cdsp->ods == 0)
|
||||
cdsp->emptyint = 1;
|
||||
manage_int(cdsp);
|
||||
}
|
||||
|
||||
static unsigned char
|
||||
get_status(struct com_data_struct *cdsp)
|
||||
{
|
||||
unsigned char s = (LS_X_DATA_E | LS_X_HOLD_E);
|
||||
if (cdsp->ids > 0)
|
||||
s |= LS_RCV_DATA_RD;
|
||||
if (cdsp->ods > 0) {
|
||||
s &= ~LS_X_DATA_E;
|
||||
if (cdsp->ods >= N_BYTES)
|
||||
s &= ~LS_X_HOLD_E;
|
||||
}
|
||||
debug(D_PORT, "get_status: %x\n", (unsigned)s);
|
||||
return s;
|
||||
}
|
||||
|
||||
static unsigned char
|
||||
get_int_id(struct com_data_struct *cdsp)
|
||||
{
|
||||
unsigned char s = II_PEND_INT;
|
||||
if (cdsp->fifo_ctrl & FC_FIFO_EN)
|
||||
s |= II_FIFOS_EN;
|
||||
if ((cdsp->int_enable & IE_RCV_DATA) && cdsp->ids > 0) {
|
||||
if (has_enough_data(cdsp))
|
||||
s = (s & ~II_PEND_INT) | II_RCV_DATA;
|
||||
else
|
||||
s = (s & ~II_PEND_INT) | II_TO;
|
||||
} else
|
||||
if ((cdsp->int_enable & IE_TRANS_HLD) && cdsp->emptyint) {
|
||||
cdsp->emptyint = 0;
|
||||
s = (s & ~II_PEND_INT) | II_TRANS_HLD;
|
||||
}
|
||||
debug(D_PORT, "get_int_id: %x\n", (unsigned)s);
|
||||
return s;
|
||||
}
|
||||
|
||||
static void
|
||||
com_async(int fd, int cond, void *arg, regcontext_t *REGS)
|
||||
{
|
||||
struct com_data_struct *cdsp = (struct com_data_struct*) arg;
|
||||
|
||||
debug(D_PORT, "com_async: %X.\n", cond);
|
||||
|
||||
if (cond & AS_RD)
|
||||
input(cdsp, 1);
|
||||
if (cond & AS_WR)
|
||||
output(cdsp);
|
||||
manage_int(cdsp);
|
||||
}
|
||||
|
||||
void
|
||||
int14(regcontext_t *REGS)
|
||||
{
|
||||
struct com_data_struct *cdsp;
|
||||
int nbytes;
|
||||
char c;
|
||||
int i;
|
||||
|
||||
debug (D_PORT, "int14: dl = 0x%02X, al = 0x%02X.\n", R_DL, R_AL);
|
||||
debug(D_PORT, "int14: dl = 0x%02X, al = 0x%02X.\n", R_DL, R_AL);
|
||||
if (R_DL >= N_COMS_MAX) {
|
||||
if (vflag)
|
||||
dump_regs(REGS);
|
||||
@ -89,39 +266,27 @@ int14(regcontext_t *REGS)
|
||||
|
||||
switch (R_AH) {
|
||||
case 0x00: /* Initialize Serial Port */
|
||||
#if 0 /* hold off: try to defeat stupid DOS defaults */
|
||||
com_set_line(cdsp, R_DL + 1, R_AL);
|
||||
R_AH = LS_X_SHFT_E | LS_X_HOLD_E;
|
||||
R_AH = get_status(cdsp);
|
||||
R_AL = 0;
|
||||
#endif 0
|
||||
break;
|
||||
|
||||
case 0x01: /* Write Character */
|
||||
errno = 0;
|
||||
c = R_AL;
|
||||
nbytes = write(cdsp->fd, &c, 1);
|
||||
debug (D_PORT, "write of 0x%02x to fd %d on '%s' returned %d %s\n",
|
||||
R_AL, cdsp->fd, cdsp->path, nbytes, strerror(errno));
|
||||
if (nbytes == 1) {
|
||||
R_AH = LS_X_SHFT_E | LS_X_HOLD_E;
|
||||
if (write_char(cdsp, R_AL)) {
|
||||
R_AH = get_status(cdsp);
|
||||
R_AL = 0;
|
||||
} else {
|
||||
debug(D_PORT, "int14: lost output character 0x%02x\n",
|
||||
R_AL);
|
||||
debug(D_PORT, "int14: lost output character 0x%02x\n", R_AL);
|
||||
R_AH = LS_SW_TIME_OUT;
|
||||
R_AL = 0;
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x02: /* Read Character */
|
||||
errno = 0;
|
||||
nbytes = read(cdsp->fd, &c, 1);
|
||||
debug (D_PORT, "read of fd %d on '%s' returned %d byte 0x%02x %s\n",
|
||||
cdsp->fd, cdsp->path, nbytes, c,
|
||||
errno ? strerror(errno) : "");
|
||||
if (nbytes == 1) {
|
||||
R_AH = LS_X_SHFT_E | LS_X_HOLD_E;
|
||||
R_AL = c;
|
||||
i = read_char(cdsp);
|
||||
if (i != -1) {
|
||||
R_AH = get_status(cdsp);
|
||||
R_AL = (char)i;
|
||||
} else {
|
||||
R_AH = LS_SW_TIME_OUT;
|
||||
R_AL = 0x60;
|
||||
@ -129,7 +294,8 @@ int14(regcontext_t *REGS)
|
||||
break;
|
||||
|
||||
case 0x03: /* Status Request */
|
||||
R_AX = (LS_X_SHFT_E | LS_X_HOLD_E) << 8;
|
||||
R_AH = get_status(cdsp);
|
||||
R_AL = 0;
|
||||
break;
|
||||
|
||||
case 0x04: /* Extended Initialization */
|
||||
@ -159,119 +325,181 @@ int14(regcontext_t *REGS)
|
||||
|
||||
|
||||
/* called when doscmd initializes a single line */
|
||||
void
|
||||
static void
|
||||
com_set_line(struct com_data_struct *cdsp, unsigned char port, unsigned char param)
|
||||
{
|
||||
struct stat stat_buf;
|
||||
int reg_num;
|
||||
|
||||
debug (D_PORT, "com_set_line: cdsp = %8p, port = 0x%04x,"
|
||||
int mode = 0; /* read | write */
|
||||
int reg_num, ret_val, spd, speed;
|
||||
u_int8_t div_hi, div_lo;
|
||||
|
||||
debug(D_PORT, "com_set_line: cdsp = %8p, port = 0x%04x,"
|
||||
"param = 0x%04X.\n", cdsp, port, param);
|
||||
if (cdsp->fd > 0) {
|
||||
debug (D_PORT, "Re-initialize serial port com%d\n", port);
|
||||
(void)close(cdsp->fd);
|
||||
debug(D_PORT, "Re-initialize serial port com%d\n", port);
|
||||
_RegisterIO(cdsp->fd, 0, 0, 0);
|
||||
(void)close(cdsp->fd);
|
||||
} else {
|
||||
debug (D_PORT, "Initialize serial port com%d\n", port);
|
||||
debug(D_PORT, "Initialize serial port com%d\n", port);
|
||||
}
|
||||
|
||||
|
||||
stat(cdsp->path, &stat_buf);
|
||||
if (!S_ISCHR(stat_buf.st_mode) ||
|
||||
((cdsp->fd = open(cdsp->path, O_RDWR | O_NONBLOCK, 0666)) == -1)) {
|
||||
|
||||
debug (D_PORT,
|
||||
"Could not initialize serial port com%d on path '%s'\n",
|
||||
port, cdsp->path);
|
||||
|
||||
debug(D_PORT,
|
||||
"Could not initialize serial port com%d on path '%s'\n",
|
||||
port, cdsp->path);
|
||||
return;
|
||||
}
|
||||
|
||||
cdsp->flags = 0x00;
|
||||
cdsp->last_char_read = 0x00;
|
||||
#if 0
|
||||
|
||||
cdsp->ids = cdsp->ods = cdsp->emptyint = 0;
|
||||
cdsp->int_enable = 0;
|
||||
cdsp->fifo_ctrl = 0;
|
||||
cdsp->modem_ctrl = 0;
|
||||
cdsp->modem_stat = 0;
|
||||
cdsp->uart_spare = 0;
|
||||
|
||||
if ((param & PARITY_EVEN) == PARITY_NONE)
|
||||
tty.c_iflag = IGNBRK | IGNPAR | IXON | IXOFF /* | IXANY */;
|
||||
cdsp->tty.c_iflag = IGNBRK | IGNPAR /* | IXON | IXOFF | IXANY */;
|
||||
else
|
||||
tty.c_iflag = IGNBRK | IXON | IXOFF /* | IXANY */;
|
||||
tty.c_oflag = 0;
|
||||
tty.c_lflag = 0;
|
||||
tty.c_cc[VTIME] = 0;
|
||||
tty.c_cc[VMIN] = 1;
|
||||
tty.c_cflag = CREAD | CLOCAL | HUPCL;
|
||||
cdsp->tty.c_iflag = IGNBRK /* | IXON | IXOFF | IXANY */;
|
||||
cdsp->tty.c_oflag = 0;
|
||||
cdsp->tty.c_lflag = 0;
|
||||
cdsp->tty.c_cc[VTIME] = 0;
|
||||
cdsp->tty.c_cc[VMIN] = 0;
|
||||
cdsp->tty.c_cflag = CREAD | CLOCAL | HUPCL;
|
||||
/* MCL WHY CLOCAL ??????; but, gets errno EIO on writes, else */
|
||||
if ((param & TXLEN_8BITS) == TXLEN_8BITS)
|
||||
tty.c_cflag |= CS8;
|
||||
else
|
||||
tty.c_cflag |= CS7;
|
||||
if ((param & STOPBIT_2) == STOPBIT_2)
|
||||
tty.c_cflag |= CSTOPB;
|
||||
if ((param & TXLEN_8BITS) == TXLEN_8BITS) {
|
||||
cdsp->tty.c_cflag |= CS8;
|
||||
cdsp->line_ctrl |= 3;
|
||||
} else {
|
||||
cdsp->tty.c_cflag |= CS7;
|
||||
cdsp->line_ctrl |= 2;
|
||||
}
|
||||
if ((param & STOPBIT_2) == STOPBIT_2) {
|
||||
cdsp->tty.c_cflag |= CSTOPB;
|
||||
cdsp->line_ctrl |= LC_STOP_B;
|
||||
} else {
|
||||
cdsp->tty.c_cflag &= ~CSTOPB;
|
||||
cdsp->line_ctrl &= ~LC_STOP_B;
|
||||
}
|
||||
switch (param & PARITY_EVEN) {
|
||||
case (PARITY_ODD):
|
||||
tty.c_cflag |= (PARENB | PARODD);
|
||||
break;
|
||||
case (PARITY_EVEN):
|
||||
tty.c_cflag |= PARENB;
|
||||
break;
|
||||
case (PARITY_NONE):
|
||||
default:
|
||||
break;
|
||||
case PARITY_ODD:
|
||||
cdsp->tty.c_cflag |= (PARENB | PARODD);
|
||||
cdsp->line_ctrl &= ~LC_EVEN_P;
|
||||
cdsp->line_ctrl |= LC_PAR_E;
|
||||
break;
|
||||
case PARITY_EVEN:
|
||||
cdsp->tty.c_cflag |= PARENB;
|
||||
cdsp->line_ctrl |= LC_EVEN_P | LC_PAR_E;
|
||||
break;
|
||||
case PARITY_NONE:
|
||||
cdsp->line_ctrl &= ~LC_PAR_E;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
switch (param & BITRATE_9600) {
|
||||
case (BITRATE_110):
|
||||
case BITRATE_110:
|
||||
speed = B110;
|
||||
spd = 110;
|
||||
break;
|
||||
case (BITRATE_150):
|
||||
case BITRATE_150:
|
||||
speed = B150;
|
||||
spd = 150;
|
||||
break;
|
||||
case (BITRATE_300):
|
||||
case BITRATE_300:
|
||||
speed = B300;
|
||||
spd = 300;
|
||||
break;
|
||||
case (BITRATE_600):
|
||||
case BITRATE_600:
|
||||
speed = B600;
|
||||
spd = 600;
|
||||
break;
|
||||
case (BITRATE_1200):
|
||||
case BITRATE_1200:
|
||||
speed = B1200;
|
||||
spd = 1200;
|
||||
break;
|
||||
case (BITRATE_2400):
|
||||
case BITRATE_2400:
|
||||
speed = B2400;
|
||||
spd = 2400;
|
||||
break;
|
||||
case (BITRATE_4800):
|
||||
case BITRATE_4800:
|
||||
speed = B4800;
|
||||
spd = 4800;
|
||||
break;
|
||||
case (BITRATE_9600):
|
||||
case BITRATE_9600:
|
||||
speed = B9600;
|
||||
spd = 9600;
|
||||
break;
|
||||
}
|
||||
debug (D_PORT, "com_set_line: going with cflag 0x%X iflag 0x%X speed %d.\n",
|
||||
tty.c_cflag, tty.c_iflag, speed);
|
||||
debug(D_PORT,
|
||||
"com_set_line: going with cflag 0x%X iflag 0x%X speed %d.\n",
|
||||
cdsp->tty.c_cflag, cdsp->tty.c_iflag, speed);
|
||||
div_lo = (115200 / spd) & 0x00ff;
|
||||
div_hi = (115200 / spd) & 0xff00;
|
||||
cdsp->div_latch[DIV_LATCH_LOW] = div_lo;
|
||||
cdsp->div_latch[DIV_LATCH_HIGH] = div_hi;
|
||||
errno = 0;
|
||||
ret_val = cfsetispeed(&tty, speed);
|
||||
debug (D_PORT, "com_set_line: cfsetispeed returned 0x%X.\n", ret_val);
|
||||
ret_val = cfsetispeed(&cdsp->tty, speed);
|
||||
debug(D_PORT, "com_set_line: cfsetispeed returned 0x%X.\n", ret_val);
|
||||
errno = 0;
|
||||
ret_val = cfsetospeed(&tty, speed);
|
||||
debug (D_PORT, "com_set_line: cfsetospeed returned 0x%X.\n", ret_val);
|
||||
ret_val = cfsetospeed(&cdsp->tty, speed);
|
||||
debug(D_PORT, "com_set_line: cfsetospeed returned 0x%X.\n", ret_val);
|
||||
errno = 0;
|
||||
ret_val = tcsetattr(cdsp->fd, 0, &tty);
|
||||
debug (D_PORT, "com_set_line: tcsetattr returned 0x%X.\n", ret_val);
|
||||
|
||||
ret_val = tcsetattr(cdsp->fd, 0, &cdsp->tty);
|
||||
debug(D_PORT, "com_set_line: tcsetattr returned 0x%X (%s).\n",
|
||||
ret_val, ret_val == -1 ? strerror(errno) : "");
|
||||
errno = 0;
|
||||
ret_val = fcntl(cdsp->fd, F_SETFL, O_NDELAY);
|
||||
debug (D_PORT, "fcntl of 0x%X, 0x%X to fd %d returned %d errno %d\n",
|
||||
F_SETFL, O_NDELAY, cdsp->fd, ret_val, errno);
|
||||
debug(D_PORT, "fcntl of 0x%X, 0x%X to fd %d returned %d errno %d\n",
|
||||
F_SETFL, O_NDELAY, cdsp->fd, ret_val, errno);
|
||||
errno = 0;
|
||||
ret_val = ioctl(cdsp->fd, TIOCFLUSH, &mode);
|
||||
debug (D_PORT, "ioctl of 0x%02x to fd %d on 0x%X returned %d errno %d\n",
|
||||
TIOCFLUSH, cdsp->fd, mode, ret_val, errno);
|
||||
#endif
|
||||
debug(D_PORT, "ioctl of 0x%02lx to fd %d on 0x%X returned %d errno %d\n",
|
||||
TIOCFLUSH, cdsp->fd, mode, ret_val, errno);
|
||||
for (reg_num = 0; reg_num < N_OF_COM_REGS; reg_num++) {
|
||||
define_input_port_handler(cdsp->addr + reg_num,
|
||||
com_port_in);
|
||||
define_output_port_handler(cdsp->addr + reg_num,
|
||||
com_port_out);
|
||||
define_input_port_handler(cdsp->addr + reg_num, com_port_in);
|
||||
define_output_port_handler(cdsp->addr + reg_num, com_port_out);
|
||||
}
|
||||
cdsp->com_queue = create_queue(cdsp->irq);
|
||||
debug(D_PORT, "com%d: attached '%s' at addr 0x%04x irq %d\n",
|
||||
port, cdsp->path, cdsp->addr, cdsp->irq);
|
||||
port, cdsp->path, cdsp->addr, cdsp->irq);
|
||||
|
||||
set_eoir(cdsp->irq, flush_out, cdsp);
|
||||
_RegisterIO(cdsp->fd, com_async, cdsp, 0);
|
||||
}
|
||||
|
||||
static void
|
||||
try_set_speed(struct com_data_struct *cdsp)
|
||||
{
|
||||
unsigned divisor, speed;
|
||||
int ret_val;
|
||||
|
||||
divisor = (unsigned) cdsp->div_latch[DIV_LATCH_HIGH] << 8
|
||||
| (unsigned) cdsp->div_latch[DIV_LATCH_LOW];
|
||||
|
||||
debug(D_PORT, "try_set_speed: divisor = %u\n", divisor);
|
||||
|
||||
if (divisor == 0)
|
||||
return;
|
||||
|
||||
speed = 115200 / divisor;
|
||||
if (speed == 0)
|
||||
return;
|
||||
|
||||
errno = 0;
|
||||
ret_val = cfsetispeed(&cdsp->tty, speed);
|
||||
debug(D_PORT, "try_set_speed: cfsetispeed returned 0x%X.\n", ret_val);
|
||||
|
||||
errno = 0;
|
||||
ret_val = cfsetospeed(&cdsp->tty, speed);
|
||||
debug(D_PORT, "try_set_speed: cfsetospeed returned 0x%X.\n", ret_val);
|
||||
|
||||
errno = 0;
|
||||
ret_val = tcsetattr(cdsp->fd, 0, &cdsp->tty);
|
||||
debug(D_PORT, "try_set_speed: tcsetattr returned 0x%X (%s).\n", ret_val,
|
||||
ret_val == -1 ? strerror (errno) : "");
|
||||
}
|
||||
|
||||
/* called when config.c initializes a single line */
|
||||
void
|
||||
@ -279,16 +507,19 @@ init_com(int port, char *path, int addr, unsigned char irq)
|
||||
{
|
||||
struct com_data_struct *cdsp;
|
||||
|
||||
debug (D_PORT, "init_com: port = 0x%04x, addr = 0x%04X, irq = %d.\n",
|
||||
port, addr, irq);
|
||||
debug(D_PORT, "init_com: port = 0x%04x, addr = 0x%04X, irq = %d.\n",
|
||||
port, addr, irq);
|
||||
cdsp = &(com_data[port]);
|
||||
cdsp->path = path; /* XXX DEBUG strcpy? */
|
||||
cdsp->addr = addr;
|
||||
cdsp->irq = irq;
|
||||
cdsp->fd = -1;
|
||||
com_set_line(cdsp, port + 1, TXLEN_8BITS | BITRATE_9600);
|
||||
}
|
||||
|
||||
/* update BIOS variables */
|
||||
nserial++;
|
||||
*(u_int16_t *)&BIOSDATA[0x00 + 2 * port] = (u_int16_t)addr;
|
||||
}
|
||||
|
||||
/* called when DOS wants to read directly from a physical port */
|
||||
unsigned char
|
||||
@ -297,7 +528,7 @@ com_port_in(int port)
|
||||
struct com_data_struct *cdsp;
|
||||
unsigned char rs;
|
||||
unsigned char i;
|
||||
int nbytes;
|
||||
int r;
|
||||
|
||||
/* search for a valid COM ???or MOUSE??? port */
|
||||
for (i = 0; i < N_COMS_MAX; i++) {
|
||||
@ -307,7 +538,7 @@ com_port_in(int port)
|
||||
}
|
||||
}
|
||||
if (i == N_COMS_MAX) {
|
||||
debug (D_PORT, "com port 0x%04x not found\n", port);
|
||||
debug(D_PORT, "com port 0x%04x not found\n", port);
|
||||
return 0xff;
|
||||
}
|
||||
|
||||
@ -317,45 +548,24 @@ com_port_in(int port)
|
||||
if (cdsp->line_ctrl & LC_DIV_ACC)
|
||||
rs = cdsp->div_latch[DIV_LATCH_LOW];
|
||||
else {
|
||||
#if 0
|
||||
if (queue_not_empty(cdsp->com_queue)) {
|
||||
rs = get_char_q(cdsp->com_queue);
|
||||
cdsp->last_char_read = rs;
|
||||
if (queue_not_empty(cdsp->com_queue) &&
|
||||
(cdsp->int_enable & IE_RCV_DATA) != 0) {
|
||||
debug(D_PORT,
|
||||
"com_port_in: setting irq %d because bytes yet to be read.\n",
|
||||
cdsp->irq);
|
||||
set_irq_request(cdsp->irq);
|
||||
}
|
||||
} else
|
||||
#else
|
||||
errno = 0;
|
||||
nbytes = read(cdsp->fd, &rs, 1);
|
||||
debug (D_PORT, "read of fd %d on '%s' returned %d byte 0x%02x errno %d\n",
|
||||
cdsp->fd, cdsp->path, nbytes, rs, errno);
|
||||
if (nbytes != 1)
|
||||
#endif
|
||||
rs = cdsp->last_char_read;
|
||||
rs = 0x60;
|
||||
r = read_char(cdsp);
|
||||
if (r != -1)
|
||||
rs = (unsigned char)r;
|
||||
}
|
||||
break;
|
||||
|
||||
/* 0x03F9 - (interrupt enable) or (divisor latch HI) */
|
||||
case 1:
|
||||
case 1:
|
||||
if (cdsp->line_ctrl & LC_DIV_ACC)
|
||||
rs = cdsp->div_latch[DIV_LATCH_HIGH];
|
||||
else
|
||||
rs = cdsp->int_enable;
|
||||
|
||||
break;
|
||||
|
||||
/* 0x03FA - interrupt identification register */
|
||||
case 2:
|
||||
/* rs = cdsp->int_id; * XXX DEBUG not initialized */
|
||||
rs = 0;
|
||||
if ((queue_not_empty(cdsp->com_queue))
|
||||
&& (test_irq_request(cdsp->irq) != 0))
|
||||
rs |= II_PEND_INT | II_RCV_DATA;
|
||||
if ((cdsp->fifo_ctrl & FC_FIFO_EN) == FC_FIFO_EN)
|
||||
rs |= II_FIFOS_EN;
|
||||
rs = get_int_id(cdsp);
|
||||
break;
|
||||
|
||||
/* 0x03FB - line control register */
|
||||
@ -370,11 +580,7 @@ com_port_in(int port)
|
||||
|
||||
/* 0x03FD - line status register */
|
||||
case 5:
|
||||
rs = LS_X_SHFT_E | LS_X_HOLD_E;
|
||||
/* if (queue_not_empty(cdsp->com_queue)) */
|
||||
ioctl(cdsp->fd, FIONREAD, &nbytes);
|
||||
if (nbytes > 0)
|
||||
rs |= LS_RCV_DATA_RD;
|
||||
rs = get_status(cdsp);
|
||||
break;
|
||||
|
||||
/* 0x03FE - modem status register */
|
||||
@ -395,13 +601,11 @@ com_port_in(int port)
|
||||
return rs;
|
||||
}
|
||||
|
||||
|
||||
/* called when DOS wants to write directly to a physical port */
|
||||
void
|
||||
com_port_out(int port, unsigned char val)
|
||||
{
|
||||
struct com_data_struct *cdsp;
|
||||
int nbytes;
|
||||
int i;
|
||||
|
||||
/* search for a valid COM ???or MOUSE??? port */
|
||||
@ -412,7 +616,7 @@ com_port_out(int port, unsigned char val)
|
||||
}
|
||||
}
|
||||
if (i == N_COMS_MAX) {
|
||||
debug (D_PORT, "com port 0x%04x not found\n", port);
|
||||
debug(D_PORT, "com port 0x%04x not found\n", port);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -421,17 +625,9 @@ com_port_out(int port, unsigned char val)
|
||||
case 0:
|
||||
if (cdsp->line_ctrl & LC_DIV_ACC) {
|
||||
cdsp->div_latch[DIV_LATCH_LOW] = val;
|
||||
cdsp->flags |= DIV_LATCH_LOW_WRITTEN;
|
||||
write_div_latches(cdsp);
|
||||
try_set_speed(cdsp);
|
||||
} else {
|
||||
errno = 0;
|
||||
nbytes = write(cdsp->fd, &val, 1);
|
||||
debug (D_PORT, "write of 0x%02x to fd %d on '%s' returned %d errno %d\n",
|
||||
val, cdsp->fd, cdsp->path, nbytes, errno);
|
||||
if (nbytes != 1)
|
||||
debug(D_PORT,
|
||||
"int14: lost output character 0x%02x\n",
|
||||
val);
|
||||
write_char(cdsp, val);
|
||||
}
|
||||
break;
|
||||
|
||||
@ -439,23 +635,24 @@ com_port_out(int port, unsigned char val)
|
||||
case 1:
|
||||
if (cdsp->line_ctrl & LC_DIV_ACC) {
|
||||
cdsp->div_latch[DIV_LATCH_HIGH] = val;
|
||||
cdsp->flags |= DIV_LATCH_HIGH_WRITTEN;
|
||||
write_div_latches(cdsp);
|
||||
try_set_speed(cdsp);
|
||||
} else {
|
||||
cdsp->int_enable = val;
|
||||
if ((val & IE_RCV_DATA) == 0) {
|
||||
reset_irq_request(cdsp->irq);
|
||||
} else {
|
||||
if (queue_not_empty(cdsp->com_queue)) {
|
||||
set_irq_request(cdsp->irq);
|
||||
}
|
||||
}
|
||||
new_ii(cdsp);
|
||||
}
|
||||
break;
|
||||
|
||||
/* 0x03FA - FIFO control register */
|
||||
case 2:
|
||||
cdsp->fifo_ctrl = val;
|
||||
cdsp->fifo_ctrl = val & (FC_FIFO_EN | FC_FIFO_SZ_MASK);
|
||||
if (val & FC_FIFO_CRV)
|
||||
cdsp->ids = 0;
|
||||
if (val & FC_FIFO_CTR) {
|
||||
cdsp->ods = 0;
|
||||
cdsp->emptyint = 1;
|
||||
}
|
||||
input(cdsp, 1);
|
||||
manage_int(cdsp);
|
||||
break;
|
||||
|
||||
/* 0x03FB - line control register */
|
||||
@ -470,7 +667,7 @@ com_port_out(int port, unsigned char val)
|
||||
|
||||
/* 0x03FD - line status register */
|
||||
case 5:
|
||||
cdsp->line_stat = val;
|
||||
/* read-only */
|
||||
break;
|
||||
|
||||
/* 0x03FE - modem status register */
|
||||
@ -489,38 +686,3 @@ com_port_out(int port, unsigned char val)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
/*
|
||||
* called when BSD has bytes ready (as discovered via select) for DOS
|
||||
*/
|
||||
static void do_com_input(int fd)
|
||||
{
|
||||
struct com_data_struct *cdsp;
|
||||
unsigned char buffer[BUFSIZE];
|
||||
int i, nbytes;
|
||||
|
||||
dp = search_com_device_by_fd(fd);
|
||||
if (dp == NULL)
|
||||
return;
|
||||
do {
|
||||
nbytes = read(cdsp->fd, buffer, BUFSIZE);
|
||||
if (nbytes > 0) {
|
||||
debug(D_PORT, "do_com_input: read %d bytes from fd %d (aka %d): ",
|
||||
nbytes, fd, cdsp->fd);
|
||||
for (i = 0; i < nbytes; i++) {
|
||||
put_char_q(cdsp->com_queue, buffer[i]);
|
||||
if (cdsp->int_enable & IE_RCV_DATA) {
|
||||
debug(D_PORT, "\n");
|
||||
debug(D_PORT, "do_com_input: setting irq %d because %d bytes read.\n",
|
||||
dp->irq, nbytes);
|
||||
debug(D_PORT, "do_com_input: ");
|
||||
set_irq_request(dp->irq);
|
||||
}
|
||||
debug(D_PORT, "%02x ", buffer[i]);
|
||||
}
|
||||
debug(D_PORT, "\n");
|
||||
}
|
||||
} while (nbytes == BUFSIZE);
|
||||
}
|
||||
#endif 0
|
||||
|
@ -84,12 +84,10 @@ generichandler(struct sigframe sf)
|
||||
#error BSD/OS sigframe/trapframe kernel interface not currently supported.
|
||||
#endif
|
||||
|
||||
void
|
||||
setsignal(int s, void (*h)(struct sigframe *))
|
||||
void setsignal(int s, void (*h)(struct sigframe *))
|
||||
{
|
||||
static int first = 1;
|
||||
struct sigaction sa;
|
||||
sigset_t set;
|
||||
|
||||
if (first) {
|
||||
struct sigaltstack sstack;
|
||||
@ -110,8 +108,5 @@ setsignal(int s, void (*h)(struct sigframe *))
|
||||
sigaddset(&sa.sa_mask, SIGALRM);
|
||||
sa.sa_flags = SA_ONSTACK;
|
||||
sigaction(s, &sa, NULL);
|
||||
|
||||
sigaddset(&set, s);
|
||||
sigprocmask(SIG_UNBLOCK, &set, 0);
|
||||
}
|
||||
}
|
||||
|
@ -13,7 +13,8 @@ int08(regcontext_t *REGS)
|
||||
*(u_long *)&BIOSDATA[0x6c] -= 24*60*6*182;
|
||||
BIOSDATA[0x70]++; /* # times past mn */
|
||||
}
|
||||
|
||||
/* What is the real BIOS' sequence? */
|
||||
send_eoi();
|
||||
softint(0x1c);
|
||||
}
|
||||
|
||||
|
@ -321,13 +321,10 @@ sigbus(struct sigframe *sf)
|
||||
resettrace(REGS);
|
||||
|
||||
if ((R_EFLAGS & (PSL_VIP | PSL_VIF)) == (PSL_VIP | PSL_VIF)) {
|
||||
if (n_pending < 1) {
|
||||
fatal("Pending interrupts out of sync\n");
|
||||
exit(1);
|
||||
}
|
||||
resume_interrupt();
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* printf("%p\n", addr); fflush(stdout); */
|
||||
debug (D_TRAPS2, "%04x:%04x [%02x %02x %02x] ", R_CS, R_IP,
|
||||
(int)addr[0], (int)addr[1], (int)addr[2]);
|
||||
@ -516,7 +513,7 @@ sigbus(struct sigframe *sf)
|
||||
|
||||
out:
|
||||
if (tmode)
|
||||
tracetrap(REGS);
|
||||
tracetrap(REGS);
|
||||
}
|
||||
#endif /* USE_VM86 */
|
||||
|
||||
@ -601,11 +598,9 @@ sigalrm(struct sigframe *sf)
|
||||
if (tmode)
|
||||
resettrace(REGS);
|
||||
|
||||
/* debug(D_ALWAYS,"tick %d", update_counter); */
|
||||
update_counter = 0; /* remember we've updated */
|
||||
video_update((regcontext_t *)®S->sc);
|
||||
hardint(0x08);
|
||||
/* debug(D_ALWAYS,"\n"); */
|
||||
hardint(0x00);
|
||||
|
||||
if (tmode)
|
||||
tracetrap(REGS);
|
||||
|
@ -125,16 +125,16 @@ static struct termios tty_cook, tty_raw;
|
||||
#define col (CursCol0)
|
||||
|
||||
/* Local functions */
|
||||
static void _kbd_event(void *, regcontext_t *);
|
||||
static void _kbd_event(int, int, void *, regcontext_t *);
|
||||
static void Failure(void *);
|
||||
static void SetVREGCur(void);
|
||||
static void debug_event(void *, regcontext_t *);
|
||||
static void debug_event(int, int, void *, regcontext_t *);
|
||||
static unsigned char inb_port60(int);
|
||||
static int inrange(int, int, int);
|
||||
static void kbd_event(int);
|
||||
static void kbd_event(int, int, void *, regcontext_t *);
|
||||
static u_short read_raw_kbd(int, u_short *);
|
||||
static void setgc(u_short);
|
||||
static void video_async_event(void *, regcontext_t *);
|
||||
static void video_async_event(int, int, void *, regcontext_t *);
|
||||
|
||||
#ifndef NO_X
|
||||
static void dac2rgb(XColor *, int);
|
||||
@ -234,10 +234,10 @@ console_denit(void *arg)
|
||||
}
|
||||
|
||||
void
|
||||
_kbd_event(void *pfd, regcontext_t *REGS)
|
||||
_kbd_event(int fd, int cond, void *arg, regcontext_t *REGS)
|
||||
{
|
||||
int fd = *(int *)pfd;
|
||||
|
||||
if (!(cond & AS_RD))
|
||||
return;
|
||||
printf("_kbd_event: fd=%d\n", fd);
|
||||
kbd_read = 1;
|
||||
}
|
||||
@ -317,19 +317,17 @@ console_init()
|
||||
}
|
||||
|
||||
#if 0
|
||||
_RegisterIO(0, debug_event, 0, Failure);
|
||||
_RegisterIO(fd, kbd_event, fd, Failure);
|
||||
_RegisterIO(STDIN_FILENO, debug_event, 0, Failure);
|
||||
_RegisterIO(fd, kbd_event, 0, Failure);
|
||||
#endif
|
||||
_RegisterIO(fd, _kbd_event, &fd, Failure);
|
||||
_RegisterIO(fd, _kbd_event, 0, Failure);
|
||||
}
|
||||
|
||||
void
|
||||
video_setborder(int color)
|
||||
{
|
||||
#ifndef NO_X
|
||||
_BlockIO();
|
||||
XSetWindowBackground(dpy, win, pixels[color & 0xf]);
|
||||
_UnblockIO();
|
||||
#endif
|
||||
}
|
||||
void
|
||||
@ -360,7 +358,7 @@ video_update(regcontext_t *REGS)
|
||||
static int icnt = 3;
|
||||
|
||||
if (kbd_read)
|
||||
kbd_event(kbd_fd);
|
||||
kbd_event(kbd_fd, AS_RD, 0, REGS);
|
||||
|
||||
if (--icnt == 0) {
|
||||
icnt = 3;
|
||||
@ -651,7 +649,7 @@ struct {
|
||||
};
|
||||
|
||||
void
|
||||
debug_event(void *pfd, regcontext_t *REGS)
|
||||
debug_event(int fd, int cond, void *arg, regcontext_t *REGS)
|
||||
{
|
||||
static char ibuf[1024];
|
||||
static int icnt = 0;
|
||||
@ -660,6 +658,9 @@ debug_event(void *pfd, regcontext_t *REGS)
|
||||
static u_short cnt = 16 * 8;
|
||||
char *ep;
|
||||
int r;
|
||||
|
||||
if (!(cond & AS_RD))
|
||||
return;
|
||||
|
||||
r = read(STDIN_FILENO, ibuf + icnt, sizeof(ibuf) - icnt);
|
||||
if (r <= 0)
|
||||
@ -777,13 +778,16 @@ inb_port60(int port)
|
||||
}
|
||||
|
||||
void
|
||||
kbd_event(int fd)
|
||||
kbd_event(int fd, int cond, void *arg, regcontext_t *REGS)
|
||||
{
|
||||
if (!(cond & AS_RD))
|
||||
return;
|
||||
|
||||
kbd_read = 0;
|
||||
|
||||
printf("kbd_event: fd=%d\n", fd);
|
||||
if ((break_code = read_raw_kbd(fd, &scan_code)) != 0xffff)
|
||||
hardint(0x09);
|
||||
hardint(0x01);
|
||||
}
|
||||
|
||||
void
|
||||
@ -795,10 +799,11 @@ int09(REGISTERS)
|
||||
break_code = 0;
|
||||
scan_code = 0xffff;
|
||||
#if 0
|
||||
kbd_event(kbd_fd, sc);
|
||||
kbd_event(kbd_fd, 0, sc, REGS);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
send_eoi();
|
||||
}
|
||||
|
||||
u_short
|
||||
@ -974,12 +979,14 @@ printf("FORCED REDRAW\n");
|
||||
}
|
||||
|
||||
void
|
||||
video_async_event(void *pfd, regcontext_t *REGS)
|
||||
video_async_event(int fd, int cond, void *arg, regcontext_t *REGS)
|
||||
{
|
||||
#ifndef NO_X
|
||||
int int9 = 0;
|
||||
int fd = *(int *)pfd;
|
||||
|
||||
if (!(cond & AS_RD))
|
||||
return;
|
||||
|
||||
for (;;) {
|
||||
int x;
|
||||
fd_set fdset;
|
||||
@ -1012,7 +1019,7 @@ video_async_event(void *pfd, regcontext_t *REGS)
|
||||
case 0:
|
||||
XFlush(dpy);
|
||||
if (int9)
|
||||
hardint(0x09);
|
||||
hardint(0x01);
|
||||
return;
|
||||
default:
|
||||
if (FD_ISSET(fd, &fdset)) {
|
||||
@ -1967,10 +1974,9 @@ init_window()
|
||||
err(1, "Could not open display ``%s''\n", XDisplayName(NULL));
|
||||
xfd = ConnectionNumber(dpy);
|
||||
|
||||
_RegisterIO(xfd, video_async_event, &xfd, Failure);
|
||||
_RegisterIO(xfd, video_async_event, 0, Failure);
|
||||
if (debug_flags & D_DEBUGIN)
|
||||
_RegisterIO(0, debug_event, 0, Failure);
|
||||
_BlockIO();
|
||||
|
||||
/* Create window, but defer setting a size and GC. */
|
||||
win = XCreateSimpleWindow(dpy, DefaultRootWindow(dpy), 0, 0,
|
||||
@ -1996,8 +2002,6 @@ init_window()
|
||||
|
||||
XStoreName(dpy, win, "DOS");
|
||||
|
||||
_UnblockIO();
|
||||
|
||||
/* Get the default visual and depth for later use. */
|
||||
depth = DefaultDepth(dpy, DefaultScreen(dpy));
|
||||
visual = DefaultVisual(dpy, DefaultScreen(dpy));
|
||||
|
@ -138,6 +138,7 @@ video_inb(int port)
|
||||
return gdc_index;
|
||||
case VGA_InputStatus1Port:
|
||||
set_atc_index = 1;
|
||||
VGA_InputStatus1 = (VGA_InputStatus1 + 1) & 15;
|
||||
return VGA_InputStatus1;
|
||||
default:
|
||||
return 0;
|
||||
@ -259,6 +260,7 @@ video_init()
|
||||
define_input_port_handler(TSC_DataPort, video_inb);
|
||||
define_input_port_handler(GDC_IndexPort, video_inb);
|
||||
define_input_port_handler(GDC_DataPort, video_inb);
|
||||
define_input_port_handler(VGA_InputStatus1Port, video_inb);
|
||||
|
||||
define_output_port_handler(CRTC_IndexPortColor, video_outb);
|
||||
define_output_port_handler(CRTC_DataPortColor, video_outb);
|
||||
@ -364,6 +366,8 @@ init_vga(void)
|
||||
vplane1 = vram + 0x10000;
|
||||
vplane2 = vram + 0x20000;
|
||||
vplane3 = vram + 0x30000;
|
||||
|
||||
VGA_InputStatus1 = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -450,7 +454,6 @@ init_mode(int mode)
|
||||
BIOS_DpyRows = DpyRows;
|
||||
BIOS_CharHeight = CharHeight;
|
||||
|
||||
_BlockIO();
|
||||
/* Load 'pixels[]' from default DAC values. */
|
||||
update_pixels();
|
||||
|
||||
@ -460,7 +463,6 @@ init_mode(int mode)
|
||||
|
||||
/* Resize window if necessary. */
|
||||
resize_window();
|
||||
_UnblockIO();
|
||||
|
||||
/* Mmap video memory for the graphics modes. Write access to 0xa0000 -
|
||||
0xaffff will generate a T_PAGEFAULT trap in VM86 mode (aside: why not a
|
||||
|
Loading…
Reference in New Issue
Block a user