changes for maxine from Rick Macklem.
authorRalph Campbell <ralph@ucbvax.Berkeley.EDU>
Mon, 16 Nov 1992 07:49:15 +0000 (23:49 -0800)
committerRalph Campbell <ralph@ucbvax.Berkeley.EDU>
Mon, 16 Nov 1992 07:49:15 +0000 (23:49 -0800)
SCCS-vsn: sys/pmax/dev/dc.c 7.11
SCCS-vsn: sys/pmax/dev/pm.c 7.8
SCCS-vsn: sys/pmax/dev/if_le.c 7.8
SCCS-vsn: sys/pmax/dev/if_lereg.h 7.3
SCCS-vsn: sys/pmax/dev/pdma.h 7.3
SCCS-vsn: sys/pmax/dev/sii.c 7.7
SCCS-vsn: sys/pmax/dev/asc.c 7.8
SCCS-vsn: sys/pmax/dev/cfb.c 7.5
SCCS-vsn: sys/pmax/dev/ascreg.h 7.2

usr/src/sys/pmax/dev/asc.c
usr/src/sys/pmax/dev/ascreg.h
usr/src/sys/pmax/dev/cfb.c
usr/src/sys/pmax/dev/dc.c
usr/src/sys/pmax/dev/if_le.c
usr/src/sys/pmax/dev/if_lereg.h
usr/src/sys/pmax/dev/pdma.h
usr/src/sys/pmax/dev/pm.c
usr/src/sys/pmax/dev/sii.c

index 971b6ca..b1bfbdf 100644 (file)
@@ -3,11 +3,11 @@
  * All rights reserved.
  *
  * This code is derived from software contributed to Berkeley by
  * All rights reserved.
  *
  * This code is derived from software contributed to Berkeley by
- * Ralph Campbell.
+ * Ralph Campbell and Rick Macklem.
  *
  * %sccs.include.redist.c%
  *
  *
  * %sccs.include.redist.c%
  *
- *     @(#)asc.c       7.7 (Berkeley) %G%
+ *     @(#)asc.c       7.8 (Berkeley) %G%
  */
 
 /* 
  */
 
 /* 
  *
  */
 
  *
  */
 
-#include "asc.h"
+#include <asc.h>
 #if NASC > 0
 
 #include <sys/param.h>
 #include <sys/systm.h>
 #if NASC > 0
 
 #include <sys/param.h>
 #include <sys/systm.h>
+#include <sys/dkstat.h>
+#include <sys/buf.h>
+#include <sys/conf.h>
 #include <sys/errno.h>
 
 #include <sys/errno.h>
 
+#include <machine/machConst.h>
+
 #include <pmax/dev/device.h>
 #include <pmax/dev/scsi.h>
 #include <pmax/dev/ascreg.h>
 
 #include <pmax/dev/device.h>
 #include <pmax/dev/scsi.h>
 #include <pmax/dev/ascreg.h>
 
+#include <pmax/pmax/asic.h>
+#include <pmax/pmax/kmin.h>
+#include <pmax/pmax/pmaxtype.h>
+
 #define ASC_OFFSET_53C94       0x0             /* from module base */
 #define ASC_OFFSET_DMAR                0x40000         /* DMA Address Register */
 #define ASC_OFFSET_RAM         0x80000         /* SRAM Buffer */
 #define ASC_OFFSET_53C94       0x0             /* from module base */
 #define ASC_OFFSET_DMAR                0x40000         /* DMA Address Register */
 #define ASC_OFFSET_RAM         0x80000         /* SRAM Buffer */
 
 #define        ASC_RAM_SIZE            0x20000         /* 128k (32k*32) */
 
 
 #define        ASC_RAM_SIZE            0x20000         /* 128k (32k*32) */
 
+#define        readback(a)     { register int foo; foo = (a); }
 /*
  * DMA Address Register
  */
 /*
  * DMA Address Register
  */
 /*
  * Synch xfer parameters, and timing conversions
  */
 /*
  * Synch xfer parameters, and timing conversions
  */
-#define SCSI_MIN_PERIOD        50      /* in 4 nsecs units */
-#define ASC_MIN_PERIOD 5       /* in CLKS/BYTE, 1 CLK = 40nsecs */
-#define ASC_MAX_PERIOD 35      /* in CLKS/BYTE, 1 CLK = 40nsecs */
-#define ASC_MAX_OFFSET 15      /* pure number */
+#define SCSI_MIN_PERIOD                50      /* in 4 nsecs units */
+#define ASC_MIN_PERIOD25       5       /* in CLKS/BYTE, 1 CLK = 40nsecs */
+#define ASC_MIN_PERIOD12       3       /* in CLKS/BYTE, 1 CLK = 80nsecs */
+#define ASC_MAX_PERIOD25       35      /* in CLKS/BYTE, 1 CLK = 40nsecs */
+#define ASC_MAX_PERIOD12       18      /* in CLKS/BYTE, 1 CLK = 80nsecs */
+#define ASC_MAX_OFFSET         15      /* pure number */
 
 
+extern int pmax_boardtype;
+
+/*
+ * In 4ns ticks.
+ */
 int    asc_to_scsi_period[] = {
 int    asc_to_scsi_period[] = {
-       320,
-       330,
-       340,
-       350,
-       50,
-       50,
-       60,
-       70,
-       80,
-       90,
-       100,
-       110,
-       120,
-       130,
-       140,
-       150,
-       160,
-       170,
-       180,
-       190,
-       200,
-       210,
-       220,
-       230,
-       240,
-       250,
-       260,
-       270,
-       280,
-       290,
-       300,
-       310,
+       32,
+       33,
+       34,
+       35,
+       5,
+       5,
+       6,
+       7,
+       8,
+       9,
+       10,
+       11,
+       12,
+       13,
+       14,
+       15,
+       16,
+       17,
+       18,
+       19,
+       20,
+       21,
+       22,
+       23,
+       24,
+       25,
+       26,
+       27,
+       28,
+       29,
+       30,
+       31,
 };
 
 /*
 };
 
 /*
@@ -205,21 +222,21 @@ typedef struct script {
 #define        SCRIPT_MATCH(ir, csr)           ((ir) | (ASC_PHASE(csr) << 8))
 
 /* forward decls of script actions */
 #define        SCRIPT_MATCH(ir, csr)           ((ir) | (ASC_PHASE(csr) << 8))
 
 /* forward decls of script actions */
-static int     script_nop();           /* when nothing needed */
-static int     asc_end();              /* all come to an end */
-static int     asc_get_status();       /* get status from target */
-static int     asc_dma_in();           /* start reading data from target */
-static int     asc_last_dma_in();      /* cleanup after all data is read */
-static int     asc_resume_in();        /* resume data in after a message */
-static int     asc_resume_dma_in();    /* resume DMA after a disconnect */
-static int     asc_dma_out();          /* send data to target via dma */
-static int     asc_last_dma_out();     /* cleanup after all data is written */
-static int     asc_resume_out();       /* resume data out after a message */
-static int     asc_resume_dma_out();   /* resume DMA after a disconnect */
-static int     asc_sendsync();         /* negotiate sync xfer */
-static int     asc_replysync();        /* negotiate sync xfer */
-static int     asc_msg_in();           /* process a message byte */
-static int     asc_disconnect();       /* process an expected disconnect */
+static int script_nop();               /* when nothing needed */
+static int asc_end();                  /* all come to an end */
+static int asc_get_status();           /* get status from target */
+static int asc_dma_in();               /* start reading data from target */
+static int asc_last_dma_in();          /* cleanup after all data is read */
+static int asc_resume_in();            /* resume data in after a message */
+static int asc_resume_dma_in();                /* resume DMA after a disconnect */
+static int asc_dma_out();              /* send data to target via dma */
+static int asc_last_dma_out();         /* cleanup after all data is written */
+static int asc_resume_out();           /* resume data out after a message */
+static int asc_resume_dma_out();       /* resume DMA after a disconnect */
+static int asc_sendsync();             /* negotiate sync xfer */
+static int asc_replysync();            /* negotiate sync xfer */
+static int asc_msg_in();               /* process a message byte */
+static int asc_disconnect();           /* process an expected disconnect */
 
 /* Define the index into asc_scripts for various state transitions */
 #define        SCRIPT_DATA_IN          0
 
 /* Define the index into asc_scripts for various state transitions */
 #define        SCRIPT_DATA_IN          0
@@ -379,7 +396,7 @@ typedef struct scsi_state {
 struct asc_softc {
        asc_regmap_t    *regs;          /* chip address */
        volatile int    *dmar;          /* DMA address register address */
 struct asc_softc {
        asc_regmap_t    *regs;          /* chip address */
        volatile int    *dmar;          /* DMA address register address */
-       u_char          *buff;          /* RAM buffer address */
+       u_char          *buff;          /* RAM buffer address (uncached) */
        int             myid;           /* SCSI ID of this interface */
        int             myidmask;       /* ~(1 << myid) */
        int             state;          /* current SCSI connection state */
        int             myid;           /* SCSI ID of this interface */
        int             myidmask;       /* ~(1 << myid) */
        int             state;          /* current SCSI connection state */
@@ -387,6 +404,15 @@ struct asc_softc {
        script_t        *script;        /* next expected interrupt & action */
        ScsiCmd         *cmd[ASC_NCMD]; /* active command indexed by SCSI ID */
        State           st[ASC_NCMD];   /* state info for each active command */
        script_t        *script;        /* next expected interrupt & action */
        ScsiCmd         *cmd[ASC_NCMD]; /* active command indexed by SCSI ID */
        State           st[ASC_NCMD];   /* state info for each active command */
+       void            (*dma_start)(); /* Start dma routine */
+       void            (*dma_end)();   /* End dma routine */
+       u_char          *dma_next;
+       int             dma_xfer;       /* Dma len still to go */
+       int             min_period;     /* Min transfer period clk/byte */
+       int             max_period;     /* Max transfer period clk/byte */
+       int             ccf;            /* CCF, whatever that really is? */
+       int             timeout_250;    /* 250ms timeout */
+       int             tb_ticks;       /* 4ns. ticks/tb channel ticks */
 } asc_softc[NASC];
 
 #define        ASC_STATE_IDLE          0       /* idle state */
 } asc_softc[NASC];
 
 #define        ASC_STATE_IDLE          0       /* idle state */
@@ -396,6 +422,14 @@ struct asc_softc {
 
 typedef struct asc_softc *asc_softc_t;
 
 
 typedef struct asc_softc *asc_softc_t;
 
+/*
+ * Dma operations.
+ */
+#define        ASCDMA_READ     1
+#define        ASCDMA_WRITE    2
+static void tb_dma_start(), tb_dma_end(), asic_dma_start(), asic_dma_end();
+u_long asc_iobuf[33792];
+
 /*
  * Definition of the controller for the auto-configuration program.
  */
 /*
  * Definition of the controller for the auto-configuration program.
  */
@@ -416,6 +450,7 @@ asc_probe(cp)
        register asc_softc_t asc;
        register asc_regmap_t *regs;
        int unit, id, s, i;
        register asc_softc_t asc;
        register asc_regmap_t *regs;
        int unit, id, s, i;
+       u_int bufadr;
 
        if ((unit = cp->pmax_unit) >= NASC)
                return (0);
 
        if ((unit = cp->pmax_unit) >= NASC)
                return (0);
@@ -427,8 +462,60 @@ asc_probe(cp)
         * Initialize hw descriptor, cache some pointers
         */
        asc->regs = (asc_regmap_t *)(cp->pmax_addr + ASC_OFFSET_53C94);
         * Initialize hw descriptor, cache some pointers
         */
        asc->regs = (asc_regmap_t *)(cp->pmax_addr + ASC_OFFSET_53C94);
-       asc->dmar = (volatile int *)(cp->pmax_addr + ASC_OFFSET_DMAR);
-       asc->buff = (u_char *)(cp->pmax_addr + ASC_OFFSET_RAM);
+
+       /*
+        * Set up machine dependencies.
+        * 1) how to do dma
+        * 2) timing based on turbochannel frequency
+        */
+       switch (pmax_boardtype) {
+       case DS_3MIN:
+       case DS_MAXINE:
+           if (unit == 0) {
+               bufadr = MACH_PHYS_TO_UNCACHED(MACH_CACHED_TO_PHYS(asc_iobuf));
+               bufadr = (bufadr + NBPG - 1) & ~(NBPG - 1);
+               asc->buff = (u_char *)bufadr;
+               *((volatile int *)MACH_PHYS_TO_UNCACHED(KMIN_REG_SCSI_DMAPTR))
+                       = -1;
+               *((volatile int *)MACH_PHYS_TO_UNCACHED(KMIN_REG_SCSI_DMANPTR))
+                       = -1;
+               *((volatile int *)MACH_PHYS_TO_UNCACHED(KMIN_REG_SCSI_SCR)) = 0;
+               asc->dma_start = asic_dma_start;
+               asc->dma_end = asic_dma_end;
+               break;
+           }
+           /*
+            * Fall through for turbochannel option.
+            */
+       case DS_3MAX:
+       default:
+           asc->dmar = (volatile int *)(cp->pmax_addr + ASC_OFFSET_DMAR);
+           asc->buff = (u_char *)(cp->pmax_addr + ASC_OFFSET_RAM);
+           asc->dma_start = tb_dma_start;
+           asc->dma_end = tb_dma_end;
+       };
+       /*
+        * Now for timing. The 3max has a 25Mhz tb whereas the 3min and
+        * maxine are 12.5Mhz.
+        */
+       switch (pmax_boardtype) {
+       case DS_3MAX:
+               asc->min_period = ASC_MIN_PERIOD25;
+               asc->max_period = ASC_MAX_PERIOD25;
+               asc->ccf = ASC_CCF(25);
+               asc->timeout_250 = ASC_TIMEOUT_250(25, asc->ccf);
+               asc->tb_ticks = 10;
+               break;
+       case DS_3MIN:
+       case DS_MAXINE:
+       default:
+               asc->min_period = ASC_MIN_PERIOD12;
+               asc->max_period = ASC_MAX_PERIOD12;
+               asc->ccf = ASC_CCF(13);
+               asc->timeout_250 = ASC_TIMEOUT_250(13, asc->ccf);
+               asc->tb_ticks = 20;
+               break;
+       };
 
        asc->state = ASC_STATE_IDLE;
        asc->target = -1;
 
        asc->state = ASC_STATE_IDLE;
        asc->target = -1;
@@ -529,17 +616,16 @@ asc_reset(asc, regs)
        /*
         * Set up various chip parameters
         */
        /*
         * Set up various chip parameters
         */
-       regs->asc_ccf = ASC_CCF_25MHz;  /* 25 MHz clock */
+       regs->asc_ccf = asc->ccf;
        MachEmptyWriteBuffer(); DELAY(25);
        MachEmptyWriteBuffer(); DELAY(25);
-       regs->asc_sel_timo = ASC_TIMEOUT_250;
+       regs->asc_sel_timo = asc->timeout_250;
        /* restore our ID */
        regs->asc_cnfg1 = asc->myid | ASC_CNFG1_P_CHECK;
        /* restore our ID */
        regs->asc_cnfg1 = asc->myid | ASC_CNFG1_P_CHECK;
-       regs->asc_cnfg2 = /* ASC_CNFG2_RFB | */ ASC_CNFG2_EPL;
+       regs->asc_cnfg2 = /* ASC_CNFG2_RFB | */ ASC_CNFG2_SCSI2;
        regs->asc_cnfg3 = 0;
        /* zero anything else */
        ASC_TC_PUT(regs, 0);
        regs->asc_cnfg3 = 0;
        /* zero anything else */
        ASC_TC_PUT(regs, 0);
-       regs->asc_sel_timo = ASC_TIMEOUT_250;
-       regs->asc_syn_p = ASC_MIN_PERIOD;
+       regs->asc_syn_p = asc->min_period;
        regs->asc_syn_o = 0;    /* async for now */
        MachEmptyWriteBuffer();
 }
        regs->asc_syn_o = 0;    /* async for now */
        MachEmptyWriteBuffer();
 }
@@ -571,6 +657,7 @@ asc_startcmd(asc, target)
         */
        if (asc->state == ASC_STATE_RESEL) {
                regs->asc_cmd = ASC_CMD_DISABLE_SEL;
         */
        if (asc->state == ASC_STATE_RESEL) {
                regs->asc_cmd = ASC_CMD_DISABLE_SEL;
+               readback(regs->asc_cmd);
                while (!(regs->asc_status & ASC_CSR_INT))
                        DELAY(1);
                asc_intr(asc - asc_softc);
                while (!(regs->asc_status & ASC_CSR_INT))
                        DELAY(1);
                asc_intr(asc - asc_softc);
@@ -612,6 +699,8 @@ asc_startcmd(asc, target)
         * Init the chip and target state.
         */
        regs->asc_cmd = ASC_CMD_FLUSH;
         * Init the chip and target state.
         */
        regs->asc_cmd = ASC_CMD_FLUSH;
+       readback(regs->asc_cmd);
+       DELAY(2);
        state->flags = state->flags & DID_SYNC;
        state->error = 0;
        state->script = (script_t *)0;
        state->flags = state->flags & DID_SYNC;
        state->error = 0;
        state->script = (script_t *)0;
@@ -646,19 +735,25 @@ asc_startcmd(asc, target)
 
        /* preload the FIFO with the message to be sent */
        regs->asc_fifo = SCSI_DIS_REC_IDENTIFY;
 
        /* preload the FIFO with the message to be sent */
        regs->asc_fifo = SCSI_DIS_REC_IDENTIFY;
+       MachEmptyWriteBuffer();
 
        /* start the asc */
 
        /* start the asc */
-       *asc->dmar = ASC_DMAR_WRITE | ASC_DMA_ADDR(state->dmaBufAddr);
+       (*asc->dma_start)(asc, state, state->dmaBufAddr, ASCDMA_WRITE);
        ASC_TC_PUT(regs, len);
        ASC_TC_PUT(regs, len);
+       readback(regs->asc_cmd);
 
        regs->asc_dbus_id = target;
 
        regs->asc_dbus_id = target;
+       readback(regs->asc_dbus_id);
        regs->asc_syn_p = state->sync_period;
        regs->asc_syn_p = state->sync_period;
+       readback(regs->asc_syn_p);
        regs->asc_syn_o = state->sync_offset;
        regs->asc_syn_o = state->sync_offset;
+       readback(regs->asc_syn_o);
 
        if (state->flags & TRY_SYNC)
                regs->asc_cmd = ASC_CMD_SEL_ATN_STOP;
        else
                regs->asc_cmd = ASC_CMD_SEL_ATN | ASC_CMD_DMA;
 
        if (state->flags & TRY_SYNC)
                regs->asc_cmd = ASC_CMD_SEL_ATN_STOP;
        else
                regs->asc_cmd = ASC_CMD_SEL_ATN | ASC_CMD_DMA;
+       readback(regs->asc_cmd);
 }
 
 /*
 }
 
 /*
@@ -705,6 +800,7 @@ again:
                 */
                if ((*scpt->action)(asc, status, ss, ir)) {
                        regs->asc_cmd = scpt->command;
                 */
                if ((*scpt->action)(asc, status, ss, ir)) {
                        regs->asc_cmd = scpt->command;
+                       readback(regs->asc_cmd);
                        asc->script = scpt->next;
                }
                goto done;
                        asc->script = scpt->next;
                }
                goto done;
@@ -731,12 +827,14 @@ again:
                        regs->asc_fifo = state->msg_out;
                        state->msg_out = SCSI_NO_OP;
                        regs->asc_cmd = ASC_CMD_XFER_INFO;
                        regs->asc_fifo = state->msg_out;
                        state->msg_out = SCSI_NO_OP;
                        regs->asc_cmd = ASC_CMD_XFER_INFO;
+                       readback(regs->asc_cmd);
                        goto done;
 
                case ASC_PHASE_STATUS:
                        /* probably an error in the SCSI command */
                        asc->script = &asc_scripts[SCRIPT_GET_STATUS];
                        regs->asc_cmd = ASC_CMD_I_COMPLETE;
                        goto done;
 
                case ASC_PHASE_STATUS:
                        /* probably an error in the SCSI command */
                        asc->script = &asc_scripts[SCRIPT_GET_STATUS];
                        regs->asc_cmd = ASC_CMD_I_COMPLETE;
+                       readback(regs->asc_cmd);
                        goto done;
 
                default:
                        goto done;
 
                default:
@@ -766,7 +864,9 @@ again:
                                printf("asc_intr: dmalen %d len %d fifo %d\n",
                                        state->dmalen, len, fifo); /* XXX */
                        regs->asc_cmd = ASC_CMD_FLUSH;
                                printf("asc_intr: dmalen %d len %d fifo %d\n",
                                        state->dmalen, len, fifo); /* XXX */
                        regs->asc_cmd = ASC_CMD_FLUSH;
+                       readback(regs->asc_cmd);
                        MachEmptyWriteBuffer();
                        MachEmptyWriteBuffer();
+                       DELAY(2);
                }
                if (len) {
                        /* save number of bytes still to be sent or received */
                }
                if (len) {
                        /* save number of bytes still to be sent or received */
@@ -785,6 +885,7 @@ again:
                        if (state->flags & DMA_IN) {
                                if (state->flags & DMA_IN_PROGRESS) {
                                        state->flags &= ~DMA_IN_PROGRESS;
                        if (state->flags & DMA_IN) {
                                if (state->flags & DMA_IN_PROGRESS) {
                                        state->flags &= ~DMA_IN_PROGRESS;
+                                       (*asc->dma_end)(asc, state, ASCDMA_READ);
                                        len = state->dmalen;
                                        bcopy(state->dmaBufAddr, state->buf,
                                                len);
                                        len = state->dmalen;
                                        bcopy(state->dmaBufAddr, state->buf,
                                                len);
@@ -804,6 +905,7 @@ again:
                                 */
                                if (state->flags & DMA_IN_PROGRESS) {
                                        state->flags &= ~DMA_IN_PROGRESS;
                                 */
                                if (state->flags & DMA_IN_PROGRESS) {
                                        state->flags &= ~DMA_IN_PROGRESS;
+                                       (*asc->dma_end)(asc, state, ASCDMA_WRITE);
                                        len = state->dmalen;
                                        state->buf += len;
                                        state->buflen -= len;
                                        len = state->dmalen;
                                        state->buf += len;
                                        state->buflen -= len;
@@ -825,6 +927,7 @@ again:
                asc->script = &asc_scripts[SCRIPT_MSG_IN];
                state->msglen = 0;
                regs->asc_cmd = ASC_CMD_XFER_INFO;
                asc->script = &asc_scripts[SCRIPT_MSG_IN];
                state->msglen = 0;
                regs->asc_cmd = ASC_CMD_XFER_INFO;
+               readback(regs->asc_cmd);
                goto done;
        }
 
                goto done;
        }
 
@@ -899,6 +1002,7 @@ again:
                regs->asc_syn_p = state->sync_period;
                regs->asc_syn_o = state->sync_offset;
                regs->asc_cmd = ASC_CMD_MSG_ACPT;
                regs->asc_syn_p = state->sync_period;
                regs->asc_syn_o = state->sync_offset;
                regs->asc_cmd = ASC_CMD_MSG_ACPT;
+               readback(regs->asc_cmd);
                goto done;
        }
 
                goto done;
        }
 
@@ -958,6 +1062,7 @@ asc_get_status(asc, status, ss, ir)
                printf("asc_get_status: fifo cnt %d\n", data); /* XXX */
                if (data < 2) {
                        asc->regs->asc_cmd = ASC_CMD_MSG_ACPT;
                printf("asc_get_status: fifo cnt %d\n", data); /* XXX */
                if (data < 2) {
                        asc->regs->asc_cmd = ASC_CMD_MSG_ACPT;
+                       readback(asc->regs->asc_cmd);
                        return (0);
                }
                do {
                        return (0);
                }
                do {
@@ -1020,6 +1125,7 @@ asc_end(asc, status, ss, ir)
                if (!asc->cmd[i] || !(asc->st[i].flags & DISCONN))
                        continue;
                asc->regs->asc_cmd = ASC_CMD_ENABLE_SEL;
                if (!asc->cmd[i] || !(asc->st[i].flags & DISCONN))
                        continue;
                asc->regs->asc_cmd = ASC_CMD_ENABLE_SEL;
+               readback(asc->regs->asc_cmd);
                asc->state = ASC_STATE_RESEL;
                asc->script = &asc_scripts[SCRIPT_RESEL];
                break;
                asc->state = ASC_STATE_RESEL;
                asc->script = &asc_scripts[SCRIPT_RESEL];
                break;
@@ -1058,6 +1164,7 @@ asc_dma_in(asc, status, ss, ir)
                 * There may be some bytes in the FIFO if synchonous transfers
                 * are in progress.
                 */
                 * There may be some bytes in the FIFO if synchonous transfers
                 * are in progress.
                 */
+               (*asc->dma_end)(asc, state, ASCDMA_READ);
                ASC_TC_GET(regs, len);
                len = state->dmalen - len;
                bcopy(state->dmaBufAddr, state->buf, len);
                ASC_TC_GET(regs, len);
                len = state->dmalen - len;
                bcopy(state->dmaBufAddr, state->buf, len);
@@ -1070,7 +1177,7 @@ asc_dma_in(asc, status, ss, ir)
        if (len > state->dmaBufSize)
                len = state->dmaBufSize;
        state->dmalen = len;
        if (len > state->dmaBufSize)
                len = state->dmaBufSize;
        state->dmalen = len;
-       *asc->dmar = ASC_DMA_ADDR(state->dmaBufAddr);
+       (*asc->dma_start)(asc, state, state->dmaBufAddr, ASCDMA_READ);
        ASC_TC_PUT(regs, len);
 #ifdef DEBUG
        if (asc_debug > 2)
        ASC_TC_PUT(regs, len);
 #ifdef DEBUG
        if (asc_debug > 2)
@@ -1081,6 +1188,7 @@ asc_dma_in(asc, status, ss, ir)
        state->flags |= DMA_IN_PROGRESS;
        if (len != state->buflen) {
                regs->asc_cmd = ASC_CMD_XFER_INFO | ASC_CMD_DMA;
        state->flags |= DMA_IN_PROGRESS;
        if (len != state->buflen) {
                regs->asc_cmd = ASC_CMD_XFER_INFO | ASC_CMD_DMA;
+               readback(regs->asc_cmd);
                asc->script = &asc_scripts[SCRIPT_CONTINUE_IN];
                return (0);
        }
                asc->script = &asc_scripts[SCRIPT_CONTINUE_IN];
                return (0);
        }
@@ -1098,6 +1206,7 @@ asc_last_dma_in(asc, status, ss, ir)
        register int len, fifo;
 
        /* copy data from buffer to main memory */
        register int len, fifo;
 
        /* copy data from buffer to main memory */
+       (*asc->dma_end)(asc, state, ASCDMA_READ);
        ASC_TC_GET(regs, len);
        fifo = regs->asc_flags & ASC_FLAGS_FIFO_CNT;
 #ifdef DEBUG
        ASC_TC_GET(regs, len);
        fifo = regs->asc_flags & ASC_FLAGS_FIFO_CNT;
 #ifdef DEBUG
@@ -1108,6 +1217,7 @@ asc_last_dma_in(asc, status, ss, ir)
        if (fifo) {
                /* device must be trying to send more than we expect */
                regs->asc_cmd = ASC_CMD_FLUSH;
        if (fifo) {
                /* device must be trying to send more than we expect */
                regs->asc_cmd = ASC_CMD_FLUSH;
+               readback(regs->asc_cmd);
                MachEmptyWriteBuffer();
        }
        state->flags &= ~DMA_IN_PROGRESS;
                MachEmptyWriteBuffer();
        }
        state->flags &= ~DMA_IN_PROGRESS;
@@ -1133,7 +1243,7 @@ asc_resume_in(asc, status, ss, ir)
        if (len > state->dmaBufSize)
                len = state->dmaBufSize;
        state->dmalen = len;
        if (len > state->dmaBufSize)
                len = state->dmaBufSize;
        state->dmalen = len;
-       *asc->dmar = ASC_DMA_ADDR(state->dmaBufAddr);
+       (*asc->dma_start)(asc, state, state->dmaBufAddr, ASCDMA_READ);
        ASC_TC_PUT(regs, len);
 #ifdef DEBUG
        if (asc_debug > 2)
        ASC_TC_PUT(regs, len);
 #ifdef DEBUG
        if (asc_debug > 2)
@@ -1145,6 +1255,7 @@ asc_resume_in(asc, status, ss, ir)
        state->flags |= DMA_IN_PROGRESS;
        if (len != state->buflen) {
                regs->asc_cmd = ASC_CMD_XFER_INFO | ASC_CMD_DMA;
        state->flags |= DMA_IN_PROGRESS;
        if (len != state->buflen) {
                regs->asc_cmd = ASC_CMD_XFER_INFO | ASC_CMD_DMA;
+               readback(regs->asc_cmd);
                asc->script = &asc_scripts[SCRIPT_CONTINUE_IN];
                return (0);
        }
                asc->script = &asc_scripts[SCRIPT_CONTINUE_IN];
                return (0);
        }
@@ -1169,7 +1280,7 @@ asc_resume_dma_in(asc, status, ss, ir)
                        state->dmalen, len, off); /* XXX */
                regs->asc_res_fifo = state->dmaBufAddr[off];
        }
                        state->dmalen, len, off); /* XXX */
                regs->asc_res_fifo = state->dmaBufAddr[off];
        }
-       *asc->dmar = ASC_DMA_ADDR(state->dmaBufAddr + off);
+       (*asc->dma_start)(asc, state, state->dmaBufAddr + off, ASCDMA_READ);
        ASC_TC_PUT(regs, len);
 #ifdef DEBUG
        if (asc_debug > 2)
        ASC_TC_PUT(regs, len);
 #ifdef DEBUG
        if (asc_debug > 2)
@@ -1181,6 +1292,7 @@ asc_resume_dma_in(asc, status, ss, ir)
        state->flags |= DMA_IN_PROGRESS;
        if (state->dmalen != state->buflen) {
                regs->asc_cmd = ASC_CMD_XFER_INFO | ASC_CMD_DMA;
        state->flags |= DMA_IN_PROGRESS;
        if (state->dmalen != state->buflen) {
                regs->asc_cmd = ASC_CMD_XFER_INFO | ASC_CMD_DMA;
+               readback(regs->asc_cmd);
                asc->script = &asc_scripts[SCRIPT_CONTINUE_IN];
                return (0);
        }
                asc->script = &asc_scripts[SCRIPT_CONTINUE_IN];
                return (0);
        }
@@ -1216,7 +1328,7 @@ asc_dma_out(asc, status, ss, ir)
                len = state->dmaBufSize;
        state->dmalen = len;
        bcopy(state->buf, state->dmaBufAddr, len);
                len = state->dmaBufSize;
        state->dmalen = len;
        bcopy(state->buf, state->dmaBufAddr, len);
-       *asc->dmar = ASC_DMAR_WRITE | ASC_DMA_ADDR(state->dmaBufAddr);
+       (*asc->dma_start)(asc, state, state->dmaBufAddr, ASCDMA_WRITE);
        ASC_TC_PUT(regs, len);
 #ifdef DEBUG
        if (asc_debug > 2)
        ASC_TC_PUT(regs, len);
 #ifdef DEBUG
        if (asc_debug > 2)
@@ -1227,6 +1339,7 @@ asc_dma_out(asc, status, ss, ir)
        state->flags |= DMA_IN_PROGRESS;
        if (len != state->buflen) {
                regs->asc_cmd = ASC_CMD_XFER_INFO | ASC_CMD_DMA;
        state->flags |= DMA_IN_PROGRESS;
        if (len != state->buflen) {
                regs->asc_cmd = ASC_CMD_XFER_INFO | ASC_CMD_DMA;
+               readback(regs->asc_cmd);
                asc->script = &asc_scripts[SCRIPT_CONTINUE_OUT];
                return (0);
        }
                asc->script = &asc_scripts[SCRIPT_CONTINUE_OUT];
                return (0);
        }
@@ -1253,6 +1366,7 @@ asc_last_dma_out(asc, status, ss, ir)
        if (fifo) {
                len += fifo;
                regs->asc_cmd = ASC_CMD_FLUSH;
        if (fifo) {
                len += fifo;
                regs->asc_cmd = ASC_CMD_FLUSH;
+               readback(regs->asc_cmd);
                MachEmptyWriteBuffer();
        }
        state->flags &= ~DMA_IN_PROGRESS;
                MachEmptyWriteBuffer();
        }
        state->flags &= ~DMA_IN_PROGRESS;
@@ -1277,7 +1391,7 @@ asc_resume_out(asc, status, ss, ir)
                len = state->dmaBufSize;
        state->dmalen = len;
        bcopy(state->buf, state->dmaBufAddr, len);
                len = state->dmaBufSize;
        state->dmalen = len;
        bcopy(state->buf, state->dmaBufAddr, len);
-       *asc->dmar = ASC_DMAR_WRITE | ASC_DMA_ADDR(state->dmaBufAddr);
+       (*asc->dma_start)(asc, state, state->dmaBufAddr, ASCDMA_WRITE);
        ASC_TC_PUT(regs, len);
 #ifdef DEBUG
        if (asc_debug > 2)
        ASC_TC_PUT(regs, len);
 #ifdef DEBUG
        if (asc_debug > 2)
@@ -1289,6 +1403,7 @@ asc_resume_out(asc, status, ss, ir)
        state->flags |= DMA_IN_PROGRESS;
        if (len != state->buflen) {
                regs->asc_cmd = ASC_CMD_XFER_INFO | ASC_CMD_DMA;
        state->flags |= DMA_IN_PROGRESS;
        if (len != state->buflen) {
                regs->asc_cmd = ASC_CMD_XFER_INFO | ASC_CMD_DMA;
+               readback(regs->asc_cmd);
                asc->script = &asc_scripts[SCRIPT_CONTINUE_OUT];
                return (0);
        }
                asc->script = &asc_scripts[SCRIPT_CONTINUE_OUT];
                return (0);
        }
@@ -1315,7 +1430,7 @@ asc_resume_dma_out(asc, status, ss, ir)
                off++;
                len--;
        }
                off++;
                len--;
        }
-       *asc->dmar = ASC_DMAR_WRITE | ASC_DMA_ADDR(state->dmaBufAddr + off);
+       (*asc->dma_start)(asc, state, state->dmaBufAddr + off, ASCDMA_WRITE);
        ASC_TC_PUT(regs, len);
 #ifdef DEBUG
        if (asc_debug > 2)
        ASC_TC_PUT(regs, len);
 #ifdef DEBUG
        if (asc_debug > 2)
@@ -1327,6 +1442,7 @@ asc_resume_dma_out(asc, status, ss, ir)
        state->flags |= DMA_IN_PROGRESS;
        if (state->dmalen != state->buflen) {
                regs->asc_cmd = ASC_CMD_XFER_INFO | ASC_CMD_DMA;
        state->flags |= DMA_IN_PROGRESS;
        if (state->dmalen != state->buflen) {
                regs->asc_cmd = ASC_CMD_XFER_INFO | ASC_CMD_DMA;
+               readback(regs->asc_cmd);
                asc->script = &asc_scripts[SCRIPT_CONTINUE_OUT];
                return (0);
        }
                asc->script = &asc_scripts[SCRIPT_CONTINUE_OUT];
                return (0);
        }
@@ -1370,7 +1486,7 @@ asc_replysync(asc, status, ss, ir)
 #ifdef DEBUG
        if (asc_debug > 2)
                printf("asc_replysync: %x %x\n",
 #ifdef DEBUG
        if (asc_debug > 2)
                printf("asc_replysync: %x %x\n",
-                       asc_to_scsi_period[state->sync_period],
+                       asc_to_scsi_period[state->sync_period] * asc->tb_ticks,
                        state->sync_offset);
 #endif
        /* send synchronous transfer in response to a request */
                        state->sync_offset);
 #endif
        /* send synchronous transfer in response to a request */
@@ -1380,10 +1496,11 @@ asc_replysync(asc, status, ss, ir)
        MachEmptyWriteBuffer();
        regs->asc_fifo = SCSI_SYNCHRONOUS_XFER;
        MachEmptyWriteBuffer();
        MachEmptyWriteBuffer();
        regs->asc_fifo = SCSI_SYNCHRONOUS_XFER;
        MachEmptyWriteBuffer();
-       regs->asc_fifo = asc_to_scsi_period[state->sync_period];
+       regs->asc_fifo = asc_to_scsi_period[state->sync_period] * asc->tb_ticks;
        MachEmptyWriteBuffer();
        regs->asc_fifo = state->sync_offset;
        regs->asc_cmd = ASC_CMD_XFER_INFO;
        MachEmptyWriteBuffer();
        regs->asc_fifo = state->sync_offset;
        regs->asc_cmd = ASC_CMD_XFER_INFO;
+       readback(regs->asc_cmd);
 
        /* return to the appropriate script */
        if (!state->script) {
 
        /* return to the appropriate script */
        if (!state->script) {
@@ -1446,17 +1563,17 @@ asc_msg_in(asc, status, ss, ir)
                        state->sync_offset = state->msg_in[2];
 
                        /* convert SCSI period to ASC period */
                        state->sync_offset = state->msg_in[2];
 
                        /* convert SCSI period to ASC period */
-                       i = state->msg_in[1] / 10;
-                       if (i < ASC_MIN_PERIOD)
-                               i = ASC_MIN_PERIOD;
-                       else if (i >= ASC_MAX_PERIOD) {
+                       i = state->msg_in[1] / asc->tb_ticks;
+                       if (i < asc->min_period)
+                               i = asc->min_period;
+                       else if (i >= asc->max_period) {
                                /* can't do sync transfer, period too long */
                                printf("asc%d: SCSI device %d: sync xfer period too long (%d)\n",
                                        asc - asc_softc, asc->target, i);
                                /* can't do sync transfer, period too long */
                                printf("asc%d: SCSI device %d: sync xfer period too long (%d)\n",
                                        asc - asc_softc, asc->target, i);
-                               i = ASC_MAX_PERIOD;
+                               i = asc->max_period;
                                state->sync_offset = 0;
                        }
                                state->sync_offset = 0;
                        }
-                       if ((i * 10) != state->msg_in[1])
+                       if ((i * asc->tb_ticks) != state->msg_in[1])
                                i++;
                        state->sync_period = i & 0x1F;
 
                                i++;
                        state->sync_period = i & 0x1F;
 
@@ -1466,23 +1583,29 @@ asc_msg_in(asc, status, ss, ir)
                         */
                        if (!(state->flags & TRY_SYNC)) {
                                regs->asc_cmd = ASC_CMD_SET_ATN;
                         */
                        if (!(state->flags & TRY_SYNC)) {
                                regs->asc_cmd = ASC_CMD_SET_ATN;
+                               readback(regs->asc_cmd);
                                MachEmptyWriteBuffer();
 
                                MachEmptyWriteBuffer();
 
-                               if (state->sync_period < ASC_MIN_PERIOD)
+                               if (state->sync_period < asc->min_period)
                                        state->sync_period =
                                        state->sync_period =
-                                               ASC_MIN_PERIOD;
+                                               asc->min_period;
                                if (state->sync_offset > ASC_MAX_OFFSET)
                                        state->sync_offset =
                                                ASC_MAX_OFFSET;
                                asc->script = &asc_scripts[SCRIPT_REPLY_SYNC];
                                regs->asc_syn_p = state->sync_period;
                                if (state->sync_offset > ASC_MAX_OFFSET)
                                        state->sync_offset =
                                                ASC_MAX_OFFSET;
                                asc->script = &asc_scripts[SCRIPT_REPLY_SYNC];
                                regs->asc_syn_p = state->sync_period;
+                               readback(regs->asc_syn_p);
                                regs->asc_syn_o = state->sync_offset;
                                regs->asc_syn_o = state->sync_offset;
+                               readback(regs->asc_syn_o);
                                regs->asc_cmd = ASC_CMD_MSG_ACPT;
                                regs->asc_cmd = ASC_CMD_MSG_ACPT;
+                               readback(regs->asc_cmd);
                                return (0);
                        }
 
                        regs->asc_syn_p = state->sync_period;
                                return (0);
                        }
 
                        regs->asc_syn_p = state->sync_period;
+                       readback(regs->asc_syn_p);
                        regs->asc_syn_o = state->sync_offset;
                        regs->asc_syn_o = state->sync_offset;
+                       readback(regs->asc_syn_o);
                        goto done;
 
                default:
                        goto done;
 
                default:
@@ -1504,12 +1627,14 @@ asc_msg_in(asc, status, ss, ir)
                printf(" did not like SYNCH xfer "); /* XXX */
                state->flags |= DID_SYNC;
                regs->asc_cmd = ASC_CMD_MSG_ACPT;
                printf(" did not like SYNCH xfer "); /* XXX */
                state->flags |= DID_SYNC;
                regs->asc_cmd = ASC_CMD_MSG_ACPT;
+               readback(regs->asc_cmd);
                status = asc_wait(regs, ASC_CSR_INT);
                ir = regs->asc_intr;
                /* some just break out here, some dont */
                if (ASC_PHASE(status) == ASC_PHASE_MSG_OUT) {
                        regs->asc_fifo = SCSI_ABORT;
                        regs->asc_cmd = ASC_CMD_XFER_INFO;
                status = asc_wait(regs, ASC_CSR_INT);
                ir = regs->asc_intr;
                /* some just break out here, some dont */
                if (ASC_PHASE(status) == ASC_PHASE_MSG_OUT) {
                        regs->asc_fifo = SCSI_ABORT;
                        regs->asc_cmd = ASC_CMD_XFER_INFO;
+                       readback(regs->asc_cmd);
                        status = asc_wait(regs, ASC_CSR_INT);
                        ir = regs->asc_intr;
                }
                        status = asc_wait(regs, ASC_CSR_INT);
                        ir = regs->asc_intr;
                }
@@ -1546,6 +1671,7 @@ asc_msg_in(asc, status, ss, ir)
                        goto abort;
                state->flags |= DISCONN;
                regs->asc_cmd = ASC_CMD_MSG_ACPT;
                        goto abort;
                state->flags |= DISCONN;
                regs->asc_cmd = ASC_CMD_MSG_ACPT;
+               readback(regs->asc_cmd);
                asc->script = &asc_scripts[SCRIPT_DISCONNECT];
                return (0);
 
                asc->script = &asc_scripts[SCRIPT_DISCONNECT];
                return (0);
 
@@ -1556,12 +1682,14 @@ asc_msg_in(asc, status, ss, ir)
                /* request a message out before acknowledging this message */
                state->msg_out = SCSI_MESSAGE_REJECT;
                regs->asc_cmd = ASC_CMD_SET_ATN;
                /* request a message out before acknowledging this message */
                state->msg_out = SCSI_MESSAGE_REJECT;
                regs->asc_cmd = ASC_CMD_SET_ATN;
+               readback(regs->asc_cmd);
                MachEmptyWriteBuffer();
        }
 
 done:
        /* return to original script */
        regs->asc_cmd = ASC_CMD_MSG_ACPT;
                MachEmptyWriteBuffer();
        }
 
 done:
        /* return to original script */
        regs->asc_cmd = ASC_CMD_MSG_ACPT;
+       readback(regs->asc_cmd);
        if (!state->script) {
        abort:
 #ifdef DEBUG
        if (!state->script) {
        abort:
 #ifdef DEBUG
@@ -1587,6 +1715,132 @@ asc_disconnect(asc, status, ss, ir)
        return (1);
 }
 
        return (1);
 }
 
+/*
+ * DMA handling routines. For a turbochannel device, just set the dmar
+ * for the I/O ASIC, handle the actual DMA interface.
+ */
+static void
+tb_dma_start(asc, state, cp, flag)
+       asc_softc_t asc;
+       State *state;
+       caddr_t cp;
+       int flag;
+{
+
+       if (flag == ASCDMA_WRITE)
+               *asc->dmar = ASC_DMAR_WRITE | ASC_DMA_ADDR(cp);
+       else
+               *asc->dmar = ASC_DMA_ADDR(cp);
+}
+
+static void
+tb_dma_end(asc, state, flag)
+       asc_softc_t asc;
+       State *state;
+       int flag;
+{
+
+}
+
+static void
+asic_dma_start(asc, state, cp, flag)
+       asc_softc_t asc;
+       State *state;
+       caddr_t cp;
+       int flag;
+{
+       register volatile u_int *ssr = (volatile u_int *)
+               MACH_PHYS_TO_UNCACHED(KMIN_REG_CSR);
+       u_int phys, nphys;
+
+       /* stop DMA engine first */
+       *ssr &= ~ASIC_CSR_DMAEN_SCSI;
+       * ((volatile int *)MACH_PHYS_TO_UNCACHED(KMIN_REG_SCSI_SCR)) = 0;
+
+       phys = MACH_CACHED_TO_PHYS(cp);
+       cp = (caddr_t)pmax_trunc_page(cp + NBPG);
+       nphys = MACH_CACHED_TO_PHYS(cp);
+
+       asc->dma_next = cp;
+       asc->dma_xfer = state->dmalen - (nphys - phys);
+
+       *(volatile int *)MACH_PHYS_TO_UNCACHED(KMIN_REG_SCSI_DMAPTR) =
+               ASIC_DMA_ADDR(phys);
+       *(volatile int *)MACH_PHYS_TO_UNCACHED(KMIN_REG_SCSI_DMANPTR) =
+               ASIC_DMA_ADDR(nphys);
+       if (flag == ASCDMA_READ)
+               *ssr |= ASIC_CSR_SCSI_DIR | ASIC_CSR_DMAEN_SCSI;
+       else
+               *ssr = (*ssr & ~ASIC_CSR_SCSI_DIR) | ASIC_CSR_DMAEN_SCSI;
+       MachEmptyWriteBuffer();
+}
+
+static void
+asic_dma_end(asc, state, flag)
+       asc_softc_t asc;
+       State *state;
+       int flag;
+{
+       register volatile u_int *ssr = (volatile u_int *)
+               MACH_PHYS_TO_UNCACHED(KMIN_REG_CSR);
+       int nb;
+
+       *ssr &= ~ASIC_CSR_DMAEN_SCSI;
+       *((volatile int *)MACH_PHYS_TO_UNCACHED(KMIN_REG_SCSI_DMAPTR)) = -1;
+       *((volatile int *)MACH_PHYS_TO_UNCACHED(KMIN_REG_SCSI_DMANPTR)) = -1;
+       MachEmptyWriteBuffer();
+
+       if (flag == ASCDMA_READ) {
+               MachFlushDCache(MACH_PHYS_TO_CACHED(
+                   MACH_UNCACHED_TO_PHYS(state->dmaBufAddr)), state->dmalen);
+               if (nb = *((int *)MACH_PHYS_TO_UNCACHED(KMIN_REG_SCSI_SCR))) {
+                       /* pick up last upto6 bytes, sigh. */
+                       register u_short *to;
+                       register int w;
+       
+                       /* Last byte really xferred is.. */
+                       to = (u_short *)(state->dmaBufAddr + state->dmalen - (nb << 1));
+                       w = *(int *)MACH_PHYS_TO_UNCACHED(KMIN_REG_SCSI_SDR0);
+                       *to++ = w;
+                       if (--nb > 0) {
+                               w >>= 16;
+                               *to++ = w;
+                       }
+                       if (--nb > 0) {
+                               w = *(int *)MACH_PHYS_TO_UNCACHED(KMIN_REG_SCSI_SDR1);
+                               *to++ = w;
+                       }
+               }
+       }
+}
+
+/*
+ * Called by asic_intr() for scsi dma pointer update interrupts.
+ */
+void
+asc_dma_intr()
+{
+       asc_softc_t asc = &asc_softc[0];
+       u_int next_phys;
+
+       asc->dma_xfer -= NBPG;
+       if (asc->dma_xfer <= -NBPG) {
+               volatile u_int *ssr = (volatile u_int *)
+                       MACH_PHYS_TO_UNCACHED(KMIN_REG_CSR);
+               *ssr &= ~ASIC_CSR_DMAEN_SCSI;
+       } else {
+               asc->dma_next += NBPG;
+               next_phys = MACH_CACHED_TO_PHYS(asc->dma_next);
+       }
+#ifdef notdef
+       else
+               next_phys = MACH_CACHED_TO_PHYS(asc_iobuf);
+#endif
+       *(volatile int *)MACH_PHYS_TO_UNCACHED(KMIN_REG_SCSI_DMANPTR) =
+               ASIC_DMA_ADDR(next_phys);
+       MachEmptyWriteBuffer();
+}
+
 #ifdef DEBUG
 asc_DumpLog(str)
        char *str;
 #ifdef DEBUG
 asc_DumpLog(str)
        char *str;
index 5522b09..2588dd9 100644 (file)
@@ -3,11 +3,11 @@
  * All rights reserved.
  *
  * This code is derived from software contributed to Berkeley by
  * All rights reserved.
  *
  * This code is derived from software contributed to Berkeley by
- * Ralph Campbell.
+ * Ralph Campbell and Rick Macklem.
  *
  * %sccs.include.redist.c%
  *
  *
  * %sccs.include.redist.c%
  *
- *     @(#)ascreg.h    7.1 (Berkeley) %G%
+ *     @(#)ascreg.h    7.2 (Berkeley) %G%
  */
 
 /* 
  */
 
 /* 
@@ -121,7 +121,7 @@ typedef volatile struct {
 #define ASC_TC_PUT(ptr, val)                           \
        (ptr)->asc_tc_lsb = (val);                      \
        (ptr)->asc_tc_msb = (val) >> 8;                 \
 #define ASC_TC_PUT(ptr, val)                           \
        (ptr)->asc_tc_lsb = (val);                      \
        (ptr)->asc_tc_msb = (val) >> 8;                 \
-       (ptr)->asc_cmd = ASC_CMD_NOP;
+       (ptr)->asc_cmd = ASC_CMD_NOP | ASC_CMD_DMA;
 
 /*
  * Command register (command codes)
 
 /*
  * Command register (command codes)
@@ -209,7 +209,7 @@ typedef volatile struct {
  *     val = (timeout * CLK_freq) / (8192 * CCF);
  */
 
  *     val = (timeout * CLK_freq) / (8192 * CCF);
  */
 
-#define        ASC_TIMEOUT_250         0x99    /* 250 msecs at 25 Mhz */
+#define        ASC_TIMEOUT_250(clk, ccf)       (((clk) * 31) / (ccf))
 
 /*
  * Sequence Step register
 
 /*
  * Sequence Step register
@@ -256,10 +256,7 @@ typedef volatile struct {
  * CCF register
  */
 
  * CCF register
  */
 
-#define ASC_CCF_10MHz          0x2
-#define ASC_CCF_15MHz          0x3
-#define ASC_CCF_20MHz          0x4
-#define ASC_CCF_25MHz          0x5
+#define        ASC_CCF(clk)            ((((clk) - 1) / 5) + 1)
 
 /*
  * Test register
 
 /*
  * Test register
index f5c5bd4..de089f2 100644 (file)
@@ -3,11 +3,11 @@
  * All rights reserved.
  *
  * This code is derived from software contributed to Berkeley by
  * All rights reserved.
  *
  * This code is derived from software contributed to Berkeley by
- * Ralph Campbell.
+ * Ralph Campbell and Rick Macklem.
  *
  * %sccs.include.redist.c%
  *
  *
  * %sccs.include.redist.c%
  *
- *     @(#)cfb.c       7.4 (Berkeley) %G%
+ *     @(#)cfb.c       7.5 (Berkeley) %G%
  */
 
 /*
  */
 
 /*
  * rights to redistribute these changes.
  */
 
  * rights to redistribute these changes.
  */
 
-#include "cfb.h"
+#include <cfb.h>
 #if NCFB > 0
 #if NCFB > 0
-
-/*
- * This is a device driver for the PMAG-BA color frame buffer
- * on the TURBOchannel.
- * XXX This is just to get a console working;
- *     it will need changes to work with X11R5.
- */
-
 #include <sys/param.h>
 #include <sys/time.h>
 #include <sys/kernel.h>
 #include <sys/param.h>
 #include <sys/time.h>
 #include <sys/kernel.h>
 #include <vm/vm.h>
 
 #include <machine/machConst.h>
 #include <vm/vm.h>
 
 #include <machine/machConst.h>
-#include <machine/machMon.h>
-#include <machine/dc7085cons.h>
 #include <machine/pmioctl.h>
 
 #include <machine/pmioctl.h>
 
+#include <pmax/pmax/maxine.h>
+#include <pmax/pmax/cons.h>
+#include <pmax/pmax/pmaxtype.h>
+
 #include <pmax/dev/device.h>
 #include <pmax/dev/cfbreg.h>
 #include <pmax/dev/device.h>
 #include <pmax/dev/cfbreg.h>
-#include <pmax/dev/font.c>
+#include <pmax/dev/fbreg.h>
 
 
-#define MAX_ROW        56
-#define MAX_COL        80
-
-/*
- * Macro to translate from a time struct to milliseconds.
- */
-#define TO_MS(tv) ((tv.tv_sec * 1000) + (tv.tv_usec / 1000))
-
-static int     isMono;         /* true if B&W frame buffer */
-static int     initialized;    /* true if 'probe' was successful */
-static int     GraphicsOpen;   /* true if the graphics device is open */
-static int     row, col;       /* row and col for console cursor */
-static struct  selinfo cfb_selp;       /* process waiting for select */
-static unsigned        fb_addr;        /* frame buffer kernel virtual address */
-static unsigned        planemask_addr; /* plane mask kernel virtual address */
+#include <dc.h>
+#include <dtop.h>
+#include <scc.h>
 
 /*
  * These need to be mapped into user space.
  */
 
 /*
  * These need to be mapped into user space.
  */
-static struct pmuaccess {
-       PM_Info         scrInfo;
-       pmEvent         events[PM_MAXEVQ];      
-       pmTimeCoord     tcs[MOTION_BUFFER_SIZE];
-} pmu;
-
-/*
- * Font mask bits used by Blitc().
- */
-static unsigned int fontmaskBits[16] = {
-       0x00000000,
-       0x00000001,
-       0x00000100,
-       0x00000101,
-       0x00010000,
-       0x00010001,
-       0x00010100,
-       0x00010101,
-       0x01000000,
-       0x01000001,
-       0x01000100,
-       0x01000101,
-       0x01010000,
-       0x01010001,
-       0x01010100,
-       0x01010101
-};
+struct fbuaccess cfbu;
+struct pmax_fb cfbfb;
 
 /*
  * Forward references.
  */
 
 /*
  * Forward references.
  */
-static void Scroll();
-static void Blitc();
-
-static void ScreenInit();
-static void LoadCursor();
-static void RestoreCursorColor();
-static void CursorColor();
-static void PosCursor();
-static void InitColorMap();
-static void LoadColorMap();
-static void EnableVideo();
-static void DisableVideo();
-
-extern void dcKBDPutc();
+extern void fbScroll();
+
+static void cfbScreenInit();
+static void cfbLoadCursor();
+static void cfbRestoreCursorColor();
+static void cfbCursorColor();
+void cfbPosCursor();
+static void cfbInitColorMap();
+static void cfbLoadColorMap();
+static void bt459_set_cursor_ram(), bt459_video_on(), bt459_video_off();
+static void bt459_select_reg(), bt459_write_reg();
+static u_char bt459_read_reg();
+static void cfbConfigMouse(), cfbDeconfigMouse();
+
+extern void fbKbdEvent(), fbMouseEvent(), fbMouseButtons();
+void cfbKbdEvent(), cfbMouseEvent(), cfbMouseButtons();
+#if NDC > 0
+#include <machine/dc7085cons.h>
+extern void dcPutc();
 extern void (*dcDivertXInput)();
 extern void (*dcMouseEvent)();
 extern void (*dcMouseButtons)();
 extern void (*dcDivertXInput)();
 extern void (*dcMouseEvent)();
 extern void (*dcMouseButtons)();
+#endif
+#if NSCC > 0
+#include <pmax/dev/sccreg.h>
+extern void sccPutc();
+extern void (*sccDivertXInput)();
+extern void (*sccMouseEvent)();
+extern void (*sccMouseButtons)();
+#endif
+#if NDTOP > 0
+#include <pmax/dev/dtopreg.h>
+extern void dtopKBDPutc();
+extern void (*dtopDivertXInput)();
+extern void (*dtopMouseEvent)();
+extern void (*dtopMouseButtons)();
+#endif
+extern int pmax_boardtype;
+extern u_short defCursor[32];
+extern struct consdev cn_tab;
 
 int    cfbprobe();
 struct driver cfbdriver = {
        "cfb", cfbprobe, 0, 0,
 };
 
 
 int    cfbprobe();
 struct driver cfbdriver = {
        "cfb", cfbprobe, 0, 0,
 };
 
+#define        CFB_OFFSET_VRAM         0x0             /* from module's base */
+#define CFB_OFFSET_BT459       0x200000        /* Bt459 registers */
+#define CFB_OFFSET_IREQ                0x300000        /* Interrupt req. control */
+#define CFB_OFFSET_ROM         0x380000        /* Diagnostic ROM */
+#define CFB_OFFSET_RESET       0x3c0000        /* Bt459 resets on writes */
+
 /*
  * Test to see if device is present.
  * Return true if found and initialized ok.
  */
 /*
  * Test to see if device is present.
  * Return true if found and initialized ok.
  */
+/*ARGSUSED*/
 cfbprobe(cp)
        register struct pmax_ctlr *cp;
 {
 cfbprobe(cp)
        register struct pmax_ctlr *cp;
 {
+       register struct pmax_fb *fp = &cfbfb;
 
 
-       if (!initialized) {
-               if (!cfb_init(cp))
-                       return (0);
-       }
-       printf("cfb%d at nexus0 csr 0x%x priority %d\n",
-               cp->pmax_unit, cp->pmax_addr, cp->pmax_pri);
+       if (!fp->initialized && !cfbinit(cp->pmax_addr))
+               return (0);
+       printf("cfb0 (color display)\n");
        return (1);
 }
 
        return (1);
 }
 
-/*
- *----------------------------------------------------------------------
- *
- * cfbKbdEvent --
- *
- *     Process a received character.
- *
- * Results:
- *     None.
- *
- * Side effects:
- *     Events added to the queue.
- *
- *----------------------------------------------------------------------
- */
-void
-cfbKbdEvent(ch)
-       int ch;
-{
-       register pmEvent *eventPtr;
-       int i;
-
-       if (!GraphicsOpen)
-               return;
-
-       /*
-        * See if there is room in the queue.
-        */
-       i = PM_EVROUND(pmu.scrInfo.qe.eTail + 1);
-       if (i == pmu.scrInfo.qe.eHead)
-               return;
-
-       /*
-        * Add the event to the queue.
-        */
-       eventPtr = &pmu.events[pmu.scrInfo.qe.eTail];
-       eventPtr->type = BUTTON_RAW_TYPE;
-       eventPtr->device = KEYBOARD_DEVICE;
-       eventPtr->x = pmu.scrInfo.mouse.x;
-       eventPtr->y = pmu.scrInfo.mouse.y;
-       eventPtr->time = TO_MS(time);
-       eventPtr->key = ch;
-       pmu.scrInfo.qe.eTail = i;
-       selwakeup(&cfb_selp);
-}
-
-/*
- *----------------------------------------------------------------------
- *
- * cfbMouseEvent --
- *
- *     Process a mouse event.
- *
- * Results:
- *     None.
- *
- * Side effects:
- *     An event is added to the event queue.
- *
- *----------------------------------------------------------------------
- */
-void
-cfbMouseEvent(newRepPtr) 
-       register MouseReport *newRepPtr;
-{
-       unsigned milliSec;
-       int i;
-       pmEvent *eventPtr;
-
-       if (!GraphicsOpen)
-               return;
-
-       milliSec = TO_MS(time);
-
-       /*
-        * Check to see if we have to accelerate the mouse
-        */
-       if (pmu.scrInfo.mscale >= 0) {
-               if (newRepPtr->dx >= pmu.scrInfo.mthreshold) {
-                       newRepPtr->dx +=
-                               (newRepPtr->dx - pmu.scrInfo.mthreshold) *
-                               pmu.scrInfo.mscale;
-               }
-               if (newRepPtr->dy >= pmu.scrInfo.mthreshold) {
-                       newRepPtr->dy +=
-                               (newRepPtr->dy - pmu.scrInfo.mthreshold) *
-                               pmu.scrInfo.mscale;
-               }
-       }
-
-       /*
-        * Update mouse position
-        */
-       if (newRepPtr->state & MOUSE_X_SIGN) {
-               pmu.scrInfo.mouse.x += newRepPtr->dx;
-               if (pmu.scrInfo.mouse.x > pmu.scrInfo.max_cur_x)
-                       pmu.scrInfo.mouse.x = pmu.scrInfo.max_cur_x;
-       } else {
-               pmu.scrInfo.mouse.x -= newRepPtr->dx;
-               if (pmu.scrInfo.mouse.x < pmu.scrInfo.min_cur_x)
-                       pmu.scrInfo.mouse.x = pmu.scrInfo.min_cur_x;
-       }
-       if (newRepPtr->state & MOUSE_Y_SIGN) {
-               pmu.scrInfo.mouse.y -= newRepPtr->dy;
-               if (pmu.scrInfo.mouse.y < pmu.scrInfo.min_cur_y)
-                       pmu.scrInfo.mouse.y = pmu.scrInfo.min_cur_y;
-       } else {
-               pmu.scrInfo.mouse.y += newRepPtr->dy;
-               if (pmu.scrInfo.mouse.y > pmu.scrInfo.max_cur_y)
-                       pmu.scrInfo.mouse.y = pmu.scrInfo.max_cur_y;
-       }
-
-       /*
-        * Move the hardware cursor.
-        */
-       PosCursor(pmu.scrInfo.mouse.x, pmu.scrInfo.mouse.y);
-
-       /*
-        * Store the motion event in the motion buffer.
-        */
-       pmu.tcs[pmu.scrInfo.qe.tcNext].time = milliSec;
-       pmu.tcs[pmu.scrInfo.qe.tcNext].x = pmu.scrInfo.mouse.x;
-       pmu.tcs[pmu.scrInfo.qe.tcNext].y = pmu.scrInfo.mouse.y;
-       if (++pmu.scrInfo.qe.tcNext >= MOTION_BUFFER_SIZE)
-               pmu.scrInfo.qe.tcNext = 0;
-       if (pmu.scrInfo.mouse.y < pmu.scrInfo.mbox.bottom &&
-           pmu.scrInfo.mouse.y >=  pmu.scrInfo.mbox.top &&
-           pmu.scrInfo.mouse.x < pmu.scrInfo.mbox.right &&
-           pmu.scrInfo.mouse.x >=  pmu.scrInfo.mbox.left)
-               return;
-
-       pmu.scrInfo.mbox.bottom = 0;
-       if (PM_EVROUND(pmu.scrInfo.qe.eTail + 1) == pmu.scrInfo.qe.eHead)
-               return;
-
-       i = PM_EVROUND(pmu.scrInfo.qe.eTail - 1);
-       if ((pmu.scrInfo.qe.eTail != pmu.scrInfo.qe.eHead) && 
-           (i != pmu.scrInfo.qe.eHead)) {
-               pmEvent *eventPtr;
-
-               eventPtr = &pmu.events[i];
-               if (eventPtr->type == MOTION_TYPE) {
-                       eventPtr->x = pmu.scrInfo.mouse.x;
-                       eventPtr->y = pmu.scrInfo.mouse.y;
-                       eventPtr->time = milliSec;
-                       eventPtr->device = MOUSE_DEVICE;
-                       return;
-               }
-       }
-       /*
-        * Put event into queue and wakeup any waiters.
-        */
-       eventPtr = &pmu.events[pmu.scrInfo.qe.eTail];
-       eventPtr->type = MOTION_TYPE;
-       eventPtr->time = milliSec;
-       eventPtr->x = pmu.scrInfo.mouse.x;
-       eventPtr->y = pmu.scrInfo.mouse.y;
-       eventPtr->device = MOUSE_DEVICE;
-       pmu.scrInfo.qe.eTail = PM_EVROUND(pmu.scrInfo.qe.eTail + 1);
-       selwakeup(&cfb_selp);
-}
-
-/*
- *----------------------------------------------------------------------
- *
- * cfbMouseButtons --
- *
- *     Process mouse buttons.
- *
- * Results:
- *     None.
- *
- * Side effects:
- *     None.
- *
- *----------------------------------------------------------------------
- */
-void
-cfbMouseButtons(newRepPtr)
-       MouseReport *newRepPtr;
-{
-       static char temp, oldSwitch, newSwitch;
-       int i, j;
-       pmEvent *eventPtr;
-       static MouseReport lastRep;
-
-       if (!GraphicsOpen)
-               return;
-
-       newSwitch = newRepPtr->state & 0x07;
-       oldSwitch = lastRep.state & 0x07;
-
-       temp = oldSwitch ^ newSwitch;
-       if (temp == 0)
-               return;
-       for (j = 1; j < 8; j <<= 1) {
-               if ((j & temp) == 0)
-                       continue;
-
-               /*
-                * Check for room in the queue
-                */
-               i = PM_EVROUND(pmu.scrInfo.qe.eTail+1);
-               if (i == pmu.scrInfo.qe.eHead)
-                       return;
-
-               /*
-                * Put event into queue.
-                */
-               eventPtr = &pmu.events[pmu.scrInfo.qe.eTail];
-
-               switch (j) {
-               case RIGHT_BUTTON:
-                       eventPtr->key = EVENT_RIGHT_BUTTON;
-                       break;
-
-               case MIDDLE_BUTTON:
-                       eventPtr->key = EVENT_MIDDLE_BUTTON;
-                       break;
-
-               case LEFT_BUTTON:
-                       eventPtr->key = EVENT_LEFT_BUTTON;
-               }
-               if (newSwitch & j)
-                       eventPtr->type = BUTTON_DOWN_TYPE;
-               else
-                       eventPtr->type = BUTTON_UP_TYPE;
-               eventPtr->device = MOUSE_DEVICE;
-
-               eventPtr->time = TO_MS(time);
-               eventPtr->x = pmu.scrInfo.mouse.x;
-               eventPtr->y = pmu.scrInfo.mouse.y;
-       }
-       pmu.scrInfo.qe.eTail = i;
-       selwakeup(&cfb_selp);
-
-       lastRep = *newRepPtr;
-       pmu.scrInfo.mswitches = newSwitch;
-}
-
-/*
- *----------------------------------------------------------------------
- *
- * Scroll --
- *
- *     Scroll the screen.
- *
- * Results:
- *     None.
- *
- * Side effects:
- *     None.
- *
- *----------------------------------------------------------------------
- */
-static void
-Scroll()
-{
-       register int *dest, *src;
-       register int *end;
-       register int temp0, temp1, temp2, temp3;
-       register int i, scanInc, lineCount;
-       int line;
-
-       /*
-        * If the mouse is on we don't scroll so that the bit map remains sane.
-        */
-       if (GraphicsOpen) {
-               row = 0;
-               return;
-       }
-
-       /*
-        *  The following is an optimization to cause the scrolling 
-        *  of text to be memory limited.  Basically the writebuffer is 
-        *  4 words (32 bits ea.) long so to achieve maximum speed we 
-        *  read and write in multiples of 4 words. We also limit the 
-        *  size to be MAX_COL characters for more speed. 
-        */
-       if (isMono) {
-               lineCount = 5;
-               line = 1920 * 2;
-               scanInc = 44;
-       } else {
-               lineCount = 40;
-               scanInc = 96;
-               line = 1920 * 8;
-       }
-       src = (int *)(fb_addr + line);
-       dest = (int *)(fb_addr);
-       end = (int *)(fb_addr + (60 * line) - line);
-       do {
-               i = 0;
-               do {
-                       temp0 = src[0];
-                       temp1 = src[1];
-                       temp2 = src[2];
-                       temp3 = src[3];
-                       dest[0] = temp0;
-                       dest[1] = temp1;
-                       dest[2] = temp2;
-                       dest[3] = temp3;
-                       dest += 4;
-                       src += 4;
-                       i++;
-               } while (i < lineCount);
-               src += scanInc;
-               dest += scanInc;
-       } while (src < end);
-
-       /* 
-        * Now zero out the last two lines 
-        */
-       bzero(fb_addr + (row * line), 3 * line);
-}
-
-/*
- *----------------------------------------------------------------------
- *
- * cfbPutc --
- *
- *     Write a character to the console.
- *
- * Results:
- *     None.
- *
- * Side effects:
- *     None.
- *
- *----------------------------------------------------------------------
- */
-cfbPutc(c)
-       register int c;
-{
-       int s;
-
-       s = splhigh();  /* in case we do any printf's at interrupt time */
-       if (initialized) {
-#ifdef DEBUG
-               /*
-                * If the HELP key is pressed, wait for another
-                * HELP key press to start/stop output.
-                */
-               if (dcDebugGetc() == LK_HELP) {
-                       while (dcDebugGetc() != LK_HELP)
-                               ;
-               }
-#endif
-               Blitc(c);
-       } else {
-               void (*f)() = (void (*)())MACH_MON_PUTCHAR;
-
-               (*f)(c);
-       }
-       splx(s);
-}
-
-/*
- *----------------------------------------------------------------------
- *
- * Blitc --
- *
- *     Write a character to the screen.
- *
- * Results:
- *     None.
- *
- * Side effects:
- *     None.
- *
- *----------------------------------------------------------------------
- */
-static void
-Blitc(c)
-       register int c;
-{
-       register char *bRow, *fRow;
-       register int i;
-       register int ote = isMono ? 256 : 1024; /* offset to table entry */
-       int colMult = isMono ? 1 : 8;
-
-       c &= 0xff;
-
-       switch (c) {
-       case '\t':
-               for (i = 8 - (col & 0x7); i > 0; i--)
-                       Blitc(' ');
-               break;
-
-       case '\r':
-               col = 0;
-               break;
-
-       case '\b':
-               col--;
-               if (col < 0)
-                       col = 0;
-               break;
-
-       case '\n':
-               if (row + 1 >= MAX_ROW)
-                       Scroll();
-               else
-                       row++;
-               col = 0;
-               break;
-
-       case '\007':
-               dcKBDPutc(LK_RING_BELL);
-               break;
-
-       default:
-               /*
-                * 0xA1 to 0xFD are the printable characters added with 8-bit
-                * support.
-                */
-               if (c < ' ' || c > '~' && c < 0xA1 || c > 0xFD)
-                       break;
-               /*
-                * If the next character will wrap around then 
-                * increment row counter or scroll screen.
-                */
-               if (col >= MAX_COL) {
-                       col = 0;
-                       if (row + 1 >= MAX_ROW)
-                               Scroll();
-                       else
-                               row++;
-               }
-               bRow = (char *)(fb_addr +
-                       (row * 15 & 0x3ff) * ote + col * colMult);
-               i = c - ' ';
-               /*
-                * This is to skip the (32) 8-bit 
-                * control chars, as well as DEL 
-                * and 0xA0 which aren't printable
-                */
-               if (c > '~')
-                       i -= 34; 
-               i *= 15;
-               fRow = (char *)((int)pmFont + i);
-
-               /* inline expansion for speed */
-               if (isMono) {
-                       *bRow = *fRow++; bRow += ote;
-                       *bRow = *fRow++; bRow += ote;
-                       *bRow = *fRow++; bRow += ote;
-                       *bRow = *fRow++; bRow += ote;
-                       *bRow = *fRow++; bRow += ote;
-                       *bRow = *fRow++; bRow += ote;
-                       *bRow = *fRow++; bRow += ote;
-                       *bRow = *fRow++; bRow += ote;
-                       *bRow = *fRow++; bRow += ote;
-                       *bRow = *fRow++; bRow += ote;
-                       *bRow = *fRow++; bRow += ote;
-                       *bRow = *fRow++; bRow += ote;
-                       *bRow = *fRow++; bRow += ote;
-                       *bRow = *fRow++; bRow += ote;
-                       *bRow = *fRow++; bRow += ote;
-               } else {
-                       register int j;
-                       register unsigned int *pInt;
-
-                       pInt = (unsigned int *)bRow;
-                       for (j = 0; j < 15; j++) {
-                               /*
-                                * fontmaskBits converts a nibble
-                                * (4 bytes) to a long word 
-                                * containing 4 pixels corresponding
-                                * to each bit in the nibble.  Thus
-                                * we write two longwords for each
-                                * byte in font.
-                                * 
-                                * Remember the font is 8 bits wide
-                                * and 15 bits high.
-                                *
-                                * We add 256 to the pointer to
-                                * point to the pixel on the 
-                                * next scan line
-                                * directly below the current
-                                * pixel.
-                                */
-                               pInt[0] = fontmaskBits[(*fRow) & 0xf];
-                               pInt[1] = fontmaskBits[((*fRow) >> 4) & 0xf];
-                               fRow++; 
-                               pInt += 256;
-                       }
-               }
-               col++; /* increment column counter */
-       }
-       if (!GraphicsOpen)
-               PosCursor(col * 8, row * 15);
-}
-
 /*ARGSUSED*/
 cfbopen(dev, flag)
        dev_t dev;
        int flag;
 {
 /*ARGSUSED*/
 cfbopen(dev, flag)
        dev_t dev;
        int flag;
 {
+       register struct pmax_fb *fp = &cfbfb;
+       int s;
 
 
-       if (!initialized)
+       if (!fp->initialized)
                return (ENXIO);
                return (ENXIO);
-       if (GraphicsOpen)
+       if (fp->GraphicsOpen)
                return (EBUSY);
 
                return (EBUSY);
 
-       GraphicsOpen = 1;
-       if (!isMono)
-               InitColorMap();
+       fp->GraphicsOpen = 1;
+       cfbInitColorMap();
        /*
         * Set up event queue for later
         */
        /*
         * Set up event queue for later
         */
-       pmu.scrInfo.qe.eSize = PM_MAXEVQ;
-       pmu.scrInfo.qe.eHead = pmu.scrInfo.qe.eTail = 0;
-       pmu.scrInfo.qe.tcSize = MOTION_BUFFER_SIZE;
-       pmu.scrInfo.qe.tcNext = 0;
-       pmu.scrInfo.qe.timestamp_ms = TO_MS(time);
+       fp->fbu->scrInfo.qe.eSize = PM_MAXEVQ;
+       fp->fbu->scrInfo.qe.eHead = fp->fbu->scrInfo.qe.eTail = 0;
+       fp->fbu->scrInfo.qe.tcSize = MOTION_BUFFER_SIZE;
+       fp->fbu->scrInfo.qe.tcNext = 0;
+       fp->fbu->scrInfo.qe.timestamp_ms = TO_MS(time);
+       cfbConfigMouse();
        return (0);
 }
 
        return (0);
 }
 
@@ -696,23 +189,19 @@ cfbclose(dev, flag)
        dev_t dev;
        int flag;
 {
        dev_t dev;
        int flag;
 {
+       register struct pmax_fb *fp = &cfbfb;
        int s;
 
        int s;
 
-       if (!GraphicsOpen)
+       if (!fp->GraphicsOpen)
                return (EBADF);
 
                return (EBADF);
 
-       GraphicsOpen = 0;
-       if (!isMono)
-               InitColorMap();
-       s = spltty();
-       dcDivertXInput = (void (*)())0;
-       dcMouseEvent = (void (*)())0;
-       dcMouseButtons = (void (*)())0;
-       splx(s);
-       ScreenInit();
+       fp->GraphicsOpen = 0;
+       cfbInitColorMap();
+       cfbDeconfigMouse();
+       cfbScreenInit();
        vmUserUnmap();
        vmUserUnmap();
-       bzero(fb_addr, (isMono ? 1024 / 8 : 1024) * 864);
-       PosCursor(col * 8, row * 15);
+       bzero((caddr_t)fp->fr_addr, 1024 * 864);
+       cfbPosCursor(fp->col * 8, fp->row * 15);
        return (0);
 }
 
        return (0);
 }
 
@@ -721,6 +210,7 @@ cfbioctl(dev, cmd, data, flag)
        dev_t dev;
        caddr_t data;
 {
        dev_t dev;
        caddr_t data;
 {
+       register struct pmax_fb *fp = &cfbfb;
        int s;
 
        switch (cmd) {
        int s;
 
        switch (cmd) {
@@ -733,26 +223,20 @@ cfbioctl(dev, cmd, data, flag)
                 * Map the all the data the user needs access to into
                 * user space.
                 */
                 * Map the all the data the user needs access to into
                 * user space.
                 */
-               addr = vmUserMap(sizeof(pmu), (unsigned)&pmu);
+               addr = vmUserMap(sizeof(struct fbuaccess), (unsigned)fp->fbu);
                if (addr == (caddr_t)0)
                        goto mapError;
                if (addr == (caddr_t)0)
                        goto mapError;
-               *(PM_Info **)data = &((struct pmuaccess *)addr)->scrInfo;
-               pmu.scrInfo.qe.events = ((struct pmuaccess *)addr)->events;
-               pmu.scrInfo.qe.tcs = ((struct pmuaccess *)addr)->tcs;
-               /*
-                * Map the plane mask into the user's address space.
-                */
-               addr = vmUserMap(4, planemask_addr);
-               if (addr == (caddr_t)0)
-                       goto mapError;
-               pmu.scrInfo.planemask = (char *)addr;
+               *(PM_Info **)data = &((struct fbuaccess *)addr)->scrInfo;
+               fp->fbu->scrInfo.qe.events = ((struct fbuaccess *)addr)->events;
+               fp->fbu->scrInfo.qe.tcs = ((struct fbuaccess *)addr)->tcs;
+               fp->fbu->scrInfo.planemask = (char *)0;
                /*
                 * Map the frame buffer into the user's address space.
                 */
                /*
                 * Map the frame buffer into the user's address space.
                 */
-               addr = vmUserMap(isMono ? 256*1024 : 1024*1024, fb_addr);
+               addr = vmUserMap(1024 * 1024, (unsigned)fp->fr_addr);
                if (addr == (caddr_t)0)
                        goto mapError;
                if (addr == (caddr_t)0)
                        goto mapError;
-               pmu.scrInfo.bitmap = (char *)addr;
+               fp->fbu->scrInfo.bitmap = (char *)addr;
                break;
 
        mapError:
                break;
 
        mapError:
@@ -765,15 +249,15 @@ cfbioctl(dev, cmd, data, flag)
                /*
                 * Set mouse state.
                 */
                /*
                 * Set mouse state.
                 */
-               pmu.scrInfo.mouse = *(pmCursor *)data;
-               PosCursor(pmu.scrInfo.mouse.x, pmu.scrInfo.mouse.y);
+               fp->fbu->scrInfo.mouse = *(pmCursor *)data;
+               cfbPosCursor(fp->fbu->scrInfo.mouse.x, fp->fbu->scrInfo.mouse.y);
                break;
 
        case QIOCINIT:
                /*
                 * Initialize the screen.
                 */
                break;
 
        case QIOCINIT:
                /*
                 * Initialize the screen.
                 */
-               ScreenInit();
+               cfbScreenInit();
                break;
 
        case QIOCKPCMD:
                break;
 
        case QIOCKPCMD:
@@ -784,56 +268,49 @@ cfbioctl(dev, cmd, data, flag)
                kpCmdPtr = (pmKpCmd *)data;
                if (kpCmdPtr->nbytes == 0)
                        kpCmdPtr->cmd |= 0x80;
                kpCmdPtr = (pmKpCmd *)data;
                if (kpCmdPtr->nbytes == 0)
                        kpCmdPtr->cmd |= 0x80;
-               if (!GraphicsOpen)
+               if (!fp->GraphicsOpen)
                        kpCmdPtr->cmd |= 1;
                        kpCmdPtr->cmd |= 1;
-               dcKBDPutc((int)kpCmdPtr->cmd);
+               (*fp->KBDPutc)(fp->kbddev, (int)kpCmdPtr->cmd);
                cp = &kpCmdPtr->par[0];
                for (; kpCmdPtr->nbytes > 0; cp++, kpCmdPtr->nbytes--) {
                        if (kpCmdPtr->nbytes == 1)
                                *cp |= 0x80;
                cp = &kpCmdPtr->par[0];
                for (; kpCmdPtr->nbytes > 0; cp++, kpCmdPtr->nbytes--) {
                        if (kpCmdPtr->nbytes == 1)
                                *cp |= 0x80;
-                       dcKBDPutc((int)*cp);
+                       (*fp->KBDPutc)(fp->kbddev, (int)*cp);
                }
                }
-               break;
            }
            }
+           break;
 
        case QIOCADDR:
 
        case QIOCADDR:
-               *(PM_Info **)data = &pmu.scrInfo;
+               *(PM_Info **)data = &fp->fbu->scrInfo;
                break;
 
        case QIOWCURSOR:
                break;
 
        case QIOWCURSOR:
-               LoadCursor((unsigned short *)data);
+               cfbLoadCursor((unsigned short *)data);
                break;
 
        case QIOWCURSORCOLOR:
                break;
 
        case QIOWCURSORCOLOR:
-               CursorColor((unsigned int *)data);
+               cfbCursorColor((unsigned int *)data);
                break;
 
        case QIOSETCMAP:
                break;
 
        case QIOSETCMAP:
-               LoadColorMap((ColorMap *)data);
+               cfbLoadColorMap((ColorMap *)data);
                break;
 
        case QIOKERNLOOP:
                break;
 
        case QIOKERNLOOP:
-               s = spltty();
-               dcDivertXInput = cfbKbdEvent;
-               dcMouseEvent = cfbMouseEvent;
-               dcMouseButtons = cfbMouseButtons;
-               splx(s);
+               cfbConfigMouse();
                break;
 
        case QIOKERNUNLOOP:
                break;
 
        case QIOKERNUNLOOP:
-               s = spltty();
-               dcDivertXInput = (void (*)())0;
-               dcMouseEvent = (void (*)())0;
-               dcMouseButtons = (void (*)())0;
-               splx(s);
+               cfbDeconfigMouse();
                break;
 
        case QIOVIDEOON:
                break;
 
        case QIOVIDEOON:
-               EnableVideo();
+               cfbRestoreCursorColor();
+               bt459_video_on();
                break;
 
        case QIOVIDEOOFF:
                break;
 
        case QIOVIDEOOFF:
-               DisableVideo();
+               bt459_video_off();
                break;
 
        default:
                break;
 
        default:
@@ -848,12 +325,13 @@ cfbselect(dev, flag, p)
        int flag;
        struct proc *p;
 {
        int flag;
        struct proc *p;
 {
+       struct pmax_fb *fp = &cfbfb;
 
        switch (flag) {
        case FREAD:
 
        switch (flag) {
        case FREAD:
-               if (pmu.scrInfo.qe.eHead != pmu.scrInfo.qe.eTail)
+               if (fp->fbu->scrInfo.qe.eHead != fp->fbu->scrInfo.qe.eTail)
                        return (1);
                        return (1);
-               selrecord(p, &cfb_selp);
+               selrecord(p, &fp->selp);
                break;
        }
 
                break;
        }
 
@@ -863,54 +341,77 @@ cfbselect(dev, flag, p)
 static u_char  cursor_RGB[6];  /* cursor color 2 & 3 */
 
 /*
 static u_char  cursor_RGB[6];  /* cursor color 2 & 3 */
 
 /*
- * The default cursor.
+ * XXX This assumes 2bits/cursor pixel so that the 1Kbyte cursor RAM
+ * defines a 64x64 cursor. If the bt459 does not map the cursor RAM
+ * this way, this code is Screwed!
  */
  */
-static unsigned short defCursor[1024] = {
-       0x00FF, 0x00FF, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
-       0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
-       0x00FF, 0x00FF, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
-       0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
-       0x00FF, 0x00FF, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
-       0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
-       0x00FF, 0x00FF, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
-       0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
-       0x00FF, 0x00FF, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
-       0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
-       0x00FF, 0x00FF, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
-       0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
-       0x00FF, 0x00FF, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
-       0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
-       0x00FF, 0x00FF, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
-       0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
-       0x00FF, 0x00FF, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
-       0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
-       0x00FF, 0x00FF, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
-       0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
-       0x00FF, 0x00FF, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
-       0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
-       0x00FF, 0x00FF, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
-       0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
-       0x00FF, 0x00FF, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
-       0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
-       0x00FF, 0x00FF, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
-       0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
-       0x00FF, 0x00FF, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
-       0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
-       0x00FF, 0x00FF, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
-       0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
-};
+static void
+cfbLoadCursor(cursor)
+       u_short *cursor;
+{
+       register int i, j, k, pos;
+       register u_short ap, bp, out;
 
 
-#define        CFB_OFFSET_VRAM         0x0             /* from module's base */
-                                               /* Replicated at x100000 */
-#define CFB_OFFSET_BT459       0x200000        /* Bt459 registers */
-#define CFB_OFFSET_IREQ                0x300000        /* Interrupt req. control */
-#define CFB_OFFSET_ROM         0x380000        /* Diagnostic ROM */
-#define CFB_OFFSET_RESET       0x3c0000        /* Bt459 resets on writes */
+       /*
+        * Fill in the cursor sprite using the A and B planes, as provided
+        * for the pmax.
+        * XXX This will have to change when the X server knows that this
+        * is not a pmax display.
+        */
+       pos = 0;
+       for (k = 0; k < 16; k++) {
+               ap = *cursor;
+               bp = *(cursor + 16);
+               j = 0;
+               while (j < 4) {
+                       out = 0;
+                       for (i = 0; i < 4; i++) {
+                               out = (out << 2) | ((ap & 0x1) << 1) |
+                                       (bp & 0x1);
+                               ap >>= 1;
+                               bp >>= 1;
+                       }
+                       bt459_set_cursor_ram(pos, out);
+                       pos++;
+                       j++;
+               }
+               while (j < 16) {
+                       bt459_set_cursor_ram(pos, 0);
+                       pos++;
+                       j++;
+               }
+               cursor++;
+       }
+       while (pos < 1024) {
+               bt459_set_cursor_ram(pos, 0);
+               pos++;
+       }
+}
+
+/*
+ * Set a cursor ram value.
+ */
+static void
+bt459_set_cursor_ram(pos, val)
+       int pos;
+       register u_char val;
+{
+       register bt459_regmap_t *regs = (bt459_regmap_t *)
+               (cfbfb.fr_addr + CFB_OFFSET_BT459);
+       register int cnt;
+       u_char nval;
+
+       cnt = 0;
+       do {
+               bt459_write_reg(regs, BT459_REG_CRAM_BASE + pos, val);
+               nval = bt459_read_reg(regs, BT459_REG_CRAM_BASE + pos);
+       } while (val != nval && ++cnt < 10);
+}
 
 /*
  * Generic register access
  */
 
 /*
  * Generic register access
  */
-void
+static void
 bt459_select_reg(regs, regno)
        bt459_regmap_t *regs;
 {
 bt459_select_reg(regs, regno)
        bt459_regmap_t *regs;
 {
@@ -919,7 +420,7 @@ bt459_select_reg(regs, regno)
        MachEmptyWriteBuffer();
 }
 
        MachEmptyWriteBuffer();
 }
 
-void
+static void
 bt459_write_reg(regs, regno, val)
        bt459_regmap_t *regs;
 {
 bt459_write_reg(regs, regno, val)
        bt459_regmap_t *regs;
 {
@@ -930,55 +431,68 @@ bt459_write_reg(regs, regno, val)
        MachEmptyWriteBuffer();
 }
 
        MachEmptyWriteBuffer();
 }
 
-unsigned char
+static u_char
 bt459_read_reg(regs, regno)
        bt459_regmap_t *regs;
 {
        regs->addr_lo = regno;
        regs->addr_hi = regno >> 8;
        MachEmptyWriteBuffer();
 bt459_read_reg(regs, regno)
        bt459_regmap_t *regs;
 {
        regs->addr_lo = regno;
        regs->addr_hi = regno >> 8;
        MachEmptyWriteBuffer();
-       return regs->addr_reg;
+       return (regs->addr_reg);
 }
 
 }
 
-#ifdef DEBUG
-bt459_print_colormap(regs)
-       bt459_regmap_t *regs;
-{
-       register int i;
-
-       bt459_select_reg(regs, 0);
-       for (i = 0; i < 256; i++) {
-               register unsigned red, green, blue;
-
-               red = regs->addr_cmap;
-               green = regs->addr_cmap;
-               blue = regs->addr_cmap;
-               printf("%x->[x%x x%x x%x]\n", i, red, green, blue);
-       }
-}
-#endif
-
 /*
 /*
- * Test to see if device is present.
- * Return true if found and initialized ok.
+ * Initialization
  */
  */
-cfb_init(cp)
-       register struct pmax_ctlr *cp;
+int
+cfbinit(cp)
+       char *cp;
 {
 {
-       bt459_regmap_t *regs;
+       register bt459_regmap_t *regs;
+       register struct pmax_fb *fp = &cfbfb;
 
        /* check for no frame buffer */
 
        /* check for no frame buffer */
-       if (badaddr(cp->pmax_addr, 4))
+       if (badaddr(cp, 4))
+               return (0);
+
+       fp->isMono = 0;
+       fp->fr_addr = (char *)(cp + CFB_OFFSET_VRAM);
+       fp->fbu = &cfbu;
+       fp->posCursor = cfbPosCursor;
+       switch (pmax_boardtype) {
+#if NDC > 0
+       case DS_3MAX:
+               fp->KBDPutc = dcPutc;
+               fp->kbddev = makedev(DCDEV, DCKBD_PORT);
+               break;
+#endif
+#if NSCC > 0
+       case DS_3MIN:
+               fp->KBDPutc = sccPutc;
+               fp->kbddev = makedev(SCCDEV, SCCKBD_PORT);
+               break;
+#endif
+#if NDTOP > 0
+       case DS_MAXINE:
+               fp->KBDPutc = dtopKBDPutc;
+               fp->kbddev = makedev(DTOPDEV, DTOPKBD_PORT);
+               break;
+#endif
+       default:
+               printf("Can't cofigure keyboard/mouse\n");
                return (0);
                return (0);
+       };
 
 
-       fb_addr = (unsigned)cp->pmax_addr + CFB_OFFSET_VRAM;
-       planemask_addr = 0; /* XXX */
-       regs = (bt459_regmap_t *)(fb_addr + CFB_OFFSET_BT459);
+       /*
+        * Initialize the screen.
+        */
+       regs = (bt459_regmap_t *)(fp->fr_addr + CFB_OFFSET_BT459);
 
        if (bt459_read_reg(regs, BT459_REG_ID) != 0x4a)
                return (0);
 
 
        if (bt459_read_reg(regs, BT459_REG_ID) != 0x4a)
                return (0);
 
-       *(int *)(fb_addr + CFB_OFFSET_RESET) = 0;       /* force chip reset */
+       /* Reset the chip */
+       *(volatile int *)(fp->fr_addr + CFB_OFFSET_RESET) = 0;
        DELAY(2000);    /* ???? check right time on specs! ???? */
 
        /* use 4:1 input mux */
        DELAY(2000);    /* ???? check right time on specs! ???? */
 
        /* use 4:1 input mux */
@@ -1037,38 +551,40 @@ cfb_init(cp)
        /*
         * Initialize screen info.
         */
        /*
         * Initialize screen info.
         */
-       pmu.scrInfo.max_row = MAX_ROW;
-       pmu.scrInfo.max_col = MAX_COL;
-       pmu.scrInfo.max_x = 1024;
-       pmu.scrInfo.max_y = 864;
-       pmu.scrInfo.max_cur_x = 1023;
-       pmu.scrInfo.max_cur_y = 863;
-       pmu.scrInfo.version = 11;
-       pmu.scrInfo.mthreshold = 4;
-       pmu.scrInfo.mscale = 2;
-       pmu.scrInfo.min_cur_x = 0;
-       pmu.scrInfo.min_cur_y = 0;
-       pmu.scrInfo.qe.timestamp_ms = TO_MS(time);
-       pmu.scrInfo.qe.eSize = PM_MAXEVQ;
-       pmu.scrInfo.qe.eHead = pmu.scrInfo.qe.eTail = 0;
-       pmu.scrInfo.qe.tcSize = MOTION_BUFFER_SIZE;
-       pmu.scrInfo.qe.tcNext = 0;
+       fp->fbu->scrInfo.max_row = 56;
+       fp->fbu->scrInfo.max_col = 80;
+       fp->fbu->scrInfo.max_x = 1024;
+       fp->fbu->scrInfo.max_y = 864;
+       fp->fbu->scrInfo.max_cur_x = 1023;
+       fp->fbu->scrInfo.max_cur_y = 863;
+       fp->fbu->scrInfo.version = 11;
+       fp->fbu->scrInfo.mthreshold = 4;
+       fp->fbu->scrInfo.mscale = 2;
+       fp->fbu->scrInfo.min_cur_x = 0;
+       fp->fbu->scrInfo.min_cur_y = 0;
+       fp->fbu->scrInfo.qe.timestamp_ms = TO_MS(time);
+       fp->fbu->scrInfo.qe.eSize = PM_MAXEVQ;
+       fp->fbu->scrInfo.qe.eHead = fp->fbu->scrInfo.qe.eTail = 0;
+       fp->fbu->scrInfo.qe.tcSize = MOTION_BUFFER_SIZE;
+       fp->fbu->scrInfo.qe.tcNext = 0;
 
        /*
         * Initialize the color map, the screen, and the mouse.
         */
 
        /*
         * Initialize the color map, the screen, and the mouse.
         */
-       InitColorMap();
-       ScreenInit();
-       Scroll();
+       cfbInitColorMap();
+       cfbScreenInit();
+       fbScroll(fp);
 
 
-       initialized = 1;
+       fp->initialized = 1;
+       if (cn_tab.cn_fb == (struct pmax_fb *)0)
+               cn_tab.cn_fb = fp;
        return (1);
 }
 
 /*
  * ----------------------------------------------------------------------------
  *
        return (1);
 }
 
 /*
  * ----------------------------------------------------------------------------
  *
- * ScreenInit --
+ * cfbScreenInit --
  *
  *     Initialize the screen.
  *
  *
  *     Initialize the screen.
  *
@@ -1081,66 +597,23 @@ cfb_init(cp)
  * ----------------------------------------------------------------------------
  */
 static void
  * ----------------------------------------------------------------------------
  */
 static void
-ScreenInit()
+cfbScreenInit()
 {
 {
+       register struct pmax_fb *fp = &cfbfb;
 
        /*
         * Home the cursor.
 
        /*
         * Home the cursor.
-        * We want an LSI terminal emulation. We want the graphics
+        * We want an LSI terminal emulation.  We want the graphics
         * terminal to scroll from the bottom. So start at the bottom.
         */
         * terminal to scroll from the bottom. So start at the bottom.
         */
-       row = 55;
-       col = 0;
+       fp->row = 55;
+       fp->col = 0;
 
        /*
         * Load the cursor with the default values
         *
         */
 
        /*
         * Load the cursor with the default values
         *
         */
-       LoadCursor(defCursor);
-}
-
-/*
- * ----------------------------------------------------------------------------
- *
- * LoadCursor --
- *
- *     Routine to load the cursor Sprite pattern.
- *
- * Results:
- *     None.
- *
- * Side effects:
- *     The cursor is loaded into the hardware cursor.
- *
- * ----------------------------------------------------------------------------
- */
-static void
-LoadCursor(cur)
-       unsigned short *cur;
-{
-       bt459_regmap_t *regs = (bt459_regmap_t *)(fb_addr + CFB_OFFSET_BT459);
-       register int i, j;
-
-       /*
-        * As per specs, must run a check to see if we
-        * had contention. If so, re-write the cursor.
-        */
-       for (j = 0; j < 2; j++) {
-               /* loop once to write */
-               bt459_select_reg(regs, BT459_REG_CRAM_BASE);
-               for (i = 0; i < 1024; i++) {
-                       regs->addr_reg = cur[i];
-                       MachEmptyWriteBuffer();
-               }
-
-               /* loop to check, if fail write again */
-               bt459_select_reg(regs, BT459_REG_CRAM_BASE);
-               for (i = 0; i < 1024; i++)
-                       if (regs->addr_reg != cur[i])
-                               break;
-               if (i == 1024)
-                       break;  /* all went well first shot */
-       }
+       cfbLoadCursor(defCursor);
 }
 
 /*
 }
 
 /*
@@ -1159,9 +632,9 @@ LoadCursor(cur)
  * ----------------------------------------------------------------------------
  */
 static void
  * ----------------------------------------------------------------------------
  */
 static void
-RestoreCursorColor()
+cfbRestoreCursorColor()
 {
 {
-       bt459_regmap_t *regs = (bt459_regmap_t *)(fb_addr + CFB_OFFSET_BT459);
+       bt459_regmap_t *regs = (bt459_regmap_t *)(cfbfb.fr_addr + CFB_OFFSET_BT459);
        register int i;
 
        bt459_select_reg(regs, BT459_REG_CCOLOR_2);
        register int i;
 
        bt459_select_reg(regs, BT459_REG_CCOLOR_2);
@@ -1187,7 +660,7 @@ RestoreCursorColor()
  * ----------------------------------------------------------------------------
  */
 static void
  * ----------------------------------------------------------------------------
  */
 static void
-CursorColor(color)
+cfbCursorColor(color)
        unsigned int color[];
 {
        register int i, j;
        unsigned int color[];
 {
        register int i, j;
@@ -1195,7 +668,7 @@ CursorColor(color)
        for (i = 0; i < 6; i++)
                cursor_RGB[i] = (u_char)(color[i] >> 8);
 
        for (i = 0; i < 6; i++)
                cursor_RGB[i] = (u_char)(color[i] >> 8);
 
-       RestoreCursorColor();
+       cfbRestoreCursorColor();
 }
 
 /*
 }
 
 /*
@@ -1213,18 +686,19 @@ CursorColor(color)
  *
  *----------------------------------------------------------------------
  */
  *
  *----------------------------------------------------------------------
  */
-static void
-PosCursor(x, y)
+void
+cfbPosCursor(x, y)
        register int x, y;
 {
        register int x, y;
 {
-       bt459_regmap_t *regs = (bt459_regmap_t *)(fb_addr + CFB_OFFSET_BT459);
+       bt459_regmap_t *regs = (bt459_regmap_t *)(cfbfb.fr_addr + CFB_OFFSET_BT459);
+       register struct pmax_fb *fp = &cfbfb;
 
 
-       if (y < pmu.scrInfo.min_cur_y || y > pmu.scrInfo.max_cur_y)
-               y = pmu.scrInfo.max_cur_y;
-       if (x < pmu.scrInfo.min_cur_x || x > pmu.scrInfo.max_cur_x)
-               x = pmu.scrInfo.max_cur_x;
-       pmu.scrInfo.cursor.x = x;               /* keep track of real cursor */
-       pmu.scrInfo.cursor.y = y;               /* position, indep. of mouse */
+       if (y < fp->fbu->scrInfo.min_cur_y || y > fp->fbu->scrInfo.max_cur_y)
+               y = fp->fbu->scrInfo.max_cur_y;
+       if (x < fp->fbu->scrInfo.min_cur_x || x > fp->fbu->scrInfo.max_cur_x)
+               x = fp->fbu->scrInfo.max_cur_x;
+       fp->fbu->scrInfo.cursor.x = x;          /* keep track of real cursor */
+       fp->fbu->scrInfo.cursor.y = y;          /* position, indep. of mouse */
 
        x += 219;
        y += 34;
 
        x += 219;
        y += 34;
@@ -1256,9 +730,9 @@ PosCursor(x, y)
  * ----------------------------------------------------------------------------
  */
 static void
  * ----------------------------------------------------------------------------
  */
 static void
-InitColorMap()
+cfbInitColorMap()
 {
 {
-       bt459_regmap_t *regs = (bt459_regmap_t *)(fb_addr + CFB_OFFSET_BT459);
+       bt459_regmap_t *regs = (bt459_regmap_t *)(cfbfb.fr_addr + CFB_OFFSET_BT459);
        register int i;
 
        bt459_select_reg(regs, 0);
        register int i;
 
        bt459_select_reg(regs, 0);
@@ -1276,7 +750,7 @@ InitColorMap()
                cursor_RGB[i] = 0x00;
                cursor_RGB[i + 3] = 0xff;
        }
                cursor_RGB[i] = 0x00;
                cursor_RGB[i + 3] = 0xff;
        }
-       RestoreCursorColor();
+       cfbRestoreCursorColor();
 }
 
 /*
 }
 
 /*
@@ -1295,10 +769,10 @@ InitColorMap()
  * ----------------------------------------------------------------------------
  */
 static void
  * ----------------------------------------------------------------------------
  */
 static void
-LoadColorMap(ptr)
+cfbLoadColorMap(ptr)
        ColorMap *ptr;
 {
        ColorMap *ptr;
 {
-       bt459_regmap_t *regs = (bt459_regmap_t *)(fb_addr + CFB_OFFSET_BT459);
+       bt459_regmap_t *regs = (bt459_regmap_t *)(cfbfb.fr_addr + CFB_OFFSET_BT459);
 
        if (ptr->index > 256)
                return;
 
        if (ptr->index > 256)
                return;
@@ -1313,7 +787,7 @@ LoadColorMap(ptr)
 /*
  * Video on/off state.
  */
 /*
  * Video on/off state.
  */
-struct vstate {
+static struct vstate {
        u_char  color0[3];      /* saved color map entry zero */
        u_char  off;            /* TRUE if display is off */
 } vstate;
        u_char  color0[3];      /* saved color map entry zero */
        u_char  off;            /* TRUE if display is off */
 } vstate;
@@ -1321,7 +795,7 @@ struct vstate {
 /*
  * ----------------------------------------------------------------------------
  *
 /*
  * ----------------------------------------------------------------------------
  *
- * EnableVideo --
+ * bt459_video_on
  *
  *     Enable the video display.
  *
  *
  *     Enable the video display.
  *
@@ -1334,9 +808,9 @@ struct vstate {
  * ----------------------------------------------------------------------------
  */
 static void
  * ----------------------------------------------------------------------------
  */
 static void
-EnableVideo()
+bt459_video_on()
 {
 {
-       bt459_regmap_t *regs = (bt459_regmap_t *)(fb_addr + CFB_OFFSET_BT459);
+       bt459_regmap_t *regs = (bt459_regmap_t *)(cfbfb.fr_addr + CFB_OFFSET_BT459);
 
        if (!vstate.off)
                return;
 
        if (!vstate.off)
                return;
@@ -1360,7 +834,7 @@ EnableVideo()
 /*
  * ----------------------------------------------------------------------------
  *
 /*
  * ----------------------------------------------------------------------------
  *
- * DisableVideo --
+ * bt459_video_off
  *
  *     Disable the video display.
  *
  *
  *     Disable the video display.
  *
@@ -1373,9 +847,9 @@ EnableVideo()
  * ----------------------------------------------------------------------------
  */
 static void
  * ----------------------------------------------------------------------------
  */
 static void
-DisableVideo()
+bt459_video_off()
 {
 {
-       bt459_regmap_t *regs = (bt459_regmap_t *)(fb_addr + CFB_OFFSET_BT459);
+       bt459_regmap_t *regs = (bt459_regmap_t *)(cfbfb.fr_addr + CFB_OFFSET_BT459);
 
        if (vstate.off)
                return;
 
        if (vstate.off)
                return;
@@ -1401,4 +875,101 @@ DisableVideo()
 
        vstate.off = 1;
 }
 
        vstate.off = 1;
 }
+
+/*
+ * cfb keyboard and mouse input. Just punt to the generic ones in fb.c
+ */
+void
+cfbKbdEvent(ch)
+       int ch;
+{
+       fbKbdEvent(ch, &cfbfb);
+}
+
+void
+cfbMouseEvent(newRepPtr)
+       MouseReport *newRepPtr;
+{
+       fbMouseEvent(newRepPtr, &cfbfb);
+}
+
+void
+cfbMouseButtons(newRepPtr)
+       MouseReport *newRepPtr;
+{
+       fbMouseButtons(newRepPtr, &cfbfb);
+}
+
+/*
+ * Configure the mouse and keyboard based on machine type
+ */
+static void
+cfbConfigMouse()
+{
+       int s;
+
+       s = spltty();
+       switch (pmax_boardtype) {
+#if NDC > 0
+       case DS_3MAX:
+               dcDivertXInput = cfbKbdEvent;
+               dcMouseEvent = cfbMouseEvent;
+               dcMouseButtons = cfbMouseButtons;
+               break;
 #endif
 #endif
+#if NSCC > 1
+       case DS_3MIN:
+               sccDivertXInput = cfbKbdEvent;
+               sccMouseEvent = cfbMouseEvent;
+               sccMouseButtons = cfbMouseButtons;
+               break;
+#endif
+#if NDTOP > 0
+       case DS_MAXINE:
+               dtopDivertXInput = cfbKbdEvent;
+               dtopMouseEvent = cfbMouseEvent;
+               dtopMouseButtons = cfbMouseButtons;
+               break;
+#endif
+       default:
+               printf("Can't configure mouse/keyboard\n");
+       };
+       splx(s);
+}
+
+/*
+ * and deconfigure them
+ */
+static void
+cfbDeconfigMouse()
+{
+       int s;
+
+       s = spltty();
+       switch (pmax_boardtype) {
+#if NDC > 0
+       case DS_3MAX:
+               dcDivertXInput = (void (*)())0;
+               dcMouseEvent = (void (*)())0;
+               dcMouseButtons = (void (*)())0;
+               break;
+#endif
+#if NSCC > 1
+       case DS_3MIN:
+               sccDivertXInput = (void (*)())0;
+               sccMouseEvent = (void (*)())0;
+               sccMouseButtons = (void (*)())0;
+               break;
+#endif
+#if NDTOP > 0
+       case DS_MAXINE:
+               dtopDivertXInput = (void (*)())0;
+               dtopMouseEvent = (void (*)())0;
+               dtopMouseButtons = (void (*)())0;
+               break;
+#endif
+       default:
+               printf("Can't deconfigure mouse/keyboard\n");
+       };
+}
+#endif /* NCFB */
index f195cb6..7634d7a 100644 (file)
@@ -1,19 +1,16 @@
-/*
- * Copyright (c) 1992 Regents of the University of California.
+/*-
+ * Copyright (c) 1992 The Regents of the University of California.
  * All rights reserved.
  *
  * This code is derived from software contributed to Berkeley by
  * All rights reserved.
  *
  * This code is derived from software contributed to Berkeley by
- * Ralph Campbell.
- *     @(#)dz.c        7.9 (Berkeley) 6/28/90
- */
-
-/*
- *  devDC7085.c --
+ * Ralph Campbell and Rick Macklem.
  *
  * %sccs.include.redist.c%
  *
  *
  * %sccs.include.redist.c%
  *
- *     @(#)dc.c        7.10 (Berkeley) %G%
- *
+ *     @(#)dc.c        7.11 (Berkeley) %G%
+ */
+
+/*
  * devDC7085.c --
  *
  *             This file contains machine-dependent routines that handle the
  * devDC7085.c --
  *
  *             This file contains machine-dependent routines that handle the
@@ -31,7 +28,7 @@
  *     v 1.4 89/08/29 11:55:30 nelson Exp $ SPRITE (DECWRL)";
  */
 
  *     v 1.4 89/08/29 11:55:30 nelson Exp $ SPRITE (DECWRL)";
  */
 
-#include "dc.h"
+#include <dc.h>
 #if NDC > 0
 /*
  * DC7085 (DZ-11 look alike) Driver
 #if NDC > 0
 /*
  * DC7085 (DZ-11 look alike) Driver
 #include <sys/syslog.h>
 
 #include <machine/dc7085cons.h>
 #include <sys/syslog.h>
 
 #include <machine/dc7085cons.h>
+#include <machine/pmioctl.h>
+
+#include <pmax/pmax/pmaxtype.h>
+#include <pmax/pmax/cons.h>
 
 #include <pmax/dev/device.h>
 #include <pmax/dev/pdma.h>
 
 #include <pmax/dev/device.h>
 #include <pmax/dev/pdma.h>
+#include <pmax/dev/fbreg.h>
+
+extern int pmax_boardtype;
+extern struct consdev cn_tab;
 
 /*
  * Driver information for auto-configuration stuff.
 
 /*
  * Driver information for auto-configuration stuff.
@@ -65,9 +70,15 @@ struct       driver dcdriver = {
 
 #define        NDCLINE         (NDC*4)
 
 
 #define        NDCLINE         (NDC*4)
 
-extern void dcstart __P((struct tty *));
-extern void dcxint __P((struct tty *));
+void dcstart   __P((struct tty *));
+void dcxint    __P((struct tty *));
+void dcPutc    __P((dev_t, int));
+void dcscan    __P((void *));
 extern void ttrstrt __P((void *));
 extern void ttrstrt __P((void *));
+int dcGetc     __P((dev_t));
+int dcparam    __P((struct tty *, struct termios *));
+extern void KBDReset   __P((dev_t, void (*)()));
+extern void MouseInit  __P((dev_t, void (*)(), int (*)()));
 
 struct tty dc_tty[NDCLINE];
 int    dc_cnt = NDCLINE;
 
 struct tty dc_tty[NDCLINE];
 int    dc_cnt = NDCLINE;
@@ -78,11 +89,6 @@ void (*dcMouseButtons)();    /* X windows mouse buttons event routine */
 int    debugChar;
 #endif
 
 int    debugChar;
 #endif
 
-static void dcscan __P((void *));
-static int dcMapChar __P((int));
-static void dcKBDReset __P((void));
-static void MouseInit __P((void));
-
 /*
  * Software copy of brk register since it isn't readable
  */
 /*
  * Software copy of brk register since it isn't readable
  */
@@ -114,9 +120,7 @@ struct speedtab dcspeedtab[] = {
        2400,   LPR_B2400,
        4800,   LPR_B4800,
        9600,   LPR_B9600,
        2400,   LPR_B2400,
        4800,   LPR_B4800,
        9600,   LPR_B9600,
-#ifdef DS5000
        19200,  LPR_B19200,
        19200,  LPR_B19200,
-#endif
        -1,     -1
 };
 
        -1,     -1
 };
 
@@ -128,230 +132,6 @@ struct speedtab dcspeedtab[] = {
 #define        LFLAG   (TTYDEF_LFLAG & ~ECHO)
 #endif
 
 #define        LFLAG   (TTYDEF_LFLAG & ~ECHO)
 #endif
 
-/*
- * Ascii values of command keys.
- */
-#define KBD_TAB                '\t'
-#define KBD_DEL                127
-#define KBD_RET                '\r'
-
-/*
- *  Define "hardware-independent" codes for the control, shift, meta and
- *  function keys.  Codes start after the last 7-bit ASCII code (127)
- *  and are assigned in an arbitrary order.
- */
-#define KBD_NOKEY      128
-
-#define KBD_F1         201
-#define KBD_F2         202
-#define KBD_F3         203
-#define KBD_F4         204
-#define KBD_F5         205
-#define KBD_F6         206
-#define KBD_F7         207
-#define KBD_F8         208
-#define KBD_F9         209
-#define KBD_F10                210
-#define KBD_F11                211
-#define KBD_F12                212
-#define KBD_F13                213
-#define KBD_F14                214
-#define KBD_HELP       215
-#define KBD_DO         216
-#define KBD_F17                217
-#define KBD_F18                218
-#define KBD_F19                219
-#define KBD_F20                220
-
-#define KBD_FIND       221
-#define KBD_INSERT     222
-#define KBD_REMOVE     223
-#define KBD_SELECT     224
-#define KBD_PREVIOUS   225
-#define KBD_NEXT       226
-
-#define KBD_KP_ENTER   227
-#define KBD_KP_F1      228
-#define KBD_KP_F2      229
-#define KBD_KP_F3      230
-#define KBD_KP_F4      231
-#define KBD_LEFT       232
-#define KBD_RIGHT      233
-#define KBD_DOWN       234
-#define KBD_UP         235
-
-#define KBD_CONTROL    236
-#define KBD_SHIFT      237
-#define KBD_CAPSLOCK   238
-#define KBD_ALTERNATE  239
-
-/*
- * Keyboard to Ascii, unshifted.
- */
-static unsigned char unshiftedAscii[] = {
-/*  0 */ KBD_NOKEY,    KBD_NOKEY,      KBD_NOKEY,      KBD_NOKEY,
-/*  4 */ KBD_NOKEY,    KBD_NOKEY,      KBD_NOKEY,      KBD_NOKEY,
-/*  8 */ KBD_NOKEY,    KBD_NOKEY,      KBD_NOKEY,      KBD_NOKEY,
-/*  c */ KBD_NOKEY,    KBD_NOKEY,      KBD_NOKEY,      KBD_NOKEY,
-/* 10 */ KBD_NOKEY,    KBD_NOKEY,      KBD_NOKEY,      KBD_NOKEY,
-/* 14 */ KBD_NOKEY,    KBD_NOKEY,      KBD_NOKEY,      KBD_NOKEY,
-/* 18 */ KBD_NOKEY,    KBD_NOKEY,      KBD_NOKEY,      KBD_NOKEY,
-/* 1c */ KBD_NOKEY,    KBD_NOKEY,      KBD_NOKEY,      KBD_NOKEY,
-/* 20 */ KBD_NOKEY,    KBD_NOKEY,      KBD_NOKEY,      KBD_NOKEY,
-/* 24 */ KBD_NOKEY,    KBD_NOKEY,      KBD_NOKEY,      KBD_NOKEY,
-/* 28 */ KBD_NOKEY,    KBD_NOKEY,      KBD_NOKEY,      KBD_NOKEY,
-/* 2c */ KBD_NOKEY,    KBD_NOKEY,      KBD_NOKEY,      KBD_NOKEY,
-/* 30 */ KBD_NOKEY,    KBD_NOKEY,      KBD_NOKEY,      KBD_NOKEY,
-/* 34 */ KBD_NOKEY,    KBD_NOKEY,      KBD_NOKEY,      KBD_NOKEY,
-/* 38 */ KBD_NOKEY,    KBD_NOKEY,      KBD_NOKEY,      KBD_NOKEY,
-/* 3c */ KBD_NOKEY,    KBD_NOKEY,      KBD_NOKEY,      KBD_NOKEY,
-/* 40 */ KBD_NOKEY,    KBD_NOKEY,      KBD_NOKEY,      KBD_NOKEY,
-/* 44 */ KBD_NOKEY,    KBD_NOKEY,      KBD_NOKEY,      KBD_NOKEY,
-/* 48 */ KBD_NOKEY,    KBD_NOKEY,      KBD_NOKEY,      KBD_NOKEY,
-/* 4c */ KBD_NOKEY,    KBD_NOKEY,      KBD_NOKEY,      KBD_NOKEY,
-/* 50 */ KBD_NOKEY,    KBD_NOKEY,      KBD_NOKEY,      KBD_NOKEY,
-/* 54 */ KBD_NOKEY,    KBD_NOKEY,      KBD_F1,         KBD_F2,
-/* 58 */ KBD_F3,       KBD_F4,         KBD_F5,         KBD_NOKEY,
-/* 5c */ KBD_NOKEY,    KBD_NOKEY,      KBD_NOKEY,      KBD_NOKEY,
-/* 60 */ KBD_NOKEY,    KBD_NOKEY,      KBD_NOKEY,      KBD_NOKEY,
-/* 64 */ KBD_F6,       KBD_F7,         KBD_F8,         KBD_F9,
-/* 68 */ KBD_F10,      KBD_NOKEY,      KBD_NOKEY,      KBD_NOKEY,
-/* 6c */ KBD_NOKEY,    KBD_NOKEY,      KBD_NOKEY,      KBD_NOKEY,
-/* 70 */ KBD_NOKEY,    '\033',         KBD_F12,        KBD_F13,
-/* 74 */ KBD_F14,      KBD_NOKEY,      KBD_NOKEY,      KBD_NOKEY,
-/* 78 */ KBD_NOKEY,    KBD_NOKEY,      KBD_NOKEY,      KBD_NOKEY,
-/* 7c */ KBD_HELP,     KBD_DO,         KBD_NOKEY,      KBD_NOKEY,
-/* 80 */ KBD_F17,      KBD_F18,        KBD_F19,        KBD_F20,
-/* 84 */ KBD_NOKEY,    KBD_NOKEY,      KBD_NOKEY,      KBD_NOKEY,
-/* 88 */ KBD_NOKEY,    KBD_NOKEY,      KBD_FIND,       KBD_INSERT,
-/* 8c */ KBD_REMOVE,   KBD_SELECT,     KBD_PREVIOUS,   KBD_NEXT,
-/* 90 */ KBD_NOKEY,    KBD_NOKEY,      '0',            KBD_NOKEY,
-/* 94 */ '.',          KBD_KP_ENTER,   '1',            '2',
-/* 98 */ '3',          '4',            '5',            '6',
-/* 9c */ ',',          '7',            '8',            '9',
-/* a0 */ '-',          KBD_KP_F1,      KBD_KP_F2,      KBD_KP_F3,
-/* a4 */ KBD_KP_F4,    KBD_NOKEY,      KBD_NOKEY,      KBD_LEFT,
-/* a8 */ KBD_RIGHT,    KBD_DOWN,       KBD_UP,         KBD_NOKEY,
-/* ac */ KBD_NOKEY,    KBD_NOKEY,      KBD_SHIFT,      KBD_CONTROL,
-/* b0 */ KBD_CAPSLOCK, KBD_ALTERNATE,  KBD_NOKEY,      KBD_NOKEY,
-/* b4 */ KBD_NOKEY,    KBD_NOKEY,      KBD_NOKEY,      KBD_NOKEY,
-/* b8 */ KBD_NOKEY,    KBD_NOKEY,      KBD_NOKEY,      KBD_NOKEY,
-/* bc */ KBD_DEL,      KBD_RET,        KBD_TAB,        '`',
-/* c0 */ '1',          'q',            'a',            'z',
-/* c4 */ KBD_NOKEY,    '2',            'w',            's',
-/* c8 */ 'x',          '<',            KBD_NOKEY,      '3',
-/* cc */ 'e',          'd',            'c',            KBD_NOKEY,
-/* d0 */ '4',          'r',            'f',            'v',
-/* d4 */ ' ',          KBD_NOKEY,      '5',            't',
-/* d8 */ 'g',          'b',            KBD_NOKEY,      '6',
-/* dc */ 'y',          'h',            'n',            KBD_NOKEY,
-/* e0 */ '7',          'u',            'j',            'm',
-/* e4 */ KBD_NOKEY,    '8',            'i',            'k',
-/* e8 */ ',',          KBD_NOKEY,      '9',            'o',
-/* ec */ 'l',          '.',            KBD_NOKEY,      '0',
-/* f0 */ 'p',          KBD_NOKEY,      ';',            '/',
-/* f4 */ KBD_NOKEY,    '=',            ']',            '\\',
-/* f8 */ KBD_NOKEY,    '-',            '[',            '\'',
-/* fc */ KBD_NOKEY,    KBD_NOKEY,      KBD_NOKEY,      KBD_NOKEY,
-};
-
-/*
- * Keyboard to Ascii, shifted.
- */
-static unsigned char shiftedAscii[] = {
-/*  0 */ KBD_NOKEY,    KBD_NOKEY,      KBD_NOKEY,      KBD_NOKEY,
-/*  4 */ KBD_NOKEY,    KBD_NOKEY,      KBD_NOKEY,      KBD_NOKEY,
-/*  8 */ KBD_NOKEY,    KBD_NOKEY,      KBD_NOKEY,      KBD_NOKEY,
-/*  c */ KBD_NOKEY,    KBD_NOKEY,      KBD_NOKEY,      KBD_NOKEY,
-/* 10 */ KBD_NOKEY,    KBD_NOKEY,      KBD_NOKEY,      KBD_NOKEY,
-/* 14 */ KBD_NOKEY,    KBD_NOKEY,      KBD_NOKEY,      KBD_NOKEY,
-/* 18 */ KBD_NOKEY,    KBD_NOKEY,      KBD_NOKEY,      KBD_NOKEY,
-/* 1c */ KBD_NOKEY,    KBD_NOKEY,      KBD_NOKEY,      KBD_NOKEY,
-/* 20 */ KBD_NOKEY,    KBD_NOKEY,      KBD_NOKEY,      KBD_NOKEY,
-/* 24 */ KBD_NOKEY,    KBD_NOKEY,      KBD_NOKEY,      KBD_NOKEY,
-/* 28 */ KBD_NOKEY,    KBD_NOKEY,      KBD_NOKEY,      KBD_NOKEY,
-/* 2c */ KBD_NOKEY,    KBD_NOKEY,      KBD_NOKEY,      KBD_NOKEY,
-/* 30 */ KBD_NOKEY,    KBD_NOKEY,      KBD_NOKEY,      KBD_NOKEY,
-/* 34 */ KBD_NOKEY,    KBD_NOKEY,      KBD_NOKEY,      KBD_NOKEY,
-/* 38 */ KBD_NOKEY,    KBD_NOKEY,      KBD_NOKEY,      KBD_NOKEY,
-/* 3c */ KBD_NOKEY,    KBD_NOKEY,      KBD_NOKEY,      KBD_NOKEY,
-/* 40 */ KBD_NOKEY,    KBD_NOKEY,      KBD_NOKEY,      KBD_NOKEY,
-/* 44 */ KBD_NOKEY,    KBD_NOKEY,      KBD_NOKEY,      KBD_NOKEY,
-/* 48 */ KBD_NOKEY,    KBD_NOKEY,      KBD_NOKEY,      KBD_NOKEY,
-/* 4c */ KBD_NOKEY,    KBD_NOKEY,      KBD_NOKEY,      KBD_NOKEY,
-/* 50 */ KBD_NOKEY,    KBD_NOKEY,      KBD_NOKEY,      KBD_NOKEY,
-/* 54 */ KBD_NOKEY,    KBD_NOKEY,      KBD_F1,         KBD_F2,
-/* 58 */ KBD_F3,       KBD_F4,         KBD_F5,         KBD_NOKEY,
-/* 5c */ KBD_NOKEY,    KBD_NOKEY,      KBD_NOKEY,      KBD_NOKEY,
-/* 60 */ KBD_NOKEY,    KBD_NOKEY,      KBD_NOKEY,      KBD_NOKEY,
-/* 64 */ KBD_F6,       KBD_F7,         KBD_F8,         KBD_F9,
-/* 68 */ KBD_F10,      KBD_NOKEY,      KBD_NOKEY,      KBD_NOKEY,
-/* 6c */ KBD_NOKEY,    KBD_NOKEY,      KBD_NOKEY,      KBD_NOKEY,
-/* 70 */ KBD_NOKEY,    KBD_F11,        KBD_F12,        KBD_F13,
-/* 74 */ KBD_F14,      KBD_NOKEY,      KBD_NOKEY,      KBD_NOKEY,
-/* 78 */ KBD_NOKEY,    KBD_NOKEY,      KBD_NOKEY,      KBD_NOKEY,
-/* 7c */ KBD_HELP,     KBD_DO,         KBD_NOKEY,      KBD_NOKEY,
-/* 80 */ KBD_F17,      KBD_F18,        KBD_F19,        KBD_F20,
-/* 84 */ KBD_NOKEY,    KBD_NOKEY,      KBD_NOKEY,      KBD_NOKEY,
-/* 88 */ KBD_NOKEY,    KBD_NOKEY,      KBD_FIND,       KBD_INSERT,
-/* 8c */ KBD_REMOVE,   KBD_SELECT,     KBD_PREVIOUS,   KBD_NEXT,
-/* 90 */ KBD_NOKEY,    KBD_NOKEY,      '0',            KBD_NOKEY,
-/* 94 */ '.',          KBD_KP_ENTER,   '1',            '2',
-/* 98 */ '3',          '4',            '5',            '6',
-/* 9c */ ',',          '7',            '8',            '9',
-/* a0 */ '-',          KBD_KP_F1,      KBD_KP_F2,      KBD_KP_F3,
-/* a4 */ KBD_KP_F4,    KBD_NOKEY,      KBD_NOKEY,      KBD_LEFT,
-/* a8 */ KBD_RIGHT,    KBD_DOWN,       KBD_UP,         KBD_NOKEY,
-/* ac */ KBD_NOKEY,    KBD_NOKEY,      KBD_SHIFT,      KBD_CONTROL,
-/* b0 */ KBD_CAPSLOCK, KBD_ALTERNATE,  KBD_NOKEY,      KBD_NOKEY,
-/* b4 */ KBD_NOKEY,    KBD_NOKEY,      KBD_NOKEY,      KBD_NOKEY,
-/* b8 */ KBD_NOKEY,    KBD_NOKEY,      KBD_NOKEY,      KBD_NOKEY,
-/* bc */ KBD_DEL,      KBD_RET,        KBD_TAB,        '~',
-/* c0 */ '!',          'q',            'a',            'z',
-/* c4 */ KBD_NOKEY,    '@',            'w',            's',
-/* c8 */ 'x',          '>',            KBD_NOKEY,      '#',
-/* cc */ 'e',          'd',            'c',            KBD_NOKEY,
-/* d0 */ '$',          'r',            'f',            'v',
-/* d4 */ ' ',          KBD_NOKEY,      '%',            't',
-/* d8 */ 'g',          'b',            KBD_NOKEY,      '^',
-/* dc */ 'y',          'h',            'n',            KBD_NOKEY,
-/* e0 */ '&',          'u',            'j',            'm',
-/* e4 */ KBD_NOKEY,    '*',            'i',            'k',
-/* e8 */ '<',          KBD_NOKEY,      '(',            'o',
-/* ec */ 'l',          '>',            KBD_NOKEY,      ')',
-/* f0 */ 'p',          KBD_NOKEY,      ':',            '?',
-/* f4 */ KBD_NOKEY,    '+',            '}',            '|',
-/* f8 */ KBD_NOKEY,    '_',            '{',            '"',
-/* fc */ KBD_NOKEY,    KBD_NOKEY,      KBD_NOKEY,      KBD_NOKEY,
-};
-
-/* 
- * Keyboard initialization string.
- */
-static u_char kbdInitString[] = {
-       LK_LED_ENABLE, LED_ALL,         /* show we are resetting keyboard */
-       LK_DEFAULTS,
-       LK_CMD_MODE(LK_AUTODOWN, 1), 
-       LK_CMD_MODE(LK_AUTODOWN, 2), 
-       LK_CMD_MODE(LK_AUTODOWN, 3), 
-       LK_CMD_MODE(LK_DOWN, 4),        /* could also be LK_AUTODOWN */
-       LK_CMD_MODE(LK_UPDOWN, 5),   
-       LK_CMD_MODE(LK_UPDOWN, 6),   
-       LK_CMD_MODE(LK_AUTODOWN, 7), 
-       LK_CMD_MODE(LK_AUTODOWN, 8), 
-       LK_CMD_MODE(LK_AUTODOWN, 9), 
-       LK_CMD_MODE(LK_AUTODOWN, 10), 
-       LK_CMD_MODE(LK_AUTODOWN, 11), 
-       LK_CMD_MODE(LK_AUTODOWN, 12), 
-       LK_CMD_MODE(LK_DOWN, 13), 
-       LK_CMD_MODE(LK_AUTODOWN, 14),
-       LK_AR_ENABLE,                   /* we want autorepeat by default */
-       LK_CL_ENABLE, 0x83,             /* keyclick, volume */
-       LK_KBD_ENABLE,                  /* the keyboard itself */
-       LK_BELL_ENABLE, 0x83,           /* keyboard bell, volume */
-       LK_LED_DISABLE, LED_ALL,        /* clear keyboard leds */
-};
-
 /*
  * Test to see if device is present.
  * Return true if found and initialized ok.
 /*
  * Test to see if device is present.
  * Return true if found and initialized ok.
@@ -363,6 +143,7 @@ dcprobe(cp)
        register struct pdma *pdp;
        register struct tty *tp;
        register int cntr;
        register struct pdma *pdp;
        register struct tty *tp;
        register int cntr;
+       int s;
 
        if (cp->pmax_unit >= NDC)
                return (0);
 
        if (cp->pmax_unit >= NDC)
                return (0);
@@ -381,7 +162,7 @@ dcprobe(cp)
        pdp = &dcpdma[cp->pmax_unit * 4];
        tp = &dc_tty[cp->pmax_unit * 4];
        for (cntr = 0; cntr < 4; cntr++) {
        pdp = &dcpdma[cp->pmax_unit * 4];
        tp = &dc_tty[cp->pmax_unit * 4];
        for (cntr = 0; cntr < 4; cntr++) {
-               pdp->p_addr = dcaddr;
+               pdp->p_addr = (void *)dcaddr;
                pdp->p_arg = (int)tp;
                pdp->p_fcn = dcxint;
                tp->t_addr = (caddr_t)pdp;
                pdp->p_arg = (int)tp;
                pdp->p_fcn = dcxint;
                tp->t_addr = (caddr_t)pdp;
@@ -395,18 +176,29 @@ dcprobe(cp)
        }
        printf("dc%d at nexus0 csr 0x%x priority %d\n",
                cp->pmax_unit, cp->pmax_addr, cp->pmax_pri);
        }
        printf("dc%d at nexus0 csr 0x%x priority %d\n",
                cp->pmax_unit, cp->pmax_addr, cp->pmax_pri);
-       if (cp->pmax_unit == 0) {
-               int s;
 
 
-               s = spltty();
-               dcaddr->dc_lpr = LPR_RXENAB | LPR_B4800 | LPR_8_BIT_CHAR |
-                       KBD_PORT;
-               dcaddr->dc_lpr = LPR_RXENAB | LPR_B4800 | LPR_OPAR |
-                       LPR_PARENB | LPR_8_BIT_CHAR | MOUSE_PORT;
-               MachEmptyWriteBuffer();
-               dcKBDReset();
-               MouseInit();
-               splx(s);
+       /*
+        * Special handling for consoles.
+        */
+       if (cp->pmax_unit == 0) {
+               if (cn_tab.cn_screen) {
+                       s = spltty();
+                       dcaddr->dc_lpr = LPR_RXENAB | LPR_8_BIT_CHAR |
+                               LPR_B4800 | DCKBD_PORT;
+                       dcaddr->dc_lpr = LPR_RXENAB | LPR_B4800 | LPR_OPAR |
+                               LPR_PARENB | LPR_8_BIT_CHAR | DCMOUSE_PORT;
+                       MachEmptyWriteBuffer();
+                       KBDReset(makedev(DCDEV, DCKBD_PORT), dcPutc);
+                       MouseInit(makedev(DCDEV, DCMOUSE_PORT), dcPutc, dcGetc);
+                       splx(s);
+               } else if (major(cn_tab.cn_dev) == DCDEV) {
+                       s = spltty();
+                       dcaddr->dc_lpr = LPR_RXENAB | LPR_8_BIT_CHAR |
+                               LPR_B9600 | minor(cn_tab.cn_dev);
+                       MachEmptyWriteBuffer();
+                       cn_tab.cn_disabled = 0;
+                       splx(s);
+               }
        }
        return (1);
 }
        }
        return (1);
 }
@@ -419,10 +211,9 @@ dcopen(dev, flag, mode, p)
        register struct tty *tp;
        register int unit;
        int s, error = 0;
        register struct tty *tp;
        register int unit;
        int s, error = 0;
-       extern int dcparam();
 
        unit = minor(dev);
 
        unit = minor(dev);
-       if (unit >= dc_cnt || dcpdma[unit].p_addr == 0)
+       if (unit >= dc_cnt || dcpdma[unit].p_addr == (void *)0)
                return (ENXIO);
        tp = &dc_tty[unit];
        tp->t_addr = (caddr_t)&dcpdma[unit];
                return (ENXIO);
        tp = &dc_tty[unit];
        tp->t_addr = (caddr_t)&dcpdma[unit];
@@ -510,6 +301,7 @@ dcwrite(dev, uio, flag)
 /*ARGSUSED*/
 dcioctl(dev, cmd, data, flag, p)
        dev_t dev;
 /*ARGSUSED*/
 dcioctl(dev, cmd, data, flag, p)
        dev_t dev;
+       int cmd;
        caddr_t data;
        int flag;
        struct proc *p;
        caddr_t data;
        int flag;
        struct proc *p;
@@ -581,25 +373,34 @@ dcparam(tp, t)
 
        /* check requested parameters */
         if (ospeed < 0 || (t->c_ispeed && t->c_ispeed != t->c_ospeed) ||
 
        /* check requested parameters */
         if (ospeed < 0 || (t->c_ispeed && t->c_ispeed != t->c_ospeed) ||
-            (cflag & CSIZE) == CS5 || (cflag & CSIZE) == CS6)
+            (cflag & CSIZE) == CS5 || (cflag & CSIZE) == CS6 ||
+           (pmax_boardtype == DS_PMAX && t->c_ospeed == 19200))
                 return (EINVAL);
         /* and copy to tty */
         tp->t_ispeed = t->c_ispeed;
         tp->t_ospeed = t->c_ospeed;
         tp->t_cflag = cflag;
 
                 return (EINVAL);
         /* and copy to tty */
         tp->t_ispeed = t->c_ispeed;
         tp->t_ospeed = t->c_ospeed;
         tp->t_cflag = cflag;
 
-       dcaddr = dcpdma[unit].p_addr;
-       if (tp == dc_tty + KBD_PORT) {
-               /* handle the keyboard specially */
-               dcaddr->dc_lpr = LPR_RXENAB | LPR_B4800 | LPR_8_BIT_CHAR |
-                       KBD_PORT;
-               MachEmptyWriteBuffer();
-               return (0);
-       }
-       if (tp == dc_tty + MOUSE_PORT) {
-               /* handle the mouse specially */
-               dcaddr->dc_lpr = LPR_RXENAB | LPR_B4800 | LPR_OPAR |
-                       LPR_PARENB | LPR_8_BIT_CHAR | MOUSE_PORT;
+       dcaddr = (dcregs *)dcpdma[unit].p_addr;
+
+       /*
+        * Handle console cases specially.
+        */
+       if (cn_tab.cn_screen) {
+               if (unit == DCKBD_PORT) {
+                       dcaddr->dc_lpr = LPR_RXENAB | LPR_8_BIT_CHAR |
+                               LPR_B4800 | DCKBD_PORT;
+                       MachEmptyWriteBuffer();
+                       return (0);
+               } else if (unit == DCMOUSE_PORT) {
+                       dcaddr->dc_lpr = LPR_RXENAB | LPR_B4800 | LPR_OPAR |
+                               LPR_PARENB | LPR_8_BIT_CHAR | DCMOUSE_PORT;
+                       MachEmptyWriteBuffer();
+                       return (0);
+               }
+       } else if (tp->t_dev == cn_tab.cn_dev) {
+               dcaddr->dc_lpr = LPR_RXENAB | LPR_8_BIT_CHAR |
+                       LPR_B9600 | unit;
                MachEmptyWriteBuffer();
                return (0);
        }
                MachEmptyWriteBuffer();
                return (0);
        }
@@ -634,7 +435,7 @@ dcintr(unit)
        register unsigned csr;
 
        unit <<= 2;
        register unsigned csr;
 
        unit <<= 2;
-       dcaddr = dcpdma[unit].p_addr;
+       dcaddr = (dcregs *)dcpdma[unit].p_addr;
        while ((csr = dcaddr->dc_csr) & (CSR_RDONE | CSR_TRDY)) {
                if (csr & CSR_RDONE)
                        dcrint(unit);
        while ((csr = dcaddr->dc_csr) & (CSR_RDONE | CSR_TRDY)) {
                if (csr & CSR_RDONE)
                        dcrint(unit);
@@ -652,7 +453,7 @@ dcrint(unit)
        register struct tty *tp0;
        int overrun = 0;
 
        register struct tty *tp0;
        int overrun = 0;
 
-       dcaddr = dcpdma[unit].p_addr;
+       dcaddr = (dcregs *)dcpdma[unit].p_addr;
        tp0 = &dc_tty[unit];
        while ((c = dcaddr->dc_rbuf) < 0) {     /* char present */
                cc = c & 0xff;
        tp0 = &dc_tty[unit];
        while ((c = dcaddr->dc_rbuf) < 0) {     /* char present */
                cc = c & 0xff;
@@ -663,7 +464,7 @@ dcrint(unit)
                        overrun = 1;
                }
                /* the keyboard requires special translation */
                        overrun = 1;
                }
                /* the keyboard requires special translation */
-               if (tp == &dc_tty[KBD_PORT]) {
+               if (tp == &dc_tty[DCKBD_PORT] && cn_tab.cn_screen) {
 #ifdef KADB
                        if (cc == LK_DO) {
                                spl0();
 #ifdef KADB
                        if (cc == LK_DO) {
                                spl0();
@@ -678,9 +479,9 @@ dcrint(unit)
                                (*dcDivertXInput)(cc);
                                return;
                        }
                                (*dcDivertXInput)(cc);
                                return;
                        }
-                       if ((cc = dcMapChar(cc)) < 0)
+                       if ((cc = kbdMapChar(cc)) < 0)
                                return;
                                return;
-               } else if (tp == &dc_tty[MOUSE_PORT] && dcMouseButtons) {
+               } else if (tp == &dc_tty[DCMOUSE_PORT] && dcMouseButtons) {
                        register MouseReport *mrp;
                        static MouseReport currentRep;
 
                        register MouseReport *mrp;
                        static MouseReport currentRep;
 
@@ -740,7 +541,7 @@ dcxint(tp)
 
        dp = (struct pdma *)tp->t_addr;
        if (dp->p_mem < dp->p_end) {
 
        dp = (struct pdma *)tp->t_addr;
        if (dp->p_mem < dp->p_end) {
-               dcaddr = dp->p_addr;
+               dcaddr = (dcregs *)dp->p_addr;
                dcaddr->dc_tdr = dc_brk[(tp - dc_tty) >> 2] | *dp->p_mem++;
                MachEmptyWriteBuffer();
                DELAY(10);
                dcaddr->dc_tdr = dc_brk[(tp - dc_tty) >> 2] | *dp->p_mem++;
                MachEmptyWriteBuffer();
                DELAY(10);
@@ -758,7 +559,7 @@ dcxint(tp)
        else
                dcstart(tp);
        if (tp->t_outq.c_cc == 0 || !(tp->t_state & TS_BUSY)) {
        else
                dcstart(tp);
        if (tp->t_outq.c_cc == 0 || !(tp->t_state & TS_BUSY)) {
-               dp->p_addr->dc_tcr &= ~(1 << (minor(tp->t_dev) & 03));
+               ((dcregs *)dp->p_addr)->dc_tcr &= ~(1 << (minor(tp->t_dev) & 03));
                MachEmptyWriteBuffer();
                DELAY(10);
        }
                MachEmptyWriteBuffer();
                DELAY(10);
        }
@@ -774,7 +575,7 @@ dcstart(tp)
        int s;
 
        dp = (struct pdma *)tp->t_addr;
        int s;
 
        dp = (struct pdma *)tp->t_addr;
-       dcaddr = dp->p_addr;
+       dcaddr = (dcregs *)dp->p_addr;
        s = spltty();
        if (tp->t_state & (TS_TIMEOUT|TS_BUSY|TS_TTSTOP))
                goto out;
        s = spltty();
        if (tp->t_state & (TS_TIMEOUT|TS_BUSY|TS_TTSTOP))
                goto out;
@@ -788,7 +589,7 @@ dcstart(tp)
        if (tp->t_outq.c_cc == 0)
                goto out;
        /* handle console specially */
        if (tp->t_outq.c_cc == 0)
                goto out;
        /* handle console specially */
-       if (tp == dc_tty) {
+       if (tp == &dc_tty[DCKBD_PORT] && cn_tab.cn_screen) {
                while (tp->t_outq.c_cc > 0) {
                        cc = getc(&tp->t_outq) & 0x7f;
                        cnputc(cc);
                while (tp->t_outq.c_cc > 0) {
                        cc = getc(&tp->t_outq) & 0x7f;
                        cnputc(cc);
@@ -853,48 +654,41 @@ dcmctl(dev, bits, how)
        register dcregs *dcaddr;
        register int unit, mbits;
        int b, s;
        register dcregs *dcaddr;
        register int unit, mbits;
        int b, s;
-#ifdef DS5000
        register int msr;
        register int msr;
-#endif
 
        unit = minor(dev);
        b = 1 << (unit & 03);
 
        unit = minor(dev);
        b = 1 << (unit & 03);
-       dcaddr = dcpdma[unit].p_addr;
+       dcaddr = (dcregs *)dcpdma[unit].p_addr;
        s = spltty();
        /* only channel 2 has modem control (what about line 3?) */
        s = spltty();
        /* only channel 2 has modem control (what about line 3?) */
+       mbits = DML_DTR | DML_DSR | DML_CAR;
        switch (unit & 03) {
        case 2:
                mbits = 0;
                if (dcaddr->dc_tcr & TCR_DTR2)
                        mbits |= DML_DTR;
        switch (unit & 03) {
        case 2:
                mbits = 0;
                if (dcaddr->dc_tcr & TCR_DTR2)
                        mbits |= DML_DTR;
-#ifdef DS3100
-               if (dcaddr->dc_msr & MSR_DSR2)
-                       mbits |= DML_DSR | DML_CAR;
-#endif
-#ifdef DS5000
                msr = dcaddr->dc_msr;
                if (msr & MSR_CD2)
                        mbits |= DML_CAR;
                msr = dcaddr->dc_msr;
                if (msr & MSR_CD2)
                        mbits |= DML_CAR;
-               if (msr & MSR_DSR2)
-                       mbits |= DML_DSR;
-#endif
+               if (msr & MSR_DSR2) {
+                       if (pmax_boardtype == DS_PMAX)
+                               mbits |= DML_CAR | DML_DSR;
+                       else
+                               mbits |= DML_DSR;
+               }
                break;
 
                break;
 
-#ifdef DS5000
        case 3:
        case 3:
-               mbits = 0;
-               if (dcaddr->dc_tcr & TCR_DTR3)
-                       mbits |= DML_DTR;
-               msr = dcaddr->dc_msr;
-               if (msr & MSR_CD3)
-                       mbits |= DML_CAR;
-               if (msr & MSR_DSR3)
-                       mbits |= DML_DSR;
-               break;
-#endif
-
-       default:
-               mbits = DML_DTR | DML_DSR | DML_CAR;
+               if (pmax_boardtype != DS_PMAX) {
+                       mbits = 0;
+                       if (dcaddr->dc_tcr & TCR_DTR3)
+                               mbits |= DML_DTR;
+                       msr = dcaddr->dc_msr;
+                       if (msr & MSR_CD3)
+                               mbits |= DML_CAR;
+                       if (msr & MSR_DSR3)
+                               mbits |= DML_DSR;
+               }
        }
        switch (how) {
        case DMSET:
        }
        switch (how) {
        case DMSET:
@@ -921,13 +715,13 @@ dcmctl(dev, bits, how)
                        dcaddr->dc_tcr &= ~TCR_DTR2;
                break;
 
                        dcaddr->dc_tcr &= ~TCR_DTR2;
                break;
 
-#ifdef DS5000
        case 3:
        case 3:
-               if (mbits & DML_DTR)
-                       dcaddr->dc_tcr |= TCR_DTR3;
-               else
-                       dcaddr->dc_tcr &= ~TCR_DTR3;
-#endif
+               if (pmax_boardtype != DS_PMAX) {
+                       if (mbits & DML_DTR)
+                               dcaddr->dc_tcr |= TCR_DTR3;
+                       else
+                               dcaddr->dc_tcr &= ~TCR_DTR3;
+               }
        }
        if ((mbits & DML_DTR) && (dcsoftCAR[unit >> 2] & b))
                dc_tty[unit].t_state |= TS_CARR_ON;
        }
        if ((mbits & DML_DTR) && (dcsoftCAR[unit >> 2] & b))
                dc_tty[unit].t_state |= TS_CARR_ON;
@@ -939,8 +733,7 @@ dcmctl(dev, bits, how)
  * This is called by timeout() periodically.
  * Check to see if modem status bits have changed.
  */
  * This is called by timeout() periodically.
  * Check to see if modem status bits have changed.
  */
-/* ARGSUSED */
-static void
+void
 dcscan(arg)
        void *arg;
 {
 dcscan(arg)
        void *arg;
 {
@@ -951,7 +744,7 @@ dcscan(arg)
 
        s = spltty();
        /* only channel 2 has modem control (what about line 3?) */
 
        s = spltty();
        /* only channel 2 has modem control (what about line 3?) */
-       dcaddr = dcpdma[i = 2].p_addr;
+       dcaddr = (dcregs *)dcpdma[i = 2].p_addr;
        tp = &dc_tty[i];
        bit = TCR_DTR2;
        if (dcsoftCAR[i >> 2] & bit)
        tp = &dc_tty[i];
        bit = TCR_DTR2;
        if (dcsoftCAR[i >> 2] & bit)
@@ -972,111 +765,12 @@ dcscan(arg)
 /*
  * ----------------------------------------------------------------------------
  *
 /*
  * ----------------------------------------------------------------------------
  *
- * dcKBDPutc --
+ * dcGetc --
  *
  *
- *     Put a character out to the keyboard.
+ *     Read a character from a serial line.
  *
  * Results:
  *
  * Results:
- *     None.
- *
- * Side effects:
- *     A character is written to the keyboard.
- *
- * ----------------------------------------------------------------------------
- */
-void
-dcKBDPutc(c)
-       register int c;
-{
-       register dcregs *dcaddr;
-       register u_short tcr;
-       register int timeout;
-       int s, line;
-
-       s = spltty();
-
-       dcaddr = dcpdma[KBD_PORT].p_addr;
-       tcr = dcaddr->dc_tcr;
-       dcaddr->dc_tcr = tcr | (1 << KBD_PORT);
-       MachEmptyWriteBuffer();
-       DELAY(10);
-       while (1) {
-               /*
-                * Wait for transmitter to be not busy.
-                */
-               timeout = 1000000;
-               while (!(dcaddr->dc_csr & CSR_TRDY) && timeout > 0)
-                       timeout--;
-               if (timeout == 0) {
-                       printf("dcKBDPutc: timeout waiting for CSR_TRDY\n");
-                       break;
-               }
-               line = (dcaddr->dc_csr >> 8) & 3;
-               /*
-                * Check to be sure its the right port.
-                */
-               if (line != KBD_PORT) {
-                       tcr |= 1 << line;
-                       dcaddr->dc_tcr &= ~(1 << line);
-                       MachEmptyWriteBuffer();
-                       DELAY(10);
-                       continue;
-               }
-               /*
-                * Start sending the character.
-                */
-               dcaddr->dc_tdr = dc_brk[0] | (c & 0xff);
-               MachEmptyWriteBuffer();
-               DELAY(10);
-               /*
-                * Wait for character to be sent.
-                */
-               while (1) {
-                       /*
-                        * cc -O bug: this code produces and infinite loop!
-                        * while (!(dcaddr->dc_csr & CSR_TRDY))
-                        *      ;
-                        */
-                       timeout = 1000000;
-                       while (!(dcaddr->dc_csr & CSR_TRDY) && timeout > 0)
-                               timeout--;
-                       line = (dcaddr->dc_csr >> 8) & 3;
-                       if (line != KBD_PORT) {
-                               tcr |= 1 << line;
-                               dcaddr->dc_tcr &= ~(1 << line);
-                               MachEmptyWriteBuffer();
-                               DELAY(10);
-                               continue;
-                       }
-                       dcaddr->dc_tcr &= ~(1 << KBD_PORT);
-                       MachEmptyWriteBuffer();
-                       DELAY(10);
-                       break;
-               }
-               break;
-       }
-       /*
-        * Enable interrupts for other lines which became ready.
-        */
-       if (tcr & 0xF) {
-               dcaddr->dc_tcr = tcr;
-               MachEmptyWriteBuffer();
-               DELAY(10);
-       }
-
-       splx(s);
-}
-
-#ifdef DEBUG
-/*
- * ----------------------------------------------------------------------------
- *
- * dcDebugGetc --
- *
- *     Read a character from the keyboard if one is ready (i.e., don't wait).
- *
- * Results:
- *     A character read from the mouse, -1 if none were ready.
+ *     A character read from the serial port.
  *
  * Side effects:
  *     None.
  *
  * Side effects:
  *     None.
@@ -1084,213 +778,47 @@ dcKBDPutc(c)
  * ----------------------------------------------------------------------------
  */
 int
  * ----------------------------------------------------------------------------
  */
 int
-dcDebugGetc()
+dcGetc(dev)
+       dev_t dev;
 {
        register dcregs *dcaddr;
        register int c;
        int s;
 
 {
        register dcregs *dcaddr;
        register int c;
        int s;
 
-       dcaddr = dcpdma[KBD_PORT].p_addr;
+       dcaddr = (dcregs *)dcpdma[minor(dev)].p_addr;
        if (!dcaddr)
                return (0);
        if (!dcaddr)
                return (0);
-
-       s = spltty();
-       if (c = debugChar)
-               debugChar = 0;
-       else {
-               while (dcaddr->dc_csr & CSR_RDONE) {
-                       c = dcaddr->dc_rbuf;
-                       DELAY(10);
-                       if (((c >> 8) & 03) == KBD_PORT)
-                               break;
-                       c = 0;
-               }
-       }
-       splx(s);
-
-       return (c & 0xff);
-}
-#endif
-
-/*
- * ----------------------------------------------------------------------------
- *
- * dcKBDGetc --
- *
- *     Read a character from the keyboard.
- *
- * Results:
- *     A character read from the keyboard.
- *
- * Side effects:
- *     None.
- *
- * ----------------------------------------------------------------------------
- */
-int
-dcKBDGetc()
-{
-       register dcregs *dcaddr;
-       register int c;
-       int s;
-
-       dcaddr = dcpdma[KBD_PORT].p_addr;
-       if (!dcaddr)
-               return (-1);
        s = spltty();
        for (;;) {
                if (!(dcaddr->dc_csr & CSR_RDONE))
                        continue;
                c = dcaddr->dc_rbuf;
                DELAY(10);
        s = spltty();
        for (;;) {
                if (!(dcaddr->dc_csr & CSR_RDONE))
                        continue;
                c = dcaddr->dc_rbuf;
                DELAY(10);
-               if (((c >> 8) & 03) != KBD_PORT)
-                       continue;
-               if ((c = dcMapChar(c & 0xff)) >= 0)
+               if (((c >> 8) & 03) == (minor(dev) & 03))
                        break;
        }
        splx(s);
                        break;
        }
        splx(s);
-       return (c);
-}
-
-/*
- * ----------------------------------------------------------------------------
- *
- * dcMapChar --
- *
- *     Map characters from the keyboard to ASCII. Return -1 if there is
- *     no valid mapping.
- *
- * Results:
- *     None.
- *
- * Side effects:
- *     Remember state of shift and control keys.
- *
- * ----------------------------------------------------------------------------
- */
-static int
-dcMapChar(cc)
-       int cc;
-{
-       static u_char shiftDown;
-       static u_char ctrlDown;
-       static u_char lastChar;
-
-       switch (cc) {
-       case KEY_REPEAT:
-               cc = lastChar;
-               goto done;
-
-       case KEY_UP:
-               shiftDown = 0;
-               ctrlDown = 0;
-               return (-1);
-
-       case KEY_SHIFT:
-               if (ctrlDown)
-                       shiftDown = 0;
-               else
-                       shiftDown = 1;
-               return (-1);
-
-       case KEY_CONTROL:
-               if (shiftDown)
-                       ctrlDown = 0;
-               else
-                       ctrlDown = 1;
-               return (-1);
-
-       case LK_POWER_ERROR:
-       case LK_KDOWN_ERROR:
-       case LK_INPUT_ERROR:
-       case LK_OUTPUT_ERROR:
-               log(LOG_WARNING,
-                       "dc0,0: keyboard error, code=%x\n", cc);
-               return (-1);
-       }
-       if (shiftDown)
-               cc = shiftedAscii[cc];
-       else
-               cc = unshiftedAscii[cc];
-       if (cc >= KBD_NOKEY) {
-               /*
-                * A function key was typed - ignore it.
-                */
-               return (-1);
-       }
-       if (cc >= 'a' && cc <= 'z') {
-               if (ctrlDown)
-                       cc = cc - 'a' + '\1'; /* ^A */
-               else if (shiftDown)
-                       cc = cc - 'a' + 'A';
-       } else if (ctrlDown) {
-               if (cc >= '[' && cc <= '_')
-                       cc = cc - '@';
-               else if (cc == ' ' || cc == '@')
-                       cc = '\0';
-       }
-       lastChar = cc;
-done:
-       return (cc);
+       return (c & 0xff);
 }
 
 /*
 }
 
 /*
- * ----------------------------------------------------------------------------
- *
- * dcKBDReset --
- *
- *     Reset the keyboard to default characteristics.
- *
- * Results:
- *     None.
- *
- * Side effects:
- *     None.
- *
- * ----------------------------------------------------------------------------
+ * Send a char on a port, non interrupt driven.
  */
 void
  */
 void
-dcKBDReset()
-{
-       register int i;
-       static int inKBDReset;
-
-       if (inKBDReset)
-               return;
-       inKBDReset = 1;
-       for (i = 0; i < sizeof(kbdInitString); i++)
-               dcKBDPutc((int)kbdInitString[i]);
-       inKBDReset = 0;
-}
-
-/*
- * ----------------------------------------------------------------------------
- *
- * MousePutc --
- *
- *     Write a character to the mouse.
- *     This is only called at initialization time.
- *
- * Results:
- *     None.
- *
- * Side effects:
- *     A character is written to the mouse.
- *
- * ----------------------------------------------------------------------------
- */
-static void
-MousePutc(c)
+dcPutc(dev, c)
+       dev_t dev;
        int c;
 {
        register dcregs *dcaddr;
        register u_short tcr;
        register int timeout;
        int c;
 {
        register dcregs *dcaddr;
        register u_short tcr;
        register int timeout;
-       int line;
+       int s, line;
+
+       s = spltty();
 
 
-       dcaddr = dcpdma[MOUSE_PORT].p_addr;
+       dcaddr = (dcregs *)dcpdma[minor(dev)].p_addr;
        tcr = dcaddr->dc_tcr;
        tcr = dcaddr->dc_tcr;
-       dcaddr->dc_tcr = tcr | (1 << MOUSE_PORT);
+       dcaddr->dc_tcr = tcr | (1 << minor(dev));
        MachEmptyWriteBuffer();
        DELAY(10);
        while (1) {
        MachEmptyWriteBuffer();
        DELAY(10);
        while (1) {
@@ -1301,14 +829,14 @@ MousePutc(c)
                while (!(dcaddr->dc_csr & CSR_TRDY) && timeout > 0)
                        timeout--;
                if (timeout == 0) {
                while (!(dcaddr->dc_csr & CSR_TRDY) && timeout > 0)
                        timeout--;
                if (timeout == 0) {
-                       printf("MousePutc: timeout waiting for CSR_TRDY\n");
+                       printf("dcPutc: timeout waiting for CSR_TRDY\n");
                        break;
                }
                line = (dcaddr->dc_csr >> 8) & 3;
                /*
                 * Check to be sure its the right port.
                 */
                        break;
                }
                line = (dcaddr->dc_csr >> 8) & 3;
                /*
                 * Check to be sure its the right port.
                 */
-               if (line != MOUSE_PORT) {
+               if (line != minor(dev)) {
                        tcr |= 1 << line;
                        dcaddr->dc_tcr &= ~(1 << line);
                        MachEmptyWriteBuffer();
                        tcr |= 1 << line;
                        dcaddr->dc_tcr &= ~(1 << line);
                        MachEmptyWriteBuffer();
@@ -1334,14 +862,14 @@ MousePutc(c)
                        while (!(dcaddr->dc_csr & CSR_TRDY) && timeout > 0)
                                timeout--;
                        line = (dcaddr->dc_csr >> 8) & 3;
                        while (!(dcaddr->dc_csr & CSR_TRDY) && timeout > 0)
                                timeout--;
                        line = (dcaddr->dc_csr >> 8) & 3;
-                       if (line != MOUSE_PORT) {
+                       if (line != minor(dev)) {
                                tcr |= 1 << line;
                                dcaddr->dc_tcr &= ~(1 << line);
                                MachEmptyWriteBuffer();
                                DELAY(10);
                                continue;
                        }
                                tcr |= 1 << line;
                                dcaddr->dc_tcr &= ~(1 << line);
                                MachEmptyWriteBuffer();
                                DELAY(10);
                                continue;
                        }
-                       dcaddr->dc_tcr &= ~(1 << MOUSE_PORT);
+                       dcaddr->dc_tcr &= ~(1 << minor(dev));
                        MachEmptyWriteBuffer();
                        DELAY(10);
                        break;
                        MachEmptyWriteBuffer();
                        DELAY(10);
                        break;
@@ -1356,96 +884,7 @@ MousePutc(c)
                MachEmptyWriteBuffer();
                DELAY(10);
        }
                MachEmptyWriteBuffer();
                DELAY(10);
        }
-}
-
-/*
- * ----------------------------------------------------------------------------
- *
- * MouseGetc --
- *
- *     Read a character from the mouse.
- *     This is only called at initialization time.
- *
- * Results:
- *     A character read from the mouse, -1 if we timed out waiting.
- *
- * Side effects:
- *     None.
- *
- * ----------------------------------------------------------------------------
- */
-static int
-MouseGetc()
-{
-       register dcregs *dcaddr;
-       register int timeout;
-       register int c;
-
-       dcaddr = dcpdma[MOUSE_PORT].p_addr;
-       for (timeout = 1000000; timeout > 0; timeout--) {
-               if (!(dcaddr->dc_csr & CSR_RDONE))
-                       continue;
-               c = dcaddr->dc_rbuf;
-               DELAY(10);
-               if (((c >> 8) & 03) != MOUSE_PORT)
-                       continue;
-               return (c & 0xff);
-       }
 
 
-       return (-1);
-}
-
-/*
- * ----------------------------------------------------------------------------
- *
- * MouseInit --
- *
- *     Initialize the mouse.
- *
- * Results:
- *     None.
- *
- * Side effects:
- *     None.
- *
- * ----------------------------------------------------------------------------
- */
-static void
-MouseInit()
-{
-       int id_byte1, id_byte2, id_byte3, id_byte4;
-
-       /*
-        * Initialize the mouse.
-        */
-       MousePutc(MOUSE_SELF_TEST);
-       id_byte1 = MouseGetc();
-       if (id_byte1 < 0) {
-               printf("MouseInit: Timeout on 1st byte of self-test report\n");
-               return;
-       }
-       id_byte2 = MouseGetc();
-       if (id_byte2 < 0) {
-               printf("MouseInit: Timeout on 2nd byte of self-test report\n");
-               return;
-       }
-       id_byte3 = MouseGetc();
-       if (id_byte3 < 0) {
-               printf("MouseInit: Timeout on 3rd byte of self-test report\n");
-               return;
-       }
-       id_byte4 = MouseGetc();
-       if (id_byte4 < 0) {
-               printf("MouseInit: Timeout on 4th byte of self-test report\n");
-               return;
-       }
-       if ((id_byte2 & 0x0f) != 0x2)
-               printf("MouseInit: We don't have a mouse!!!\n");
-       /*
-        * For some reason, the mouse doesn't see this command if it comes
-        * too soon after a self test.
-        */
-       DELAY(100);
-       MousePutc(MOUSE_INCREMENTAL);
+       splx(s);
 }
 #endif /* NDC */
 }
 #endif /* NDC */
index 7e99316..629184d 100644 (file)
@@ -1,19 +1,19 @@
-/*
- * Copyright (c) 1992 Regents of the University of California.
+/*-
+ * Copyright (c) 1992 The Regents of the University of California.
  * All rights reserved.
  *
  * This code is derived from software contributed to Berkeley by
  * All rights reserved.
  *
  * This code is derived from software contributed to Berkeley by
- * Ralph Campbell.
+ * Ralph Campbell and Rick Macklem.
  *
  * %sccs.include.redist.c%
  *
  *
  * %sccs.include.redist.c%
  *
- *     @(#)if_le.c     7.7 (Berkeley) %G%
+ *     @(#)if_le.c     7.8 (Berkeley) %G%
  */
 
  */
 
-#include "le.h"
+#include <le.h>
 #if NLE > 0
 
 #if NLE > 0
 
-#include "bpfilter.h"
+#include <bpfilter.h>
 
 /*
  * AMD 7990 LANCE
 
 /*
  * AMD 7990 LANCE
 #endif
 
 #include <machine/machConst.h>
 #endif
 
 #include <machine/machConst.h>
+
+#include <pmax/pmax/pmaxtype.h>
+#include <pmax/pmax/kn01.h>
+#include <pmax/pmax/kmin.h>
+#include <pmax/pmax/asic.h>
+
 #include <pmax/dev/device.h>
 #include <pmax/dev/if_lereg.h>
 
 #include <pmax/dev/device.h>
 #include <pmax/dev/if_lereg.h>
 
@@ -84,7 +90,11 @@ struct       le_softc {
 #define        sc_if   sc_ac.ac_if     /* network-visible interface */
 #define        sc_addr sc_ac.ac_enaddr /* hardware Ethernet address */
        volatile struct lereg1 *sc_r1;  /* LANCE registers */
 #define        sc_if   sc_ac.ac_if     /* network-visible interface */
 #define        sc_addr sc_ac.ac_enaddr /* hardware Ethernet address */
        volatile struct lereg1 *sc_r1;  /* LANCE registers */
-       volatile struct lereg2 *sc_r2;  /* dual-port RAM */
+       volatile void *sc_r2;   /* dual-port RAM */
+       int     sc_ler2pad;     /* Do ring descriptors require short pads? */
+       void    (*sc_copytobuf)(); /* Copy to buffer */
+       void    (*sc_copyfrombuf)(); /* Copy from buffer */
+       void    (*sc_zerobuf)(); /* and Zero bytes in buffer */
        int     sc_rmd;         /* predicted next rmd to process */
        int     sc_tmd;         /* last tmd processed */
        int     sc_tmdnext;     /* next tmd to transmit with */
        int     sc_rmd;         /* predicted next rmd to process */
        int     sc_tmd;         /* last tmd processed */
        int     sc_tmdnext;     /* next tmd to transmit with */
@@ -107,17 +117,10 @@ struct    le_softc {
 #endif
 } le_softc[NLE];
 
 #endif
 } le_softc[NLE];
 
-#ifdef DS3100
 /* access LANCE registers */
 /* access LANCE registers */
+static void lewritereg();
 #define        LERDWR(cntl, src, dst)  { (dst) = (src); DELAY(10); }
 #define        LERDWR(cntl, src, dst)  { (dst) = (src); DELAY(10); }
-
-#define CPU_TO_CHIP_ADDR(cpu) \
-       (((unsigned)(&(((struct lereg2 *)0)->cpu))) >> 1)
-#endif
-
-#ifdef DS5000
-/* access LANCE registers */
-#define        LERDWR(cntl, src, dst)  (dst) = (src);
+#define        LEWREG(src, dst)        lewritereg(&(dst), (src))
 
 #define CPU_TO_CHIP_ADDR(cpu) \
        ((unsigned)(&(((struct lereg2 *)0)->cpu)))
 
 #define CPU_TO_CHIP_ADDR(cpu) \
        ((unsigned)(&(((struct lereg2 *)0)->cpu)))
@@ -125,7 +128,13 @@ struct     le_softc {
 #define LE_OFFSET_RAM          0x0
 #define LE_OFFSET_LANCE                0x100000
 #define LE_OFFSET_ROM          0x1c0000
 #define LE_OFFSET_RAM          0x0
 #define LE_OFFSET_LANCE                0x100000
 #define LE_OFFSET_ROM          0x1c0000
-#endif
+
+void copytobuf_contig(), copyfrombuf_contig(), bzerobuf_contig();
+void copytobuf_gap2(), copyfrombuf_gap2(), bzerobuf_gap2();
+void copytobuf_gap16(), copyfrombuf_gap16(), bzerobuf_gap16();
+
+extern int pmax_boardtype;
+extern u_long le_iomem;
 
 /*
  * Test to see if device is present.
 
 /*
  * Test to see if device is present.
@@ -144,38 +153,73 @@ leprobe(dp)
        int i;
        extern int leinit(), leioctl(), lestart(), ether_output();
 
        int i;
        extern int leinit(), leioctl(), lestart(), ether_output();
 
-#ifdef DS3100
-       le->sc_r1 = ler1 = (volatile struct lereg1 *)dp->pmax_addr;
-       le->sc_r2 = (volatile struct lereg2 *)MACH_NETWORK_BUFFER_ADDR;
+       switch (pmax_boardtype) {
+       case DS_PMAX:
+               le->sc_r1 = ler1 = (volatile struct lereg1 *)dp->pmax_addr;
+               le->sc_r2 = (volatile void *)MACH_PHYS_TO_UNCACHED(0x19000000);
+               cp = (u_char *)(MACH_PHYS_TO_UNCACHED(KN01_SYS_CLOCK) + 1);
+               le->sc_ler2pad = 1;
+               le->sc_copytobuf = copytobuf_gap2;
+               le->sc_copyfrombuf = copyfrombuf_gap2;
+               le->sc_zerobuf = bzerobuf_gap2;
+               break;
+       case DS_3MIN:
+       case DS_MAXINE:
+               if (dp->pmax_unit == 0) {
+                       volatile u_int *ssr, *ldp;
+
+                       le->sc_r1 = ler1 = (volatile struct lereg1 *)
+                               MACH_PHYS_TO_UNCACHED(KMIN_SYS_LANCE);
+                       le->sc_r2 = (volatile void *)
+                               MACH_PHYS_TO_UNCACHED(le_iomem);
+                       cp = (u_char *)MACH_PHYS_TO_UNCACHED(
+                               KMIN_SYS_ETHER_ADDRESS);
+                       le->sc_ler2pad = 1;
+                       le->sc_copytobuf = copytobuf_gap16;
+                       le->sc_copyfrombuf = copyfrombuf_gap16;
+                       le->sc_zerobuf = bzerobuf_gap16;
 
 
-       /*
-        * Read the ethernet address.
-        * See "DECstation 3100 Desktop Workstation Functional Specification".
-        */
-       cp = (u_char *)(MACH_CLOCK_ADDR + 1);
-       for (i = 0; i < sizeof(le->sc_addr); i++) {
-               le->sc_addr[i] = *cp;
-               cp += 4;
-       }
-#endif
-#ifdef DS5000
-       le->sc_r1 = ler1 = (volatile struct lereg1 *)
-               (dp->pmax_addr + LE_OFFSET_LANCE);
-       le->sc_r2 = (volatile struct lereg2 *)(dp->pmax_addr + LE_OFFSET_RAM);
+                       /*
+                        * And enable Lance dma through the asic.
+                        */
+                       ssr = (volatile u_int *)
+                               MACH_PHYS_TO_UNCACHED(KMIN_REG_CSR);
+                       ldp = (volatile u_int *)
+                               MACH_PHYS_TO_UNCACHED(KMIN_REG_LANCE_DMAPTR);
+                       *ldp = (le_iomem << 3); /* phys addr << 3 */
+                       *ssr |= ASIC_CSR_DMAEN_LANCE;
+                       break;
+               }
+               /*
+                * Units other than 0 are turbochannel option boards and fall
+                * through to DS_3MAX.
+                */
+       case DS_3MAX:
+               le->sc_r1 = ler1 = (volatile struct lereg1 *)
+                       (dp->pmax_addr + LE_OFFSET_LANCE);
+               le->sc_r2 = (volatile void *)(dp->pmax_addr + LE_OFFSET_RAM);
+               cp = (u_char *)(dp->pmax_addr + LE_OFFSET_ROM + 2);
+               le->sc_ler2pad = 0;
+               le->sc_copytobuf = copytobuf_contig;
+               le->sc_copyfrombuf = copyfrombuf_contig;
+               le->sc_zerobuf = bzerobuf_contig;
+               break;
+       default:
+               printf("Unknown CPU board type %d\n", pmax_boardtype);
+               return (0);
+       };
 
        /*
 
        /*
-        * Read the ethernet address.
+        * Get the ethernet address out of rom
         */
         */
-       cp = (u_char *)(dp->pmax_addr + LE_OFFSET_ROM + 2);
        for (i = 0; i < sizeof(le->sc_addr); i++) {
                le->sc_addr[i] = *cp;
                cp += 4;
        }
        for (i = 0; i < sizeof(le->sc_addr); i++) {
                le->sc_addr[i] = *cp;
                cp += 4;
        }
-#endif
 
        /* make sure the chip is stopped */
 
        /* make sure the chip is stopped */
-       LERDWR(ler0, LE_CSR0, ler1->ler1_rap);
-       LERDWR(ler0, LE_STOP, ler1->ler1_rdp);
+       LEWREG(LE_CSR0, ler1->ler1_rap);
+       LEWREG(LE_STOP, ler1->ler1_rdp);
 
        ifp->if_unit = dp->pmax_unit;
        ifp->if_name = "le";
 
        ifp->if_unit = dp->pmax_unit;
        ifp->if_name = "le";
@@ -196,22 +240,25 @@ leprobe(dp)
        return (1);
 }
 
        return (1);
 }
 
-ledrinit(ler2)
-       register volatile struct lereg2 *ler2;
+ledrinit(le)
+       struct le_softc *le;
 {
 {
+       register volatile void *rp;
        register int i;
 
        for (i = 0; i < LERBUF; i++) {
        register int i;
 
        for (i = 0; i < LERBUF; i++) {
-               ler2->ler2_rmd[i].rmd0 = CPU_TO_CHIP_ADDR(ler2_rbuf[i][0]);
-               ler2->ler2_rmd[i].rmd1 = LE_OWN;
-               ler2->ler2_rmd[i].rmd2 = -LEMTU;
-               ler2->ler2_rmd[i].rmd3 = 0;
+               rp = LER2_RMDADDR(le->sc_r2, i);
+               LER2_rmd0(rp, CPU_TO_CHIP_ADDR(ler2_rbuf[i][0]));
+               LER2_rmd1(rp, LE_OWN);
+               LER2_rmd2(rp, -LEMTU);
+               LER2_rmd3(rp, 0);
        }
        for (i = 0; i < LETBUF; i++) {
        }
        for (i = 0; i < LETBUF; i++) {
-               ler2->ler2_tmd[i].tmd0 = CPU_TO_CHIP_ADDR(ler2_tbuf[i][0]);
-               ler2->ler2_tmd[i].tmd1 = 0;
-               ler2->ler2_tmd[i].tmd2 = 0;
-               ler2->ler2_tmd[i].tmd3 = 0;
+               rp = LER2_TMDADDR(le->sc_r2, i);
+               LER2_tmd0(rp, CPU_TO_CHIP_ADDR(ler2_tbuf[i][0]));
+               LER2_tmd1(rp, 0);
+               LER2_tmd2(rp, 0);
+               LER2_tmd3(rp, 0);
        }
 }
 
        }
 }
 
@@ -220,74 +267,71 @@ lereset(unit)
 {
        register struct le_softc *le = &le_softc[unit];
        register volatile struct lereg1 *ler1 = le->sc_r1;
 {
        register struct le_softc *le = &le_softc[unit];
        register volatile struct lereg1 *ler1 = le->sc_r1;
-       register volatile struct lereg2 *ler2 = le->sc_r2;
+       register volatile void *ler2 = le->sc_r2;
        register int timo = 100000;
        register int stat;
 
 #ifdef lint
        stat = unit;
 #endif
        register int timo = 100000;
        register int stat;
 
 #ifdef lint
        stat = unit;
 #endif
+       LEWREG(LE_CSR0, ler1->ler1_rap);
+       LEWREG(LE_STOP, ler1->ler1_rdp);
+
+       /*
+        * Setup for transmit/receive
+        */
 #if NBPFILTER > 0
        if (le->sc_if.if_flags & IFF_PROMISC)
                /* set the promiscuous bit */
 #if NBPFILTER > 0
        if (le->sc_if.if_flags & IFF_PROMISC)
                /* set the promiscuous bit */
-               le->sc_r2->ler2_mode = LE_MODE|0x8000;
+               LER2_mode(ler2, LE_MODE|0x8000);
        else
        else
-               le->sc_r2->ler2_mode = LE_MODE;
 #endif
 #endif
-       LERDWR(ler0, LE_CSR0, ler1->ler1_rap);
-       LERDWR(ler0, LE_STOP, ler1->ler1_rdp);
-
-       /*
-        * Setup for transmit/receive
-        */
-       ler2->ler2_mode = LE_MODE;
-       ler2->ler2_padr0 = (le->sc_addr[1] << 8) | le->sc_addr[0];
-       ler2->ler2_padr1 = (le->sc_addr[3] << 8) | le->sc_addr[2];
-       ler2->ler2_padr2 = (le->sc_addr[5] << 8) | le->sc_addr[4];
+               LER2_mode(ler2, LE_MODE);
+       LER2_padr0(ler2, (le->sc_addr[1] << 8) | le->sc_addr[0]);
+       LER2_padr1(ler2, (le->sc_addr[3] << 8) | le->sc_addr[2]);
+       LER2_padr2(ler2, (le->sc_addr[5] << 8) | le->sc_addr[4]);
 #ifdef RMP
        /*
         * Set up logical addr filter to accept multicast 9:0:9:0:0:4
         * This should be an ioctl() to the driver.  (XXX)
         */
 #ifdef RMP
        /*
         * Set up logical addr filter to accept multicast 9:0:9:0:0:4
         * This should be an ioctl() to the driver.  (XXX)
         */
-       ler2->ler2_ladrf0 = 0x0010;
-       ler2->ler2_ladrf1 = 0x0;
-       ler2->ler2_ladrf2 = 0x0;
-       ler2->ler2_ladrf3 = 0x0;
+       LER2_ladrf0(ler2, 0x0010);
+       LER2_ladrf1(ler2, 0x0);
+       LER2_ladrf2(ler2, 0x0);
+       LER2_ladrf3(ler2, 0x0);
 #else
 #else
-       ler2->ler2_ladrf0 = 0;
-       ler2->ler2_ladrf1 = 0;
-       ler2->ler2_ladrf2 = 0;
-       ler2->ler2_ladrf3 = 0;
+       LER2_ladrf0(ler2, 0);
+       LER2_ladrf1(ler2, 0);
+       LER2_ladrf2(ler2, 0);
+       LER2_ladrf3(ler2, 0);
 #endif
 #endif
-       ler2->ler2_rlen = LE_RLEN;
-       ler2->ler2_rdra = CPU_TO_CHIP_ADDR(ler2_rmd[0]);
-       ler2->ler2_tlen = LE_TLEN;
-       ler2->ler2_tdra = CPU_TO_CHIP_ADDR(ler2_tmd[0]);
-       ledrinit(ler2);
+       LER2_rlen(ler2, LE_RLEN);
+       LER2_rdra(ler2, CPU_TO_CHIP_ADDR(ler2_rmd[0]));
+       LER2_tlen(ler2, LE_TLEN);
+       LER2_tdra(ler2, CPU_TO_CHIP_ADDR(ler2_tmd[0]));
+       ledrinit(le);
        le->sc_rmd = 0;
        le->sc_tmd = LETBUF - 1;
        le->sc_tmdnext = 0;
 
        le->sc_rmd = 0;
        le->sc_tmd = LETBUF - 1;
        le->sc_tmdnext = 0;
 
-       LERDWR(ler0, LE_CSR1, ler1->ler1_rap);
-       LERDWR(ler0, CPU_TO_CHIP_ADDR(ler2_mode), ler1->ler1_rdp);
-       LERDWR(ler0, LE_CSR2, ler1->ler1_rap);
-       LERDWR(ler0, 0, ler1->ler1_rdp);
-       LERDWR(ler0, LE_CSR3, ler1->ler1_rap);
-       LERDWR(ler0, 0, ler1->ler1_rdp);
-       LERDWR(ler0, LE_CSR0, ler1->ler1_rap);
+       LEWREG(LE_CSR1, ler1->ler1_rap);
+       LEWREG(CPU_TO_CHIP_ADDR(ler2_mode), ler1->ler1_rdp);
+       LEWREG(LE_CSR2, ler1->ler1_rap);
+       LEWREG(0, ler1->ler1_rdp);
+       LEWREG(LE_CSR3, ler1->ler1_rap);
+       LEWREG(0, ler1->ler1_rdp);
+       LEWREG(LE_CSR0, ler1->ler1_rap);
        LERDWR(ler0, LE_INIT, ler1->ler1_rdp);
        LERDWR(ler0, LE_INIT, ler1->ler1_rdp);
-       MachEmptyWriteBuffer();
        do {
                if (--timo == 0) {
                        printf("le%d: init timeout, stat = 0x%x\n",
                               unit, stat);
                        break;
                }
        do {
                if (--timo == 0) {
                        printf("le%d: init timeout, stat = 0x%x\n",
                               unit, stat);
                        break;
                }
-               LERDWR(ler0, ler1->ler1_rdp, stat);
+               stat = ler1->ler1_rdp;
        } while ((stat & LE_IDON) == 0);
        LERDWR(ler0, LE_IDON, ler1->ler1_rdp);
        LERDWR(ler0, LE_STRT | LE_INEA, ler1->ler1_rdp);
        } while ((stat & LE_IDON) == 0);
        LERDWR(ler0, LE_IDON, ler1->ler1_rdp);
        LERDWR(ler0, LE_STRT | LE_INEA, ler1->ler1_rdp);
-       MachEmptyWriteBuffer();
        le->sc_if.if_flags &= ~IFF_OACTIVE;
 }
 
        le->sc_if.if_flags &= ~IFF_OACTIVE;
 }
 
@@ -314,7 +358,9 @@ leinit(unit)
 }
 
 #define        LENEXTTMP \
 }
 
 #define        LENEXTTMP \
-       if (++bix == LETBUF) bix = 0, tmd = le->sc_r2->ler2_tmd; else ++tmd
+       if (++bix == LETBUF) \
+               bix = 0; \
+       tmd = LER2_TMDADDR(le->sc_r2, bix)
 
 /*
  * Start output on interface.  Get another datagram to send
 
 /*
  * Start output on interface.  Get another datagram to send
@@ -326,36 +372,35 @@ lestart(ifp)
 {
        register struct le_softc *le = &le_softc[ifp->if_unit];
        register int bix = le->sc_tmdnext;
 {
        register struct le_softc *le = &le_softc[ifp->if_unit];
        register int bix = le->sc_tmdnext;
-       register volatile struct letmd *tmd = &le->sc_r2->ler2_tmd[bix];
+       register volatile void *tmd = LER2_TMDADDR(le->sc_r2, bix);
        register struct mbuf *m;
        int len = 0;
 
        if ((le->sc_if.if_flags & IFF_RUNNING) == 0)
                return (0);
        while (bix != le->sc_tmd) {
        register struct mbuf *m;
        int len = 0;
 
        if ((le->sc_if.if_flags & IFF_RUNNING) == 0)
                return (0);
        while (bix != le->sc_tmd) {
-               if (tmd->tmd1 & LE_OWN)
+               if (LER2V_tmd1(tmd) & LE_OWN)
                        panic("lestart");
                IF_DEQUEUE(&le->sc_if.if_snd, m);
                if (m == 0)
                        break;
                        panic("lestart");
                IF_DEQUEUE(&le->sc_if.if_snd, m);
                if (m == 0)
                        break;
-               len = leput(le->sc_r2->ler2_tbuf[bix], m);
 #if NBPFILTER > 0
                /*
                 * If bpf is listening on this interface, let it
                 * see the packet before we commit it to the wire.
                 */
                if (le->sc_bpf)
 #if NBPFILTER > 0
                /*
                 * If bpf is listening on this interface, let it
                 * see the packet before we commit it to the wire.
                 */
                if (le->sc_bpf)
-                       bpf_tap(le->sc_bpf, le->sc_r2->ler2_tbuf[bix], len);
+                       bpf_mtap(le->sc_bpf, m);
 #endif
 #endif
-               tmd->tmd3 = 0;
-               tmd->tmd2 = -len;
-               tmd->tmd1 = LE_OWN | LE_STP | LE_ENP;
+               len = leput(le, LER2_TBUFADDR(le->sc_r2, bix), m);
+               LER2_tmd3(tmd, 0);
+               LER2_tmd2(tmd, -len);
+               LER2_tmd1(tmd, LE_OWN | LE_STP | LE_ENP);
                LENEXTTMP;
        }
        if (len != 0) {
                le->sc_if.if_flags |= IFF_OACTIVE;
                LERDWR(ler0, LE_TDMD | LE_INEA, le->sc_r1->ler1_rdp);
                LENEXTTMP;
        }
        if (len != 0) {
                le->sc_if.if_flags |= IFF_OACTIVE;
                LERDWR(ler0, LE_TDMD | LE_INEA, le->sc_r1->ler1_rdp);
-               MachEmptyWriteBuffer();
        }
        le->sc_tmdnext = bix;
        return (0);
        }
        le->sc_tmdnext = bix;
        return (0);
@@ -393,7 +438,6 @@ leintr(unit)
                if (stat & LE_MISS)
                        le->sc_miss++;
                LERDWR(ler0, LE_BABL|LE_CERR|LE_MISS|LE_INEA, ler1->ler1_rdp);
                if (stat & LE_MISS)
                        le->sc_miss++;
                LERDWR(ler0, LE_BABL|LE_CERR|LE_MISS|LE_INEA, ler1->ler1_rdp);
-               MachEmptyWriteBuffer();
        }
        if ((stat & LE_RXON) == 0) {
                le->sc_rxoff++;
        }
        if ((stat & LE_RXON) == 0) {
                le->sc_rxoff++;
@@ -411,7 +455,6 @@ leintr(unit)
        }
        if (stat & LE_TINT) {
                LERDWR(ler0, LE_TINT|LE_INEA, ler1->ler1_rdp);
        }
        if (stat & LE_TINT) {
                LERDWR(ler0, LE_TINT|LE_INEA, ler1->ler1_rdp);
-               MachEmptyWriteBuffer();
                lexint(unit);
        }
 }
                lexint(unit);
        }
 }
@@ -425,31 +468,31 @@ lexint(unit)
 {
        register struct le_softc *le = &le_softc[unit];
        register int bix = le->sc_tmd;
 {
        register struct le_softc *le = &le_softc[unit];
        register int bix = le->sc_tmd;
-       register volatile struct letmd *tmd = &le->sc_r2->ler2_tmd[bix];
+       register volatile void *tmd;
 
        if ((le->sc_if.if_flags & IFF_OACTIVE) == 0) {
                le->sc_xint++;
                return;
        }
        LENEXTTMP;
 
        if ((le->sc_if.if_flags & IFF_OACTIVE) == 0) {
                le->sc_xint++;
                return;
        }
        LENEXTTMP;
-       while (bix != le->sc_tmdnext && (tmd->tmd1 & LE_OWN) == 0) {
+       while (bix != le->sc_tmdnext && (LER2V_tmd1(tmd) & LE_OWN) == 0) {
                le->sc_tmd = bix;
                le->sc_tmd = bix;
-               if ((tmd->tmd1 & LE_ERR) || (tmd->tmd3 & LE_TBUFF)) {
+               if ((LER2V_tmd1(tmd) & LE_ERR) || (LER2V_tmd3(tmd) & LE_TBUFF)) {
                        lexerror(unit);
                        le->sc_if.if_oerrors++;
                        lexerror(unit);
                        le->sc_if.if_oerrors++;
-                       if (tmd->tmd3 & (LE_TBUFF|LE_UFLO)) {
+                       if (LER2V_tmd3(tmd) & (LE_TBUFF|LE_UFLO)) {
                                le->sc_uflo++;
                                lereset(unit);
                                break;
                        }
                                le->sc_uflo++;
                                lereset(unit);
                                break;
                        }
-                       else if (tmd->tmd3 & LE_LCOL)
+                       else if (LER2V_tmd3(tmd) & LE_LCOL)
                                le->sc_if.if_collisions++;
                                le->sc_if.if_collisions++;
-                       else if (tmd->tmd3 & LE_RTRY)
+                       else if (LER2V_tmd3(tmd) & LE_RTRY)
                                le->sc_if.if_collisions += 16;
                }
                                le->sc_if.if_collisions += 16;
                }
-               else if (tmd->tmd1 & LE_ONE)
+               else if (LER2V_tmd1(tmd) & LE_ONE)
                        le->sc_if.if_collisions++;
                        le->sc_if.if_collisions++;
-               else if (tmd->tmd1 & LE_MORE)
+               else if (LER2V_tmd1(tmd) & LE_MORE)
                        /* what is the real number? */
                        le->sc_if.if_collisions += 2;
                else
                        /* what is the real number? */
                        le->sc_if.if_collisions += 2;
                else
@@ -462,7 +505,9 @@ lexint(unit)
 }
 
 #define        LENEXTRMP \
 }
 
 #define        LENEXTRMP \
-       if (++bix == LERBUF) bix = 0, rmd = le->sc_r2->ler2_rmd; else ++rmd
+       if (++bix == LERBUF) \
+               bix = 0; \
+       rmd = LER2_RMDADDR(le->sc_r2, bix)
 
 /*
  * Ethernet interface receiver interrupt.
 
 /*
  * Ethernet interface receiver interrupt.
@@ -475,32 +520,30 @@ lerint(unit)
 {
        register struct le_softc *le = &le_softc[unit];
        register int bix = le->sc_rmd;
 {
        register struct le_softc *le = &le_softc[unit];
        register int bix = le->sc_rmd;
-       register volatile struct lermd *rmd = &le->sc_r2->ler2_rmd[bix];
+       register volatile void *rmd = LER2_RMDADDR(le->sc_r2, bix);
 
        /*
         * Out of sync with hardware, should never happen?
         */
 
        /*
         * Out of sync with hardware, should never happen?
         */
-       if (rmd->rmd1 & LE_OWN) {
+       if (LER2V_rmd1(rmd) & LE_OWN) {
                LERDWR(le->sc_r0, LE_RINT|LE_INEA, le->sc_r1->ler1_rdp);
                LERDWR(le->sc_r0, LE_RINT|LE_INEA, le->sc_r1->ler1_rdp);
-               MachEmptyWriteBuffer();
                return;
        }
 
        /*
         * Process all buffers with valid data
         */
                return;
        }
 
        /*
         * Process all buffers with valid data
         */
-       while ((rmd->rmd1 & LE_OWN) == 0) {
-               int len = rmd->rmd3;
+       while ((LER2V_rmd1(rmd) & LE_OWN) == 0) {
+               int len = LER2V_rmd3(rmd);
 
                /* Clear interrupt to avoid race condition */
                LERDWR(le->sc_r0, LE_RINT|LE_INEA, le->sc_r1->ler1_rdp);
 
                /* Clear interrupt to avoid race condition */
                LERDWR(le->sc_r0, LE_RINT|LE_INEA, le->sc_r1->ler1_rdp);
-               MachEmptyWriteBuffer();
 
 
-               if (rmd->rmd1 & LE_ERR) {
+               if (LER2V_rmd1(rmd) & LE_ERR) {
                        le->sc_rmd = bix;
                        lererror(unit, "bad packet");
                        le->sc_if.if_ierrors++;
                        le->sc_rmd = bix;
                        lererror(unit, "bad packet");
                        le->sc_if.if_ierrors++;
-               } else if ((rmd->rmd1 & (LE_STP|LE_ENP)) != (LE_STP|LE_ENP)) {
+               } else if ((LER2V_rmd1(rmd) & (LE_STP|LE_ENP)) != (LE_STP|LE_ENP)) {
                        /*
                         * Find the end of the packet so we can see how long
                         * it was.  We still throw it away.
                        /*
                         * Find the end of the packet so we can see how long
                         * it was.  We still throw it away.
@@ -508,11 +551,10 @@ lerint(unit)
                        do {
                                LERDWR(le->sc_r0, LE_RINT|LE_INEA,
                                       le->sc_r1->ler1_rdp);
                        do {
                                LERDWR(le->sc_r0, LE_RINT|LE_INEA,
                                       le->sc_r1->ler1_rdp);
-                               MachEmptyWriteBuffer();
-                               rmd->rmd3 = 0;
-                               rmd->rmd1 = LE_OWN;
+                               LER2_rmd3(rmd, 0);
+                               LER2_rmd1(rmd, LE_OWN);
                                LENEXTRMP;
                                LENEXTRMP;
-                       } while (!(rmd->rmd1 & (LE_OWN|LE_ERR|LE_STP|LE_ENP)));
+                       } while (!(LER2V_rmd1(rmd) & (LE_OWN|LE_ERR|LE_STP|LE_ENP)));
                        le->sc_rmd = bix;
                        lererror(unit, "chained buffer");
                        le->sc_rxlen++;
                        le->sc_rmd = bix;
                        lererror(unit, "chained buffer");
                        le->sc_rxlen++;
@@ -520,15 +562,15 @@ lerint(unit)
                         * If search terminated without successful completion
                         * we reset the hardware (conservative).
                         */
                         * If search terminated without successful completion
                         * we reset the hardware (conservative).
                         */
-                       if ((rmd->rmd1 & (LE_OWN|LE_ERR|LE_STP|LE_ENP)) !=
+                       if ((LER2V_rmd1(rmd) & (LE_OWN|LE_ERR|LE_STP|LE_ENP)) !=
                            LE_ENP) {
                                lereset(unit);
                                return;
                        }
                } else
                            LE_ENP) {
                                lereset(unit);
                                return;
                        }
                } else
-                       leread(unit, le->sc_r2->ler2_rbuf[bix], len);
-               rmd->rmd3 = 0;
-               rmd->rmd1 = LE_OWN;
+                       leread(unit, LER2_RBUFADDR(le->sc_r2, bix), len);
+               LER2_rmd3(rmd, 0);
+               LER2_rmd1(rmd, LE_OWN);
                LENEXTRMP;
        }
        MachEmptyWriteBuffer();         /* Paranoia */
                LENEXTRMP;
        }
        MachEmptyWriteBuffer();         /* Paranoia */
@@ -543,26 +585,19 @@ lerint(unit)
  */
 leread(unit, buf, len)
        int unit;
  */
 leread(unit, buf, len)
        int unit;
-       le_buf_t *buf;
+       volatile void *buf;
        int len;
 {
        register struct le_softc *le = &le_softc[unit];
        struct ether_header et;
        int len;
 {
        register struct le_softc *le = &le_softc[unit];
        struct ether_header et;
-       struct mbuf *m;
+       struct mbuf *m, **hdrmp, **tailmp;
        int off, resid;
        int off, resid;
-#ifdef DS3100
-       u_short sbuf[2];
-#endif
+       u_short sbuf[2], eth_type;
        extern struct mbuf *leget();
 
        le->sc_if.if_ipackets++;
        extern struct mbuf *leget();
 
        le->sc_if.if_ipackets++;
-#ifdef DS3100
-       CopyFromBuffer(buf, (char *)&et, sizeof(et));
-#endif
-#ifdef DS5000
-       bcopy(buf, (char *)&et, sizeof(et));
-#endif
-       et.ether_type = ntohs(et.ether_type);
+       (*le->sc_copyfrombuf)(buf, 0, (char *)&et, sizeof (et));
+       eth_type = ntohs(et.ether_type);
        /* adjust input length to account for header and CRC */
        len = len - sizeof(struct ether_header) - 4;
 
        /* adjust input length to account for header and CRC */
        len = len - sizeof(struct ether_header) - 4;
 
@@ -579,28 +614,22 @@ leread(unit, buf, len)
         *  type field to ETHERTYPE_IEEE so we can switch() on it later.
         *  Yes, this is a hack and will eventually be done "right".
         */
         *  type field to ETHERTYPE_IEEE so we can switch() on it later.
         *  Yes, this is a hack and will eventually be done "right".
         */
-       if (et.ether_type <= IEEE802LEN_MAX && len >= sizeof(struct hp_llc) &&
-           len >= et.ether_type && len >= IEEE802LEN_MIN) {
-               len = et.ether_type;
-               et.ether_type = ETHERTYPE_IEEE; /* hack! */
+       if (eth_type <= IEEE802LEN_MAX && len >= sizeof(struct hp_llc) &&
+           len >= eth_type && len >= IEEE802LEN_MIN) {
+               len = eth_type;
+               eth_type = ETHERTYPE_IEEE;      /* hack! */
        }
 #endif
 
        }
 #endif
 
-       if (et.ether_type >= ETHERTYPE_TRAIL &&
-           et.ether_type < ETHERTYPE_TRAIL+ETHERTYPE_NTRAILER) {
-               off = (et.ether_type - ETHERTYPE_TRAIL) * 512;
+       if (eth_type >= ETHERTYPE_TRAIL &&
+           eth_type < ETHERTYPE_TRAIL+ETHERTYPE_NTRAILER) {
+               off = (eth_type - ETHERTYPE_TRAIL) * 512;
                if (off >= ETHERMTU)
                        return;         /* sanity */
                if (off >= ETHERMTU)
                        return;         /* sanity */
-#ifdef DS3100
-               CopyFromBuffer(buf + (sizeof(et) + off),
-                       (char *)sbuf, sizeof(sbuf));
-               et.ether_type = ntohs(sbuf[0]);
+               (*le->sc_copyfrombuf)(buf, sizeof (et) + off, (char *)sbuf,
+                       sizeof (sbuf));
+               eth_type = ntohs(sbuf[0]);
                resid = ntohs(sbuf[1]);
                resid = ntohs(sbuf[1]);
-#endif
-#ifdef DS5000
-               et.ether_type = ntohs(((u_short *)(buf + (sizeof(et) + off)))[0]);
-               resid = ntohs(((u_short *)(buf + (sizeof(et) + off)))[1]);
-#endif
                if (off + resid > len)
                        return;         /* sanity */
                len = off + resid;
                if (off + resid > len)
                        return;         /* sanity */
                len = off + resid;
@@ -616,45 +645,30 @@ leread(unit, buf, len)
                le->sc_if.if_ierrors++;
                return;
        }
                le->sc_if.if_ierrors++;
                return;
        }
-#if NBPFILTER > 0
-       /*
-        * Check if there's a bpf filter listening on this interface.
-        * If so, hand off the raw packet to bpf, which must deal with
-        * trailers in its own way.
-        */
-       if (le->sc_bpf) {
-               bpf_tap(le->sc_bpf, buf, len + sizeof(struct ether_header));
 
 
-               /*
-                * Note that the interface cannot be in promiscuous mode if
-                * there are no bpf listeners.  And if we are in promiscuous
-                * mode, we have to check if this packet is really ours.
-                *
-                * XXX This test does not support multicasts.
-                */
-               if ((le->sc_if.if_flags & IFF_PROMISC)
-                   && bcmp(et.ether_dhost, le->sc_addr, 
-                           sizeof(et.ether_dhost)) != 0
-                   && bcmp(et.ether_dhost, etherbroadcastaddr, 
-                           sizeof(et.ether_dhost)) != 0)
-                       return;
-       }
-#endif
        /*
         * Pull packet off interface.  Off is nonzero if packet
         * has trailing header; leget will then force this header
         * information to be at the front, but we still have to drop
         * the type and length which are at the front of any trailer data.
        /*
         * Pull packet off interface.  Off is nonzero if packet
         * has trailing header; leget will then force this header
         * information to be at the front, but we still have to drop
         * the type and length which are at the front of any trailer data.
+        * The hdrmp and tailmp pointers are used by lebpf_tap() to
+        * temporarily reorder the mbuf list. See the comment at the beginning
+        * of lebpf_tap() for all the ugly details.
         */
         */
-       m = leget(buf, len, off, &le->sc_if);
+       m = leget(le, buf, len, off, &le->sc_if, &hdrmp, &tailmp);
        if (m == 0)
                return;
        if (m == 0)
                return;
+#if NBPFILTER > 0
+       if (le->sc_bpf)
+               if (lebpf_tap(le, m, hdrmp, tailmp, off, &et, sbuf))
+                       return;
+#endif
 #ifdef RMP
        /*
         * (XXX)
         * This needs to be integrated with the ISO stuff in ether_input()
         */
 #ifdef RMP
        /*
         * (XXX)
         * This needs to be integrated with the ISO stuff in ether_input()
         */
-       if (et.ether_type == ETHERTYPE_IEEE) {
+       if (eth_type == ETHERTYPE_IEEE) {
                /*
                 *  Snag the Logical Link Control header (IEEE 802.2).
                 */
                /*
                 *  Snag the Logical Link Control header (IEEE 802.2).
                 */
@@ -679,83 +693,34 @@ leread(unit, buf, len)
                }
        }
 #endif
                }
        }
 #endif
+       et.ether_type = eth_type;
        ether_input(&le->sc_if, &et, m);
 }
 
 /*
  * Routine to copy from mbuf chain to transmit buffer in
  * network buffer memory.
        ether_input(&le->sc_if, &et, m);
 }
 
 /*
  * Routine to copy from mbuf chain to transmit buffer in
  * network buffer memory.
- * NOTE: On the DS3100, network memory can only be written one short at
- *     every other address.
  */
  */
-leput(lebuf, m)
-       register le_buf_t *lebuf;
+leput(le, lebuf, m)
+       struct le_softc *le;
+       register volatile void *lebuf;
        register struct mbuf *m;
 {
        register struct mbuf *mp;
        register int len, tlen = 0;
        register struct mbuf *m;
 {
        register struct mbuf *mp;
        register int len, tlen = 0;
-#ifdef DS3100
-       register char *cp;
-       int tmp, xfer;
-#endif
+       register int boff = 0;
 
        for (mp = m; mp; mp = mp->m_next) {
                len = mp->m_len;
                if (len == 0)
                        continue;
 
        for (mp = m; mp; mp = mp->m_next) {
                len = mp->m_len;
                if (len == 0)
                        continue;
-#ifdef DS3100
-               /* copy data for this mbuf */
-               cp = mtod(mp, char *);
-               if (tlen & 1) {
-                       /* handle odd length from previous mbuf */
-                       *lebuf = (cp[0] << 8) | tmp;
-                       lebuf += 2;
-                       cp++;
-                       len--;
-                       tlen++;
-               }
+               (*le->sc_copytobuf)(mtod(mp, char *), lebuf, boff, len);
                tlen += len;
                tlen += len;
-               if ((unsigned)cp & 1) {
-                       while (len > 1) {
-                               *lebuf = (cp[1] << 8) | cp[0];
-                               lebuf += 2;
-                               cp += 2;
-                               len -= 2;
-                       }
-               } else {
-                       /* optimize for aligned transfers */
-                       xfer = (int)((unsigned)len & ~0x1);
-                       CopyToBuffer((u_short *)cp, lebuf, xfer);
-                       lebuf += xfer;
-                       cp += xfer;
-                       len -= xfer;
-               }
-               if (len == 1)
-                       tmp = *cp;
-#endif
-#ifdef DS5000
-               tlen += len;
-               bcopy(mtod(mp, char *), lebuf, len);
-               lebuf += len;
-#endif
+               boff += len;
        }
        m_freem(m);
        }
        m_freem(m);
-#ifdef DS3100
-       /* handle odd length from previous mbuf */
-       if (tlen & 1)
-               *lebuf = tmp;
-#endif
        if (tlen < LEMINSIZE) {
        if (tlen < LEMINSIZE) {
-#ifdef DS3100
-               tlen = (tlen + 1) & ~1;
-               while (tlen < LEMINSIZE) {
-                       *lebuf++ = 0;
-                       tlen += 2;
-               }
-#endif
-#ifdef DS5000
-               bzero(lebuf, LEMINSIZE - tlen);
-#endif
+               (*le->sc_zerobuf)(lebuf, boff, LEMINSIZE - tlen);
                tlen = LEMINSIZE;
        }
        return(tlen);
                tlen = LEMINSIZE;
        }
        return(tlen);
@@ -763,26 +728,24 @@ leput(lebuf, m)
 
 /*
  * Routine to copy from network buffer memory into mbufs.
 
 /*
  * Routine to copy from network buffer memory into mbufs.
- * NOTE: On the DS3100, network memory can only be written one short at
- *     every other address.
  */
 struct mbuf *
  */
 struct mbuf *
-leget(lebuf, totlen, off, ifp)
-       le_buf_t *lebuf;
+leget(le, lebuf, totlen, off, ifp, hdrmp, tailmp)
+       struct le_softc *le;
+       volatile void *lebuf;
        int totlen, off;
        struct ifnet *ifp;
        int totlen, off;
        struct ifnet *ifp;
+       struct mbuf ***hdrmp, ***tailmp;
 {
        register struct mbuf *m;
        struct mbuf *top = 0, **mp = &top;
 {
        register struct mbuf *m;
        struct mbuf *top = 0, **mp = &top;
-       register int len, resid;
-       register le_buf_t *sp;
+       register int len, resid, boff;
 
        /* NOTE: sizeof(struct ether_header) should be even */
 
        /* NOTE: sizeof(struct ether_header) should be even */
-       lebuf += sizeof(struct ether_header);
-       sp = lebuf;
+       boff = sizeof(struct ether_header);
        if (off) {
                /* NOTE: off should be even */
        if (off) {
                /* NOTE: off should be even */
-               sp += off + 2 * sizeof(u_short);
+               boff += off + 2 * sizeof(u_short);
                totlen -= 2 * sizeof(u_short);
                resid = totlen - off;
        } else
                totlen -= 2 * sizeof(u_short);
                resid = totlen - off;
        } else
@@ -818,31 +781,19 @@ leget(lebuf, totlen, off, ifp)
                        m->m_len = resid;
                }
                len = m->m_len;
                        m->m_len = resid;
                }
                len = m->m_len;
-#ifdef DS3100
-               if ((unsigned)sp & 2) {
-                       /*
-                        * Previous len was odd. Copy the single byte specially.
-                        * XXX Can this ever happen??
-                        */
-                       panic("le odd rcv");
-                       *mtod(m, char *) = ((volatile char *)sp)[-1];
-                       CopyFromBuffer(sp + 1, mtod(m, char *) + 1, len - 1);
-               } else
-                       CopyFromBuffer(sp, mtod(m, char *), len);
-#endif
-#ifdef DS5000
-               bcopy(sp, mtod(m, char *), len);
-#endif
-               sp += len;
+               (*le->sc_copyfrombuf)(lebuf, boff, mtod(m, char *), len);
+               boff += len;
                *mp = m;
                mp = &m->m_next;
                totlen -= len;
                resid -= len;
                if (resid == 0) {
                *mp = m;
                mp = &m->m_next;
                totlen -= len;
                resid -= len;
                if (resid == 0) {
-                       sp = lebuf;
+                       boff = sizeof (struct ether_header);
                        resid = totlen;
                        resid = totlen;
+                       *hdrmp = mp;
                }
        }
                }
        }
+       *tailmp = mp;
        return (top);
 }
 
        return (top);
 }
 
@@ -903,8 +854,7 @@ leioctl(ifp, cmd, data)
        case SIOCSIFFLAGS:
                if ((ifp->if_flags & IFF_UP) == 0 &&
                    ifp->if_flags & IFF_RUNNING) {
        case SIOCSIFFLAGS:
                if ((ifp->if_flags & IFF_UP) == 0 &&
                    ifp->if_flags & IFF_RUNNING) {
-                       LERDWR(le->sc_r0, LE_STOP, ler1->ler1_rdp);
-                       MachEmptyWriteBuffer();
+                       LEWREG(LE_STOP, ler1->ler1_rdp);
                        ifp->if_flags &= ~IFF_RUNNING;
                } else if (ifp->if_flags & IFF_UP &&
                    (ifp->if_flags & IFF_RUNNING) == 0)
                        ifp->if_flags &= ~IFF_RUNNING;
                } else if (ifp->if_flags & IFF_UP &&
                    (ifp->if_flags & IFF_RUNNING) == 0)
@@ -952,32 +902,24 @@ lererror(unit, msg)
        char *msg;
 {
        register struct le_softc *le = &le_softc[unit];
        char *msg;
 {
        register struct le_softc *le = &le_softc[unit];
-       register volatile struct lermd *rmd;
+       register volatile void *rmd;
        u_char eaddr[6];
        u_char eaddr[6];
-       char *cp;
        int len;
 
        if (!ledebug)
                return;
 
        int len;
 
        if (!ledebug)
                return;
 
-       rmd = &le->sc_r2->ler2_rmd[le->sc_rmd];
-       len = rmd->rmd3;
-       if (len > 11) {
-#ifdef DS3100
-               CopyFromBuffer((char *)&le->sc_r2->ler2_rbuf[le->sc_rmd][6],
-                       eaddr, sizeof(eaddr));
-#endif
-#ifdef DS5000
-               bcopy((char *)&le->sc_r2->ler2_rbuf[le->sc_rmd][6],
-                       eaddr, sizeof(eaddr));
-#endif
-               cp = ether_sprintf(eaddr);
-       } else
-               cp = "unknown";
+       rmd = LER2_RMDADDR(le->sc_r2, le->sc_rmd);
+       len = LER2V_rmd3(rmd);
+       if (len > 11)
+               (*le->sc_copyfrombuf)(LER2_RBUFADDR(le->sc_r2, le->sc_rmd),
+                       6, eaddr, 6);
        log(LOG_WARNING,
            "le%d: ierror(%s): from %s: buf=%d, len=%d, rmd1=%b\n",
        log(LOG_WARNING,
            "le%d: ierror(%s): from %s: buf=%d, len=%d, rmd1=%b\n",
-           unit, msg, cp, le->sc_rmd, len,
-           rmd->rmd1,
+           unit, msg,
+           len > 11 ? ether_sprintf(eaddr) : "unknown",
+           le->sc_rmd, len,
+           LER2V_rmd1(rmd),
            "\20\20OWN\17ERR\16FRAM\15OFLO\14CRC\13RBUF\12STP\11ENP");
 }
 
            "\20\20OWN\17ERR\16FRAM\15OFLO\14CRC\13RBUF\12STP\11ENP");
 }
 
@@ -985,34 +927,351 @@ lexerror(unit)
        int unit;
 {
        register struct le_softc *le = &le_softc[unit];
        int unit;
 {
        register struct le_softc *le = &le_softc[unit];
-       register volatile struct letmd *tmd;
+       register volatile void *tmd;
        u_char eaddr[6];
        u_char eaddr[6];
-       char *cp;
        int len;
 
        if (!ledebug)
                return;
 
        int len;
 
        if (!ledebug)
                return;
 
-       tmd = le->sc_r2->ler2_tmd;
-       len = -tmd->tmd2;
-       if (len > 5) {
-#ifdef DS3100
-               CopyFromBuffer((char *)&le->sc_r2->ler2_tbuf[le->sc_tmd][0],
-                       eaddr, sizeof(eaddr));
-#endif
-#ifdef DS5000
-               bcopy((char *)&le->sc_r2->ler2_tbuf[le->sc_tmd][0],
-                       eaddr, sizeof(eaddr));
-#endif
-               cp = ether_sprintf(eaddr);
-       } else
-               cp = "unknown";
+       tmd = LER2_TMDADDR(le->sc_r2, 0);
+       len = -LER2V_tmd2(tmd);
+       if (len > 5)
+               (*le->sc_copyfrombuf)(LER2_TBUFADDR(le->sc_r2, 0), 0, eaddr, 6);
        log(LOG_WARNING,
            "le%d: oerror: to %s: buf=%d, len=%d, tmd1=%b, tmd3=%b\n",
        log(LOG_WARNING,
            "le%d: oerror: to %s: buf=%d, len=%d, tmd1=%b, tmd3=%b\n",
-           unit, cp, le->sc_tmd, len,
-           tmd->tmd1,
+           unit,
+           len > 5 ? ether_sprintf(eaddr) : "unknown",
+           0, len,
+           LER2V_tmd1(tmd),
            "\20\20OWN\17ERR\16RES\15MORE\14ONE\13DEF\12STP\11ENP",
            "\20\20OWN\17ERR\16RES\15MORE\14ONE\13DEF\12STP\11ENP",
-           tmd->tmd3,
+           LER2V_tmd3(tmd),
            "\20\20BUFF\17UFLO\16RES\15LCOL\14LCAR\13RTRY");
 }
            "\20\20BUFF\17UFLO\16RES\15LCOL\14LCAR\13RTRY");
 }
-#endif
+
+/*
+ * Write a lance register port, reading it back to ensure success. This seems
+ * to be necessary during initialization, since the chip appears to be a bit
+ * pokey sometimes.
+ */
+static void
+lewritereg(regptr, val)
+       register volatile u_short *regptr;
+       register u_short val;
+{
+       register int i = 0;
+
+       while (*regptr != val) {
+               *regptr = val;
+               MachEmptyWriteBuffer();
+               if (++i > 10000) {
+                       printf("le: Reg did not settle (to x%x): x%x\n",
+                              val, *regptr);
+                       return;
+               }
+               DELAY(100);
+       }
+}
+
+/*
+ * Routines for accessing the transmit and receive buffers. Unfortunately,
+ * CPU addressing of these buffers is done in one of 3 ways:
+ * - contiguous (for the 3max and turbochannel option card)
+ * - gap2, which means shorts (2 bytes) interspersed with short (2 byte)
+ *   spaces (for the pmax)
+ * - gap16, which means 16bytes interspersed with 16byte spaces
+ *   for buffers which must begin on a 32byte boundary (for 3min and maxine)
+ * The buffer offset is the logical byte offset, assuming contiguous storage.
+ */
+void
+copytobuf_contig(from, lebuf, boff, len)
+       char *from;
+       volatile void *lebuf;
+       int boff;
+       int len;
+{
+
+       /*
+        * Just call bcopy() to do the work.
+        */
+       bcopy(from, ((char *)lebuf) + boff, len);
+}
+
+void
+copyfrombuf_contig(lebuf, boff, to, len)
+       volatile void *lebuf;
+       int boff;
+       char *to;
+       int len;
+{
+
+       /*
+        * Just call bcopy() to do the work.
+        */
+       bcopy(((char *)lebuf) + boff, to, len);
+}
+
+void
+bzerobuf_contig(lebuf, boff, len)
+       volatile void *lebuf;
+       int boff;
+       int len;
+{
+
+       /*
+        * Just let bzero() do the work
+        */
+       bzero(((char *)lebuf) + boff, len);
+}
+
+/*
+ * For the pmax the buffer consists of shorts (2 bytes) interspersed with
+ * short (2 byte) spaces and must be accessed with halfword load/stores.
+ * (don't worry about doing an extra byte)
+ */
+void
+copytobuf_gap2(from, lebuf, boff, len)
+       register char *from;
+       volatile void *lebuf;
+       int boff;
+       register int len;
+{
+       register volatile u_short *bptr;
+       register int xfer;
+
+       if (boff & 0x1) {
+               /* handle unaligned first byte */
+               bptr = ((volatile u_short *)lebuf) + (boff - 1);
+               *bptr = (*from++ << 8) | (*bptr & 0xff);
+               bptr += 2;
+               len--;
+       } else
+               bptr = ((volatile u_short *)lebuf) + boff;
+       if ((unsigned)from & 0x1) {
+               while (len > 1) {
+                       *bptr = (from[1] << 8) | from[0];
+                       bptr += 2;
+                       from += 2;
+                       len -= 2;
+               }
+       } else {
+               /* optimize for aligned transfers */
+               xfer = (int)((unsigned)len & ~0x1);
+               CopyToBuffer((u_short *)from, bptr, xfer);
+               bptr += xfer;
+               from += xfer;
+               len -= xfer;
+       }
+       if (len == 1)
+               *bptr = (u_short)*from;
+}
+
+void
+copyfrombuf_gap2(lebuf, boff, to, len)
+       volatile void *lebuf;
+       int boff;
+       register char *to;
+       register int len;
+{
+       register volatile u_short *bptr;
+       register u_short tmp;
+       register int xfer;
+
+       if (boff & 0x1) {
+               /* handle unaligned first byte */
+               bptr = ((volatile u_short *)lebuf) + (boff - 1);
+               *to++ = (*bptr >> 8) & 0xff;
+               bptr += 2;
+               len--;
+       } else
+               bptr = ((volatile u_short *)lebuf) + boff;
+       if ((unsigned)to & 0x1) {
+               while (len > 1) {
+                       tmp = *bptr;
+                       *to++ = tmp & 0xff;
+                       *to++ = (tmp >> 8) & 0xff;
+                       bptr += 2;
+                       len -= 2;
+               }
+       } else {
+               /* optimize for aligned transfers */
+               xfer = (int)((unsigned)len & ~0x1);
+               CopyFromBuffer(bptr, to, xfer);
+               bptr += xfer;
+               to += xfer;
+               len -= xfer;
+       }
+       if (len == 1)
+               *to = *bptr & 0xff;
+}
+
+void
+bzerobuf_gap2(lebuf, boff, len)
+       volatile void *lebuf;
+       int boff;
+       int len;
+{
+       register volatile u_short *bptr;
+
+       if ((unsigned)boff & 0x1) {
+               bptr = ((volatile u_short *)lebuf) + (boff - 1);
+               *bptr &= 0xff;
+               bptr += 2;
+               len--;
+       } else
+               bptr = ((volatile u_short *)lebuf) + boff;
+       while (len > 0) {
+               *bptr = 0;
+               bptr += 2;
+               len -= 2;
+       }
+}
+
+/*
+ * For the 3min and maxine, the buffers are in main memory filled in with
+ * 16byte blocks interspersed with 16byte spaces.
+ */
+void
+copytobuf_gap16(from, lebuf, boff, len)
+       register char *from;
+       volatile void *lebuf;
+       int boff;
+       register int len;
+{
+       register char *bptr;
+       register int xfer;
+
+       bptr = ((char *)lebuf) + ((boff << 1) & ~0x1f);
+       boff &= 0xf;
+       xfer = min(len, 16 - boff);
+       while (len > 0) {
+               bcopy(from, ((char *)bptr) + boff, xfer);
+               from += xfer;
+               bptr += 32;
+               boff = 0;
+               len -= xfer;
+               xfer = min(len, 16);
+       }
+}
+
+void
+copyfrombuf_gap16(lebuf, boff, to, len)
+       volatile void *lebuf;
+       int boff;
+       register char *to;
+       register int len;
+{
+       register char *bptr;
+       register int xfer;
+
+       bptr = ((char *)lebuf) + ((boff << 1) & ~0x1f);
+       boff &= 0xf;
+       xfer = min(len, 16 - boff);
+       while (len > 0) {
+               bcopy(((char *)bptr) + boff, to, xfer);
+               to += xfer;
+               bptr += 32;
+               boff = 0;
+               len -= xfer;
+               xfer = min(len, 16);
+       }
+}
+
+void
+bzerobuf_gap16(lebuf, boff, len)
+       volatile void *lebuf;
+       int boff;
+       register int len;
+{
+       register char *bptr;
+       register int xfer;
+
+       bptr = ((char *)lebuf) + ((boff << 1) & ~0x1f);
+       boff &= 0xf;
+       xfer = min(len, 16 - boff);
+       while (len > 0) {
+               bzero(((char *)bptr) + boff, xfer);
+               bptr += 32;
+               boff = 0;
+               len -= xfer;
+               xfer = min(len, 16);
+       }
+}
+
+#if NBPFILTER > 0
+/*
+ * This is exceptionally ugly, but since the lance buffers are not always
+ * contiguous in cpu address space, this was the best I could think of.
+ * Essentially build an mbuf list with the entire raw packet in it and
+ * then dismantle it again if it is a local packet. I can't believe I am
+ * rebuilding the trailer encapsulation, but...
+ * Return true if the packet has been thrown away.
+ */
+static int
+lebpf_tap(le, m, hdrmp, tailmp, off, ep, sbuf)
+       struct le_softc *le;
+       struct mbuf *m;
+       struct mbuf **hdrmp;
+       struct mbuf **tailmp;
+       int off;
+       struct ether_header *ep;
+       u_short *sbuf;
+{
+       register struct mbuf *em, *sm;
+       u_short *sp;
+
+       MGET(em, M_DONTWAIT, MT_DATA);
+       if (off && em) {
+               MGET(sm, M_DONTWAIT, MT_DATA);
+               if (sm == (struct mbuf *)0) {
+                       m_freem(em);
+                       em = (struct mbuf *)0;
+               }
+       }
+       if (em) {
+               bcopy((caddr_t)ep, mtod(em, caddr_t), sizeof (*ep));
+               em->m_len = sizeof (*ep);
+               if (off) {
+                       sp = mtod(sm, u_short *);
+                       *sp++ = *sbuf++;
+                       *sp = *sbuf;
+                       sm->m_len = 2 * sizeof (u_short);
+                       em->m_next = *hdrmp;
+                       *hdrmp = (struct mbuf *)0;
+                       *tailmp = sm;
+                       sm->m_next = m;
+               } else
+                       em->m_next = m;
+               bpf_tap(le->sc_bpf, em);
+       }
+       /*
+        * Note that the interface cannot be in promiscuous mode if
+        * there are no bpf listeners.  And if we are in promiscuous
+        * mode, we have to check if this packet is really ours.
+        *
+        * XXX This test does not support multicasts.
+        */
+       if ((le->sc_if.if_flags & IFF_PROMISC)
+           && bcmp(ep->ether_dhost, le->sc_addr, 
+                   sizeof(ep->ether_dhost)) != 0
+           && bcmp(ep->ether_dhost, etherbroadcastaddr, 
+                   sizeof(ep->ether_dhost)) != 0) {
+               if (em)
+                       m_freem(em);
+               else
+                       m_freem(m);
+               return (1);
+       }
+       if (em == (struct mbuf *)0)
+               return (0);
+       if (off) {
+               MFREE(em, *hdrmp);
+               *tailmp = (struct mbuf *)0;
+               MFREE(sm, em);
+       } else {
+               MFREE(em, sm);
+       }
+       return (0);
+}
+#endif /* NBPFILTER */
+#endif /* NLE */
index 3f85757..7b2cab4 100644 (file)
@@ -1,16 +1,17 @@
-/*
- * Copyright (c) 1992 Regents of the University of California.
+/*-
+ * Copyright (c) 1992 The Regents of the University of California.
  * All rights reserved.
  *
  * This code is derived from software contributed to Berkeley by
  * All rights reserved.
  *
  * This code is derived from software contributed to Berkeley by
- * Ralph Campbell.
+ * Ralph Campbell and Rick Macklem.
  *
  * %sccs.include.redist.c%
  *
  *
  * %sccs.include.redist.c%
  *
- *     @(#)if_lereg.h  7.2 (Berkeley) %G%
+ *     @(#)if_lereg.h  7.3 (Berkeley) %G%
  */
 
 #define        LEMTU           1518
  */
 
 #define        LEMTU           1518
+#define        LEBLEN          1520    /* LEMTU up to a multiple of 16 */
 #define        LEMINSIZE       60      /* should be 64 if mode DTCR is set */
 #define        LERBUF          32
 #define        LERBUFLOG2      5
 #define        LEMINSIZE       60      /* should be 64 if mode DTCR is set */
 #define        LERBUF          32
 #define        LERBUFLOG2      5
@@ -29,76 +30,272 @@ struct lereg1 {
        short   pad1;
 };
 
        short   pad1;
 };
 
-#ifdef DS3100
-#define LEPAD(x)       short x;
-#define LE_RAM_SIZE    0x10000
-
-typedef u_short        le_buf_t;
-#endif
-#ifdef DS5000
-#define LEPAD(x)
-#define LE_RAM_SIZE    0x20000
-
-typedef u_char le_buf_t;
-#endif
-
 /*
  * This structure is overlayed on the network dual-port RAM.
 /*
  * This structure is overlayed on the network dual-port RAM.
- * Currently 32 * 1518 receive plus 8 * 1518 transmit buffers plus
+ * Currently 32 * 1520 receive plus 8 * 1520 transmit buffers plus
  * buffer descriptor rings.
  * buffer descriptor rings.
+ * There are two variants of the structure, one for the Pmax/3min/maxine
+ * with 2 byte pads between entries and one for the 3max and turbochannel
+ * option densely packed.
  */
  */
+struct lermd {                 /* +0x0020 */
+       u_short rmd0;
+       u_short rmd1;
+       short   rmd2;
+       u_short rmd3;
+};
+
+struct letmd {                 /* +0x0058 */
+       u_short tmd0;
+       u_short tmd1;
+       short   tmd2;
+       u_short tmd3;
+};
+
+struct lermdpad {                      /* +0x0020 */
+       u_short rmd0;
+       short   pad0;
+       u_short rmd1;
+       short   pad1;
+       short   rmd2;
+       short   pad2;
+       u_short rmd3;
+       short   pad3;
+};
+
+struct letmdpad {                      /* +0x0058 */
+       u_short tmd0;
+       short   pad0;
+       u_short tmd1;
+       short   pad1;
+       short   tmd2;
+       short   pad2;
+       u_short tmd3;
+       short   pad3;
+};
+
 struct lereg2 {
        /* init block */                /* CHIP address */
        u_short ler2_mode;              /* +0x0000 */
 struct lereg2 {
        /* init block */                /* CHIP address */
        u_short ler2_mode;              /* +0x0000 */
-       LEPAD(pad0)
        u_short ler2_padr0;             /* +0x0002 */
        u_short ler2_padr0;             /* +0x0002 */
-       LEPAD(pad1)
        u_short ler2_padr1;             /* +0x0004 */
        u_short ler2_padr1;             /* +0x0004 */
-       LEPAD(pad2)
        u_short ler2_padr2;             /* +0x0006 */
        u_short ler2_padr2;             /* +0x0006 */
-       LEPAD(pad3)
        u_short ler2_ladrf0;            /* +0x0008 */
        u_short ler2_ladrf0;            /* +0x0008 */
-       LEPAD(pad4)
        u_short ler2_ladrf1;            /* +0x000A */
        u_short ler2_ladrf1;            /* +0x000A */
-       LEPAD(pad5)
        u_short ler2_ladrf2;            /* +0x000C */
        u_short ler2_ladrf2;            /* +0x000C */
-       LEPAD(pad6)
        u_short ler2_ladrf3;            /* +0x000E */
        u_short ler2_ladrf3;            /* +0x000E */
-       LEPAD(pad7)
        u_short ler2_rdra;              /* +0x0010 */
        u_short ler2_rdra;              /* +0x0010 */
-       LEPAD(pad8)
        u_short ler2_rlen;              /* +0x0012 */
        u_short ler2_rlen;              /* +0x0012 */
-       LEPAD(pad9)
        u_short ler2_tdra;              /* +0x0014 */
        u_short ler2_tdra;              /* +0x0014 */
-       LEPAD(pad10)
        u_short ler2_tlen;              /* +0x0016 */
        u_short ler2_tlen;              /* +0x0016 */
-       LEPAD(pad11)
+       short   pad0[4];                /* Pad to 16 shorts */
        /* receive message descriptors */
        /* receive message descriptors */
-       struct  lermd {                 /* +0x0018 */
-               u_short rmd0;
-               LEPAD(pad0)
-               u_short rmd1;
-               LEPAD(pad1)
-               short   rmd2;
-               LEPAD(pad2)
-               u_short rmd3;
-               LEPAD(pad3)
-       } ler2_rmd[LERBUF];
+       struct lermd ler2_rmd[LERBUF];
        /* transmit message descriptors */
        /* transmit message descriptors */
-       struct  letmd {                 /* +0x0058 */
-               u_short tmd0;
-               LEPAD(pad0)
-               u_short tmd1;
-               LEPAD(pad1)
-               short   tmd2;
-               LEPAD(pad2)
-               u_short tmd3;
-               LEPAD(pad3)
-       } ler2_tmd[LETBUF];
-       le_buf_t        ler2_rbuf[LERBUF][LEMTU]; /* +0x0060 */
-       le_buf_t        ler2_tbuf[LETBUF][LEMTU]; /* +0x2FD0 */
+       struct letmd ler2_tmd[LETBUF];
+       char    ler2_rbuf[LERBUF][LEBLEN]; /* +0x0060 */
+       char    ler2_tbuf[LETBUF][LEBLEN]; /* +0x2FD0 */
 };
 
 };
 
+struct lereg2pad {
+       /* init block */                /* CHIP address */
+       u_short ler2_mode;              /* +0x0000 */
+       short   pad0;
+       u_short ler2_padr0;             /* +0x0002 */
+       short   pad1;
+       u_short ler2_padr1;             /* +0x0004 */
+       short   pad2;
+       u_short ler2_padr2;             /* +0x0006 */
+       short   pad3;
+       u_short ler2_ladrf0;            /* +0x0008 */
+       short   pad4;
+       u_short ler2_ladrf1;            /* +0x000A */
+       short   pad5;
+       u_short ler2_ladrf2;            /* +0x000C */
+       short   pad6;
+       u_short ler2_ladrf3;            /* +0x000E */
+       short   pad7;
+       u_short ler2_rdra;              /* +0x0010 */
+       short   pad8;
+       u_short ler2_rlen;              /* +0x0012 */
+       short   pad9;
+       u_short ler2_tdra;              /* +0x0014 */
+       short   pad10;
+       u_short ler2_tlen;              /* +0x0016 */
+       short   pad11[9];               /* Pad to 32 shorts */
+       /* receive message descriptors */
+       struct lermdpad ler2_rmd[LERBUF];
+       /* transmit message descriptors */
+       struct letmdpad ler2_tmd[LETBUF];
+       short   ler2_rbuf[LERBUF][LEBLEN]; /* +0x0060 */
+       short   ler2_tbuf[LETBUF][LEBLEN]; /* +0x2FD0 */
+};
+
+/*
+ * Now for some truly ugly macros to access the structure fields
+ * padded/non-padded at runtime. (For once, a Pascal like record variant
+ * would be nice to have.)
+ */
+#define        LER2_RMDADDR(p, i) \
+               (le->sc_ler2pad ? \
+                (volatile void *)&(((struct lereg2pad *)(p))->ler2_rmd[(i)]) : \
+                (volatile void *)&(((struct lereg2 *)(p))->ler2_rmd[(i)]))
+
+#define        LER2_TMDADDR(p, i) \
+               ((le->sc_ler2pad ? \
+                (volatile void *)&(((struct lereg2pad *)(p))->ler2_tmd[(i)]) : \
+                (volatile void *)&(((struct lereg2 *)(p))->ler2_tmd[(i)])))
+
+#define        LER2_RBUFADDR(p, i) \
+               ((le->sc_ler2pad ? \
+                (volatile void *)(((struct lereg2pad *)(p))->ler2_rbuf[(i)]) : \
+                (volatile void *)(((struct lereg2 *)(p))->ler2_rbuf[(i)])))
+
+#define        LER2_TBUFADDR(p, i) \
+               ((le->sc_ler2pad ? \
+                (volatile void *)(((struct lereg2pad *)(p))->ler2_tbuf[(i)]) : \
+                (volatile void *)(((struct lereg2 *)(p))->ler2_tbuf[(i)])))
+
+#define LER2_mode(p, v) \
+       (le->sc_ler2pad ? (((volatile struct lereg2pad *)(p))->ler2_mode = (v)) : \
+        (((volatile struct lereg2 *)(p))->ler2_mode = (v)))
+#define        LER2V_mode(p) \
+       (le->sc_ler2pad ? ((volatile struct lereg2pad *)(p))->ler2_mode : \
+        ((volatile struct lereg2 *)(p))->ler2_mode)
+
+#define LER2_padr0(p, v) \
+       (le->sc_ler2pad ? (((volatile struct lereg2pad *)(p))->ler2_padr0 = (v)) : \
+        (((volatile struct lereg2 *)(p))->ler2_padr0 = (v)))
+#define        LER2V_padr0(p) \
+       (le->sc_ler2pad ? ((volatile struct lereg2pad *)(p))->ler2_padr0 : \
+        ((volatile struct lereg2 *)(p))->ler2_padr0)
+
+#define LER2_padr1(p, v) \
+       (le->sc_ler2pad ? (((volatile struct lereg2pad *)(p))->ler2_padr1 = (v)) : \
+        (((volatile struct lereg2 *)(p))->ler2_padr1 = (v)))
+#define        LER2V_padr1(p) \
+       (le->sc_ler2pad ? ((volatile struct lereg2pad *)(p))->ler2_padr1 : \
+        ((volatile struct lereg2 *)(p))->ler2_padr1)
+
+#define LER2_padr2(p, v) \
+       (le->sc_ler2pad ? (((volatile struct lereg2pad *)(p))->ler2_padr2 = (v)) : \
+        (((volatile struct lereg2 *)(p))->ler2_padr2 = (v)))
+#define        LER2V_padr2(p) \
+       (le->sc_ler2pad ? ((volatile struct lereg2pad *)(p))->ler2_padr2 : \
+        ((volatile struct lereg2 *)(p))->ler2_padr2)
+
+#define LER2_ladrf0(p, v) \
+       (le->sc_ler2pad ? (((volatile struct lereg2pad *)(p))->ler2_ladrf0 = (v)) : \
+        (((volatile struct lereg2 *)(p))->ler2_ladrf0 = (v)))
+#define        LER2V_ladrf0(p) \
+       (le->sc_ler2pad ? ((volatile struct lereg2pad *)(p))->ler2_ladrf0 : \
+        ((volatile struct lereg2 *)(p))->ler2_ladrf0)
+
+#define LER2_ladrf1(p, v) \
+       (le->sc_ler2pad ? (((volatile struct lereg2pad *)(p))->ler2_ladrf1 = (v)) : \
+        (((volatile struct lereg2 *)(p))->ler2_ladrf1 = (v)))
+#define        LER2V_ladrf1(p) \
+       (le->sc_ler2pad ? ((volatile struct lereg2pad *)(p))->ler2_ladrf1 : \
+        ((volatile struct lereg2 *)(p))->ler2_ladrf1)
+
+#define LER2_ladrf2(p, v) \
+       (le->sc_ler2pad ? (((volatile struct lereg2pad *)(p))->ler2_ladrf2 = (v)) : \
+        (((volatile struct lereg2 *)(p))->ler2_ladrf2 = (v)))
+#define        LER2V_ladrf2(p) \
+       (le->sc_ler2pad ? ((volatile struct lereg2pad *)(p))->ler2_ladrf2 : \
+        ((volatile struct lereg2 *)(p))->ler2_ladrf2)
+
+#define LER2_ladrf3(p, v) \
+       (le->sc_ler2pad ? (((volatile struct lereg2pad *)(p))->ler2_ladrf3 = (v)) : \
+        (((volatile struct lereg2 *)(p))->ler2_ladrf3 = (v)))
+#define        LER2V_ladrf3(p) \
+       (le->sc_ler2pad ? ((volatile struct lereg2pad *)(p))->ler2_ladrf3 : \
+        ((volatile struct lereg2 *)(p))->ler2_ladrf3)
+
+#define LER2_rdra(p, v) \
+       (le->sc_ler2pad ? (((volatile struct lereg2pad *)(p))->ler2_rdra = (v)) : \
+        (((volatile struct lereg2 *)(p))->ler2_rdra = (v)))
+#define        LER2V_rdra(p) \
+       (le->sc_ler2pad ? ((volatile struct lereg2pad *)(p))->ler2_rdra : \
+        ((volatile struct lereg2 *)(p))->ler2_rdra)
+
+#define LER2_rlen(p, v) \
+       (le->sc_ler2pad ? (((volatile struct lereg2pad *)(p))->ler2_rlen = (v)) : \
+        (((volatile struct lereg2 *)(p))->ler2_rlen = (v)))
+#define        LER2V_rlen(p) \
+       (le->sc_ler2pad ? ((volatile struct lereg2pad *)(p))->ler2_rlen : \
+        ((volatile struct lereg2 *)(p))->ler2_rlen)
+
+#define LER2_tdra(p, v) \
+       (le->sc_ler2pad ? (((volatile struct lereg2pad *)(p))->ler2_tdra = (v)) : \
+        (((volatile struct lereg2 *)(p))->ler2_tdra = (v)))
+#define        LER2V_tdra(p) \
+       (le->sc_ler2pad ? ((volatile struct lereg2pad *)(p))->ler2_tdra : \
+        ((volatile struct lereg2 *)(p))->ler2_tdra)
+
+#define LER2_tlen(p, v) \
+       (le->sc_ler2pad ? (((volatile struct lereg2pad *)(p))->ler2_tlen = (v)) : \
+        (((volatile struct lereg2 *)(p))->ler2_tlen = (v)))
+#define        LER2V_tlen(p) \
+       (le->sc_ler2pad ? ((volatile struct lereg2pad *)(p))->ler2_tlen : \
+        ((volatile struct lereg2 *)(p))->ler2_tlen)
+
+#define LER2_rmd0(p, v) \
+       (le->sc_ler2pad ? (((volatile struct lermdpad *)(p))->rmd0 = (v)) : \
+        ((((volatile struct lermd *)(p))->rmd0 = (v))))
+#define LER2V_rmd0(p) \
+       (le->sc_ler2pad ? ((volatile struct lermdpad *)(p))->rmd0 : \
+        ((volatile struct lermd *)(p))->rmd0)
+
+#define LER2_rmd1(p, v) \
+       (le->sc_ler2pad ? (((volatile struct lermdpad *)(p))->rmd1 = (v)) : \
+        (((volatile struct lermd *)(p))->rmd1 = (v)))
+#define LER2V_rmd1(p) \
+       (le->sc_ler2pad ? ((volatile struct lermdpad *)(p))->rmd1 : \
+        ((volatile struct lermd *)(p))->rmd1)
+
+#define LER2_rmd2(p, v) \
+       (le->sc_ler2pad ? (((volatile struct lermdpad *)(p))->rmd2 = (v)) : \
+        (((volatile struct lermd *)(p))->rmd2 = (v)))
+#define LER2V_rmd2(p) \
+       (le->sc_ler2pad ? ((volatile struct lermdpad *)(p))->rmd2 : \
+        ((volatile struct lermd *)(p))->rmd2)
+
+#define LER2_rmd3(p, v) \
+       (le->sc_ler2pad ? (((volatile struct lermdpad *)(p))->rmd3 = (v)) : \
+        (((volatile struct lermd *)(p))->rmd3 = (v)))
+#define LER2V_rmd3(p) \
+       (le->sc_ler2pad ? ((volatile struct lermdpad *)(p))->rmd3 : \
+        ((volatile struct lermd *)(p))->rmd3)
+
+#define LER2_tmd0(p, v) \
+       (le->sc_ler2pad ? (((volatile struct letmdpad *)(p))->tmd0 = (v)) : \
+        (((volatile struct letmd *)(p))->tmd0 = (v)))
+#define LER2V_tmd0(p) \
+       (le->sc_ler2pad ? ((volatile struct letmdpad *)(p))->tmd0 : \
+        ((volatile struct letmd *)(p))->tmd0)
+
+#define LER2_tmd1(p, v) \
+       (le->sc_ler2pad ? (((volatile struct letmdpad *)(p))->tmd1 = (v)) : \
+        (((volatile struct letmd *)(p))->tmd1 = (v)))
+#define LER2V_tmd1(p) \
+       (le->sc_ler2pad ? ((volatile struct letmdpad *)(p))->tmd1 : \
+        ((volatile struct letmd *)(p))->tmd1)
+
+#define LER2_tmd2(p, v) \
+       (le->sc_ler2pad ? (((volatile struct letmdpad *)(p))->tmd2 = (v)) : \
+        (((volatile struct letmd *)(p))->tmd2 = (v)))
+#define LER2V_tmd2(p) \
+       (le->sc_ler2pad ? ((volatile struct letmdpad *)(p))->tmd2 : \
+        ((volatile struct letmd *)(p))->tmd2)
+
+#define LER2_tmd3(p, v) \
+       (le->sc_ler2pad ? (((volatile struct letmdpad *)(p))->tmd3 = (v)) : \
+        (((volatile struct letmd *)(p))->tmd3 = (v)))
+#define LER2V_tmd3(p) \
+       (le->sc_ler2pad ? ((volatile struct letmdpad *)(p))->tmd3 : \
+        ((volatile struct letmd *)(p))->tmd3)
+
 /*
  * Control and status bits -- lereg0
  */
 /*
  * Control and status bits -- lereg0
  */
index 435c910..87ce5e5 100644 (file)
@@ -1,17 +1,17 @@
-/*
- * Copyright (c) 1992 Regents of the University of California.
+/*-
+ * Copyright (c) 1992 The Regents of the University of California.
  * All rights reserved.
  *
  * This code is derived from software contributed to Berkeley by
  * All rights reserved.
  *
  * This code is derived from software contributed to Berkeley by
- * Ralph Campbell.
+ * Ralph Campbell and Rick Macklem.
  *
  * %sccs.include.redist.c%
  *
  *
  * %sccs.include.redist.c%
  *
- *     @(#)pdma.h      7.2 (Berkeley) %G%
+ *     @(#)pdma.h      7.3 (Berkeley) %G%
  */
 
 struct pdma {
  */
 
 struct pdma {
-       dcregs  *p_addr;
+       void    *p_addr;
        char    *p_mem;
        char    *p_end;
        int     p_arg;
        char    *p_mem;
        char    *p_end;
        int     p_arg;
index aa783d5..a8b9b6e 100644 (file)
@@ -1,14 +1,16 @@
-/* 
- * Copyright (c) 1992 Regents of the University of California.
+/*-
+ * Copyright (c) 1992 The Regents of the University of California.
  * All rights reserved.
  *
  * This code is derived from software contributed to Berkeley by
  * All rights reserved.
  *
  * This code is derived from software contributed to Berkeley by
- * Ralph Campbell.
+ * Ralph Campbell and Rick Macklem.
  *
  * %sccs.include.redist.c%
  *
  *
  * %sccs.include.redist.c%
  *
- *     @(#)pm.c        7.7 (Berkeley) %G%
- *
+ *     @(#)pm.c        7.8 (Berkeley) %G%
+ */
+
+/* 
  *  devGraphics.c --
  *
  *             This file contains machine-dependent routines for the graphics device.
  *  devGraphics.c --
  *
  *             This file contains machine-dependent routines for the graphics device.
  *     v 9.2 90/02/13 22:16:24 shirriff Exp $ SPRITE (DECWRL)";
  */
 
  *     v 9.2 90/02/13 22:16:24 shirriff Exp $ SPRITE (DECWRL)";
  */
 
-#include "pm.h"
+#include <pm.h>
+#include <dc.h>
 #if NPM > 0
 #if NPM > 0
+#if NDC == 0
+pm needs dc device
+#else
 
 #include <sys/param.h>
 #include <sys/time.h>
 
 #include <sys/param.h>
 #include <sys/time.h>
 #include <vm/vm.h>
 
 #include <machine/machConst.h>
 #include <vm/vm.h>
 
 #include <machine/machConst.h>
-#include <machine/machMon.h>
 #include <machine/dc7085cons.h>
 #include <machine/pmioctl.h>
 
 #include <machine/dc7085cons.h>
 #include <machine/pmioctl.h>
 
+#include <pmax/pmax/kn01.h>
+#include <pmax/pmax/pmaxtype.h>
+#include <pmax/pmax/cons.h>
+
 #include <pmax/dev/device.h>
 #include <pmax/dev/pmreg.h>
 #include <pmax/dev/device.h>
 #include <pmax/dev/pmreg.h>
-#include <pmax/dev/font.c>
-
-#define MAX_ROW        56
-#define MAX_COL        80
-
-/*
- * Macro to translate from a time struct to milliseconds.
- */
-#define TO_MS(tv) ((tv.tv_sec * 1000) + (tv.tv_usec / 1000))
-
-static u_short curReg;         /* copy of PCCRegs.cmdr since it's read only */
-static int     isMono;         /* true if B&W frame buffer */
-static int     initialized;    /* true if 'probe' was successful */
-static int     GraphicsOpen;   /* true if the graphics device is open */
-static int     row, col;       /* row and col for console cursor */
-static struct  selinfo pm_selp;/* process waiting for select */
+#include <pmax/dev/fbreg.h>
 
 /*
  * These need to be mapped into user space.
  */
 
 /*
  * These need to be mapped into user space.
  */
-static struct pmuaccess {
-       PM_Info         scrInfo;
-       pmEvent         events[PM_MAXEVQ];      
-       pmTimeCoord     tcs[MOTION_BUFFER_SIZE];
-} pmu;
-
-/*
- * Font mask bits used by Blitc().
- */
-static unsigned int fontmaskBits[16] = {
-       0x00000000,
-       0x00000001,
-       0x00000100,
-       0x00000101,
-       0x00010000,
-       0x00010001,
-       0x00010100,
-       0x00010101,
-       0x01000000,
-       0x01000001,
-       0x01000100,
-       0x01000101,
-       0x01010000,
-       0x01010001,
-       0x01010100,
-       0x01010101
-};
+struct fbuaccess pmu;
+struct pmax_fb pmfb;
+static u_short curReg;         /* copy of PCCRegs.cmdr since it's read only */
 
 /*
  * Forward references.
  */
 
 /*
  * Forward references.
  */
-static void Scroll();
-static void Blitc();
-
-static void ScreenInit();
-static void LoadCursor();
-static void RestoreCursorColor();
-static void CursorColor();
-static void PosCursor();
-static void InitColorMap();
-static void VDACInit();
-static void LoadColorMap();
-static void EnableVideo();
-static void DisableVideo();
-
-extern void dcKBDPutc();
+extern void fbScroll();
+
+static void pmScreenInit();
+static void pmLoadCursor();
+static void pmRestoreCursorColor();
+static void pmCursorColor();
+void pmPosCursor();
+static void pmInitColorMap();
+static void pmVDACInit();
+static void pmLoadColorMap();
+
+extern void dcPutc(), fbKbdEvent(), fbMouseEvent(), fbMouseButtons();
+void pmKbdEvent(), pmMouseEvent(), pmMouseButtons();
 extern void (*dcDivertXInput)();
 extern void (*dcMouseEvent)();
 extern void (*dcMouseButtons)();
 extern void (*dcDivertXInput)();
 extern void (*dcMouseEvent)();
 extern void (*dcMouseButtons)();
+extern int pmax_boardtype;
+extern u_short defCursor[32];
+extern struct consdev cn_tab;
 
 int    pmprobe();
 struct driver pmdriver = {
 
 int    pmprobe();
 struct driver pmdriver = {
@@ -129,533 +100,43 @@ struct   driver pmdriver = {
 pmprobe(cp)
        register struct pmax_ctlr *cp;
 {
 pmprobe(cp)
        register struct pmax_ctlr *cp;
 {
+       register struct pmax_fb *fp = &pmfb;
 
 
-       if (!initialized && !pminit())
+       if (pmax_boardtype != DS_PMAX)
+               return (0);
+       if (!fp->initialized && !pminit())
                return (0);
                return (0);
-       if (isMono)
+       if (fp->isMono)
                printf("pm0 (monochrome display)\n");
        else
                printf("pm0 (color display)\n");
        return (1);
 }
 
                printf("pm0 (monochrome display)\n");
        else
                printf("pm0 (color display)\n");
        return (1);
 }
 
-/*
- *----------------------------------------------------------------------
- *
- * pmKbdEvent --
- *
- *     Process a received character.
- *
- * Results:
- *     None.
- *
- * Side effects:
- *     Events added to the queue.
- *
- *----------------------------------------------------------------------
- */
-void
-pmKbdEvent(ch)
-       int ch;
-{
-       register pmEvent *eventPtr;
-       int i;
-
-       if (!GraphicsOpen)
-               return;
-
-       /*
-        * See if there is room in the queue.
-        */
-       i = PM_EVROUND(pmu.scrInfo.qe.eTail + 1);
-       if (i == pmu.scrInfo.qe.eHead)
-               return;
-
-       /*
-        * Add the event to the queue.
-        */
-       eventPtr = &pmu.events[pmu.scrInfo.qe.eTail];
-       eventPtr->type = BUTTON_RAW_TYPE;
-       eventPtr->device = KEYBOARD_DEVICE;
-       eventPtr->x = pmu.scrInfo.mouse.x;
-       eventPtr->y = pmu.scrInfo.mouse.y;
-       eventPtr->time = TO_MS(time);
-       eventPtr->key = ch;
-       pmu.scrInfo.qe.eTail = i;
-       selwakeup(&pm_selp);
-}
-
-/*
- *----------------------------------------------------------------------
- *
- * pmMouseEvent --
- *
- *     Process a mouse event.
- *
- * Results:
- *     None.
- *
- * Side effects:
- *     An event is added to the event queue.
- *
- *----------------------------------------------------------------------
- */
-void
-pmMouseEvent(newRepPtr) 
-       register MouseReport *newRepPtr;
-{
-       unsigned milliSec;
-       int i;
-       pmEvent *eventPtr;
-
-       if (!GraphicsOpen)
-               return;
-
-       milliSec = TO_MS(time);
-
-       /*
-        * Check to see if we have to accelerate the mouse
-        */
-       if (pmu.scrInfo.mscale >= 0) {
-               if (newRepPtr->dx >= pmu.scrInfo.mthreshold) {
-                       newRepPtr->dx +=
-                               (newRepPtr->dx - pmu.scrInfo.mthreshold) *
-                               pmu.scrInfo.mscale;
-               }
-               if (newRepPtr->dy >= pmu.scrInfo.mthreshold) {
-                       newRepPtr->dy +=
-                               (newRepPtr->dy - pmu.scrInfo.mthreshold) *
-                               pmu.scrInfo.mscale;
-               }
-       }
-
-       /*
-        * Update mouse position
-        */
-       if (newRepPtr->state & MOUSE_X_SIGN) {
-               pmu.scrInfo.mouse.x += newRepPtr->dx;
-               if (pmu.scrInfo.mouse.x > pmu.scrInfo.max_cur_x)
-                       pmu.scrInfo.mouse.x = pmu.scrInfo.max_cur_x;
-       } else {
-               pmu.scrInfo.mouse.x -= newRepPtr->dx;
-               if (pmu.scrInfo.mouse.x < pmu.scrInfo.min_cur_x)
-                       pmu.scrInfo.mouse.x = pmu.scrInfo.min_cur_x;
-       }
-       if (newRepPtr->state & MOUSE_Y_SIGN) {
-               pmu.scrInfo.mouse.y -= newRepPtr->dy;
-               if (pmu.scrInfo.mouse.y < pmu.scrInfo.min_cur_y)
-                       pmu.scrInfo.mouse.y = pmu.scrInfo.min_cur_y;
-       } else {
-               pmu.scrInfo.mouse.y += newRepPtr->dy;
-               if (pmu.scrInfo.mouse.y > pmu.scrInfo.max_cur_y)
-                       pmu.scrInfo.mouse.y = pmu.scrInfo.max_cur_y;
-       }
-
-       /*
-        * Move the hardware cursor.
-        */
-       PosCursor(pmu.scrInfo.mouse.x, pmu.scrInfo.mouse.y);
-
-       /*
-        * Store the motion event in the motion buffer.
-        */
-       pmu.tcs[pmu.scrInfo.qe.tcNext].time = milliSec;
-       pmu.tcs[pmu.scrInfo.qe.tcNext].x = pmu.scrInfo.mouse.x;
-       pmu.tcs[pmu.scrInfo.qe.tcNext].y = pmu.scrInfo.mouse.y;
-       if (++pmu.scrInfo.qe.tcNext >= MOTION_BUFFER_SIZE)
-               pmu.scrInfo.qe.tcNext = 0;
-       if (pmu.scrInfo.mouse.y < pmu.scrInfo.mbox.bottom &&
-           pmu.scrInfo.mouse.y >=  pmu.scrInfo.mbox.top &&
-           pmu.scrInfo.mouse.x < pmu.scrInfo.mbox.right &&
-           pmu.scrInfo.mouse.x >=  pmu.scrInfo.mbox.left)
-               return;
-
-       pmu.scrInfo.mbox.bottom = 0;
-       if (PM_EVROUND(pmu.scrInfo.qe.eTail + 1) == pmu.scrInfo.qe.eHead)
-               return;
-
-       i = PM_EVROUND(pmu.scrInfo.qe.eTail - 1);
-       if ((pmu.scrInfo.qe.eTail != pmu.scrInfo.qe.eHead) && 
-           (i != pmu.scrInfo.qe.eHead)) {
-               pmEvent *eventPtr;
-
-               eventPtr = &pmu.events[i];
-               if (eventPtr->type == MOTION_TYPE) {
-                       eventPtr->x = pmu.scrInfo.mouse.x;
-                       eventPtr->y = pmu.scrInfo.mouse.y;
-                       eventPtr->time = milliSec;
-                       eventPtr->device = MOUSE_DEVICE;
-                       return;
-               }
-       }
-       /*
-        * Put event into queue and wakeup any waiters.
-        */
-       eventPtr = &pmu.events[pmu.scrInfo.qe.eTail];
-       eventPtr->type = MOTION_TYPE;
-       eventPtr->time = milliSec;
-       eventPtr->x = pmu.scrInfo.mouse.x;
-       eventPtr->y = pmu.scrInfo.mouse.y;
-       eventPtr->device = MOUSE_DEVICE;
-       pmu.scrInfo.qe.eTail = PM_EVROUND(pmu.scrInfo.qe.eTail + 1);
-       selwakeup(&pm_selp);
-}
-
-/*
- *----------------------------------------------------------------------
- *
- * pmMouseButtons --
- *
- *     Process mouse buttons.
- *
- * Results:
- *     None.
- *
- * Side effects:
- *     None.
- *
- *----------------------------------------------------------------------
- */
-void
-pmMouseButtons(newRepPtr)
-       MouseReport *newRepPtr;
-{
-       static char temp, oldSwitch, newSwitch;
-       int i, j;
-       pmEvent *eventPtr;
-       static MouseReport lastRep;
-
-       if (!GraphicsOpen)
-               return;
-
-       newSwitch = newRepPtr->state & 0x07;
-       oldSwitch = lastRep.state & 0x07;
-
-       temp = oldSwitch ^ newSwitch;
-       if (temp == 0)
-               return;
-       for (j = 1; j < 8; j <<= 1) {
-               if ((j & temp) == 0)
-                       continue;
-
-               /*
-                * Check for room in the queue
-                */
-               i = PM_EVROUND(pmu.scrInfo.qe.eTail+1);
-               if (i == pmu.scrInfo.qe.eHead)
-                       return;
-
-               /*
-                * Put event into queue.
-                */
-               eventPtr = &pmu.events[pmu.scrInfo.qe.eTail];
-
-               switch (j) {
-               case RIGHT_BUTTON:
-                       eventPtr->key = EVENT_RIGHT_BUTTON;
-                       break;
-
-               case MIDDLE_BUTTON:
-                       eventPtr->key = EVENT_MIDDLE_BUTTON;
-                       break;
-
-               case LEFT_BUTTON:
-                       eventPtr->key = EVENT_LEFT_BUTTON;
-               }
-               if (newSwitch & j)
-                       eventPtr->type = BUTTON_DOWN_TYPE;
-               else
-                       eventPtr->type = BUTTON_UP_TYPE;
-               eventPtr->device = MOUSE_DEVICE;
-
-               eventPtr->time = TO_MS(time);
-               eventPtr->x = pmu.scrInfo.mouse.x;
-               eventPtr->y = pmu.scrInfo.mouse.y;
-       }
-       pmu.scrInfo.qe.eTail = i;
-       selwakeup(&pm_selp);
-
-       lastRep = *newRepPtr;
-       pmu.scrInfo.mswitches = newSwitch;
-}
-
-/*
- *----------------------------------------------------------------------
- *
- * Scroll --
- *
- *     Scroll the screen.
- *
- * Results:
- *     None.
- *
- * Side effects:
- *     None.
- *
- *----------------------------------------------------------------------
- */
-static void
-Scroll()
-{
-       register int *dest, *src;
-       register int *end;
-       register int temp0, temp1, temp2, temp3;
-       register int i, scanInc, lineCount;
-       int line;
-
-       /*
-        * If the mouse is on we don't scroll so that the bit map remains sane.
-        */
-       if (GraphicsOpen) {
-               row = 0;
-               return;
-       }
-
-       /*
-        *  The following is an optimization to cause the scrolling 
-        *  of text to be memory limited.  Basically the writebuffer is 
-        *  4 words (32 bits ea.) long so to achieve maximum speed we 
-        *  read and write in multiples of 4 words. We also limit the 
-        *  size to be MAX_COL characters for more speed. 
-        */
-       if (isMono) {
-               lineCount = 5;
-               line = 1920 * 2;
-               scanInc = 44;
-       } else {
-               lineCount = 40;
-               scanInc = 96;
-               line = 1920 * 8;
-       }
-       src = (int *)(MACH_UNCACHED_FRAME_BUFFER_ADDR + line);
-       dest = (int *)(MACH_UNCACHED_FRAME_BUFFER_ADDR);
-       end = (int *)(MACH_UNCACHED_FRAME_BUFFER_ADDR + (60 * line) - line);
-       do {
-               i = 0;
-               do {
-                       temp0 = src[0];
-                       temp1 = src[1];
-                       temp2 = src[2];
-                       temp3 = src[3];
-                       dest[0] = temp0;
-                       dest[1] = temp1;
-                       dest[2] = temp2;
-                       dest[3] = temp3;
-                       dest += 4;
-                       src += 4;
-                       i++;
-               } while (i < lineCount);
-               src += scanInc;
-               dest += scanInc;
-       } while (src < end);
-
-       /* 
-        * Now zero out the last two lines 
-        */
-       bzero(MACH_UNCACHED_FRAME_BUFFER_ADDR + (row * line), 3 * line);
-}
-
-/*
- *----------------------------------------------------------------------
- *
- * pmPutc --
- *
- *     Write a character to the console.
- *
- * Results:
- *     None.
- *
- * Side effects:
- *     None.
- *
- *----------------------------------------------------------------------
- */
-pmPutc(c)
-       register int c;
-{
-       int s;
-
-       s = splhigh();  /* in case we do any printf's at interrupt time */
-       if (initialized) {
-#ifdef DEBUG
-               /*
-                * If the HELP key is pressed, wait for another
-                * HELP key press to start/stop output.
-                */
-               if (dcDebugGetc() == LK_HELP) {
-                       while (dcDebugGetc() != LK_HELP)
-                               ;
-               }
-#endif
-               Blitc(c);
-       } else {
-               void (*f)() = (void (*)())MACH_MON_PUTCHAR;
-
-               (*f)(c);
-       }
-       splx(s);
-}
-
-/*
- *----------------------------------------------------------------------
- *
- * Blitc --
- *
- *     Write a character to the screen.
- *
- * Results:
- *     None.
- *
- * Side effects:
- *     None.
- *
- *----------------------------------------------------------------------
- */
-static void
-Blitc(c)
-       register int c;
-{
-       register char *bRow, *fRow;
-       register int i;
-       register int ote = isMono ? 256 : 1024; /* offset to table entry */
-       int colMult = isMono ? 1 : 8;
-
-       c &= 0xff;
-
-       switch (c) {
-       case '\t':
-               for (i = 8 - (col & 0x7); i > 0; i--)
-                       Blitc(' ');
-               break;
-
-       case '\r':
-               col = 0;
-               break;
-
-       case '\b':
-               col--;
-               if (col < 0)
-                       col = 0;
-               break;
-
-       case '\n':
-               if (row + 1 >= MAX_ROW)
-                       Scroll();
-               else
-                       row++;
-               col = 0;
-               break;
-
-       case '\007':
-               dcKBDPutc(LK_RING_BELL);
-               break;
-
-       default:
-               /*
-                * 0xA1 to 0xFD are the printable characters added with 8-bit
-                * support.
-                */
-               if (c < ' ' || c > '~' && c < 0xA1 || c > 0xFD)
-                       break;
-               /*
-                * If the next character will wrap around then 
-                * increment row counter or scroll screen.
-                */
-               if (col >= MAX_COL) {
-                       col = 0;
-                       if (row + 1 >= MAX_ROW)
-                               Scroll();
-                       else
-                               row++;
-               }
-               bRow = (char *)(MACH_UNCACHED_FRAME_BUFFER_ADDR +
-                       (row * 15 & 0x3ff) * ote + col * colMult);
-               i = c - ' ';
-               /*
-                * This is to skip the (32) 8-bit 
-                * control chars, as well as DEL 
-                * and 0xA0 which aren't printable
-                */
-               if (c > '~')
-                       i -= 34; 
-               i *= 15;
-               fRow = (char *)((int)pmFont + i);
-
-               /* inline expansion for speed */
-               if (isMono) {
-                       *bRow = *fRow++; bRow += ote;
-                       *bRow = *fRow++; bRow += ote;
-                       *bRow = *fRow++; bRow += ote;
-                       *bRow = *fRow++; bRow += ote;
-                       *bRow = *fRow++; bRow += ote;
-                       *bRow = *fRow++; bRow += ote;
-                       *bRow = *fRow++; bRow += ote;
-                       *bRow = *fRow++; bRow += ote;
-                       *bRow = *fRow++; bRow += ote;
-                       *bRow = *fRow++; bRow += ote;
-                       *bRow = *fRow++; bRow += ote;
-                       *bRow = *fRow++; bRow += ote;
-                       *bRow = *fRow++; bRow += ote;
-                       *bRow = *fRow++; bRow += ote;
-                       *bRow = *fRow++; bRow += ote;
-               } else {
-                       register int j;
-                       register unsigned int *pInt;
-
-                       pInt = (unsigned int *)bRow;
-                       for (j = 0; j < 15; j++) {
-                               /*
-                                * fontmaskBits converts a nibble
-                                * (4 bytes) to a long word 
-                                * containing 4 pixels corresponding
-                                * to each bit in the nibble.  Thus
-                                * we write two longwords for each
-                                * byte in font.
-                                * 
-                                * Remember the font is 8 bits wide
-                                * and 15 bits high.
-                                *
-                                * We add 256 to the pointer to
-                                * point to the pixel on the 
-                                * next scan line
-                                * directly below the current
-                                * pixel.
-                                */
-                               pInt[0] = fontmaskBits[(*fRow) & 0xf];
-                               pInt[1] = fontmaskBits[((*fRow) >> 4) & 0xf];
-                               fRow++; 
-                               pInt += 256;
-                       }
-               }
-               col++; /* increment column counter */
-       }
-       if (!GraphicsOpen)
-               PosCursor(col * 8, row * 15);
-}
-
 /*ARGSUSED*/
 pmopen(dev, flag)
        dev_t dev;
        int flag;
 {
 /*ARGSUSED*/
 pmopen(dev, flag)
        dev_t dev;
        int flag;
 {
+       register struct pmax_fb *fp = &pmfb;
        int s;
 
        int s;
 
-       if (!initialized)
+       if (!fp->initialized)
                return (ENXIO);
                return (ENXIO);
-       if (GraphicsOpen)
+       if (fp->GraphicsOpen)
                return (EBUSY);
 
                return (EBUSY);
 
-       GraphicsOpen = 1;
-       if (!isMono)
-               InitColorMap();
+       fp->GraphicsOpen = 1;
+       if (!fp->isMono)
+               pmInitColorMap();
        /*
         * Set up event queue for later
         */
        /*
         * Set up event queue for later
         */
-       pmu.scrInfo.qe.eSize = PM_MAXEVQ;
-       pmu.scrInfo.qe.eHead = pmu.scrInfo.qe.eTail = 0;
-       pmu.scrInfo.qe.tcSize = MOTION_BUFFER_SIZE;
-       pmu.scrInfo.qe.tcNext = 0;
-       pmu.scrInfo.qe.timestamp_ms = TO_MS(time);
+       fp->fbu->scrInfo.qe.eSize = PM_MAXEVQ;
+       fp->fbu->scrInfo.qe.eHead = fp->fbu->scrInfo.qe.eTail = 0;
+       fp->fbu->scrInfo.qe.tcSize = MOTION_BUFFER_SIZE;
+       fp->fbu->scrInfo.qe.tcNext = 0;
+       fp->fbu->scrInfo.qe.timestamp_ms = TO_MS(time);
        s = spltty();
        dcDivertXInput = pmKbdEvent;
        dcMouseEvent = pmMouseEvent;
        s = spltty();
        dcDivertXInput = pmKbdEvent;
        dcMouseEvent = pmMouseEvent;
@@ -669,24 +150,25 @@ pmclose(dev, flag)
        dev_t dev;
        int flag;
 {
        dev_t dev;
        int flag;
 {
+       register struct pmax_fb *fp = &pmfb;
        int s;
 
        int s;
 
-       if (!GraphicsOpen)
+       if (!fp->GraphicsOpen)
                return (EBADF);
 
                return (EBADF);
 
-       GraphicsOpen = 0;
-       if (!isMono)
-               InitColorMap();
+       fp->GraphicsOpen = 0;
+       if (!fp->isMono)
+               pmInitColorMap();
        s = spltty();
        dcDivertXInput = (void (*)())0;
        dcMouseEvent = (void (*)())0;
        dcMouseButtons = (void (*)())0;
        splx(s);
        s = spltty();
        dcDivertXInput = (void (*)())0;
        dcMouseEvent = (void (*)())0;
        dcMouseButtons = (void (*)())0;
        splx(s);
-       ScreenInit();
+       pmScreenInit();
        vmUserUnmap();
        vmUserUnmap();
-       bzero((caddr_t)MACH_UNCACHED_FRAME_BUFFER_ADDR,
-               (isMono ? 1024 / 8 : 1024) * 864);
-       PosCursor(col * 8, row * 15);
+       bzero((caddr_t)fp->fr_addr,
+               (fp->isMono ? 1024 / 8 : 1024) * 864);
+       pmPosCursor(fp->col * 8, fp->row * 15);
        return (0);
 }
 
        return (0);
 }
 
@@ -695,7 +177,8 @@ pmioctl(dev, cmd, data, flag)
        dev_t dev;
        caddr_t data;
 {
        dev_t dev;
        caddr_t data;
 {
-       register PCCRegs *pcc = (PCCRegs *)MACH_CURSOR_REG_ADDR;
+       register PCCRegs *pcc = (PCCRegs *)MACH_PHYS_TO_UNCACHED(KN01_SYS_PCC);
+       register struct pmax_fb *fp = &pmfb;
        int s;
 
        switch (cmd) {
        int s;
 
        switch (cmd) {
@@ -708,27 +191,28 @@ pmioctl(dev, cmd, data, flag)
                 * Map the all the data the user needs access to into
                 * user space.
                 */
                 * Map the all the data the user needs access to into
                 * user space.
                 */
-               addr = vmUserMap(sizeof(pmu), (unsigned)&pmu);
+               addr = vmUserMap(sizeof(struct fbuaccess), (unsigned)fp->fbu);
                if (addr == (caddr_t)0)
                        goto mapError;
                if (addr == (caddr_t)0)
                        goto mapError;
-               *(PM_Info **)data = &((struct pmuaccess *)addr)->scrInfo;
-               pmu.scrInfo.qe.events = ((struct pmuaccess *)addr)->events;
-               pmu.scrInfo.qe.tcs = ((struct pmuaccess *)addr)->tcs;
+               *(PM_Info **)data = &((struct fbuaccess *)addr)->scrInfo;
+               fp->fbu->scrInfo.qe.events = ((struct fbuaccess *)addr)->events;
+               fp->fbu->scrInfo.qe.tcs = ((struct fbuaccess *)addr)->tcs;
                /*
                 * Map the plane mask into the user's address space.
                 */
                /*
                 * Map the plane mask into the user's address space.
                 */
-               addr = vmUserMap(4, (unsigned)MACH_PLANE_MASK_ADDR);
+               addr = vmUserMap(4, (unsigned)
+                       MACH_PHYS_TO_UNCACHED(KN01_PHYS_COLMASK_START));
                if (addr == (caddr_t)0)
                        goto mapError;
                if (addr == (caddr_t)0)
                        goto mapError;
-               pmu.scrInfo.planemask = (char *)addr;
+               fp->fbu->scrInfo.planemask = (char *)addr;
                /*
                 * Map the frame buffer into the user's address space.
                 */
                /*
                 * Map the frame buffer into the user's address space.
                 */
-               addr = vmUserMap(isMono ? 256*1024 : 1024*1024,
-                       (unsigned)MACH_UNCACHED_FRAME_BUFFER_ADDR);
+               addr = vmUserMap(fp->isMono ? 256*1024 : 1024*1024,
+                       (unsigned)fp->fr_addr);
                if (addr == (caddr_t)0)
                        goto mapError;
                if (addr == (caddr_t)0)
                        goto mapError;
-               pmu.scrInfo.bitmap = (char *)addr;
+               fp->fbu->scrInfo.bitmap = (char *)addr;
                break;
 
        mapError:
                break;
 
        mapError:
@@ -741,15 +225,15 @@ pmioctl(dev, cmd, data, flag)
                /*
                 * Set mouse state.
                 */
                /*
                 * Set mouse state.
                 */
-               pmu.scrInfo.mouse = *(pmCursor *)data;
-               PosCursor(pmu.scrInfo.mouse.x, pmu.scrInfo.mouse.y);
+               fp->fbu->scrInfo.mouse = *(pmCursor *)data;
+               pmPosCursor(fp->fbu->scrInfo.mouse.x, fp->fbu->scrInfo.mouse.y);
                break;
 
        case QIOCINIT:
                /*
                 * Initialize the screen.
                 */
                break;
 
        case QIOCINIT:
                /*
                 * Initialize the screen.
                 */
-               ScreenInit();
+               pmScreenInit();
                break;
 
        case QIOCKPCMD:
                break;
 
        case QIOCKPCMD:
@@ -760,32 +244,32 @@ pmioctl(dev, cmd, data, flag)
                kpCmdPtr = (pmKpCmd *)data;
                if (kpCmdPtr->nbytes == 0)
                        kpCmdPtr->cmd |= 0x80;
                kpCmdPtr = (pmKpCmd *)data;
                if (kpCmdPtr->nbytes == 0)
                        kpCmdPtr->cmd |= 0x80;
-               if (!GraphicsOpen)
+               if (!fp->GraphicsOpen)
                        kpCmdPtr->cmd |= 1;
                        kpCmdPtr->cmd |= 1;
-               dcKBDPutc((int)kpCmdPtr->cmd);
+               (*fp->KBDPutc)(fp->kbddev, (int)kpCmdPtr->cmd);
                cp = &kpCmdPtr->par[0];
                for (; kpCmdPtr->nbytes > 0; cp++, kpCmdPtr->nbytes--) {
                        if (kpCmdPtr->nbytes == 1)
                                *cp |= 0x80;
                cp = &kpCmdPtr->par[0];
                for (; kpCmdPtr->nbytes > 0; cp++, kpCmdPtr->nbytes--) {
                        if (kpCmdPtr->nbytes == 1)
                                *cp |= 0x80;
-                       dcKBDPutc((int)*cp);
+                       (*fp->KBDPutc)(fp->kbddev, (int)*cp);
                }
                break;
            }
 
        case QIOCADDR:
                }
                break;
            }
 
        case QIOCADDR:
-               *(PM_Info **)data = &pmu.scrInfo;
+               *(PM_Info **)data = &fp->fbu->scrInfo;
                break;
 
        case QIOWCURSOR:
                break;
 
        case QIOWCURSOR:
-               LoadCursor((unsigned short *)data);
+               pmLoadCursor((unsigned short *)data);
                break;
 
        case QIOWCURSORCOLOR:
                break;
 
        case QIOWCURSORCOLOR:
-               CursorColor((unsigned int *)data);
+               pmCursorColor((unsigned int *)data);
                break;
 
        case QIOSETCMAP:
                break;
 
        case QIOSETCMAP:
-               LoadColorMap((ColorMap *)data);
+               pmLoadColorMap((ColorMap *)data);
                break;
 
        case QIOKERNLOOP:
                break;
 
        case QIOKERNLOOP:
@@ -805,16 +289,16 @@ pmioctl(dev, cmd, data, flag)
                break;
 
        case QIOVIDEOON:
                break;
 
        case QIOVIDEOON:
-               if (!isMono)
-                       RestoreCursorColor();
+               if (!fp->isMono)
+                       pmRestoreCursorColor();
                curReg |= PCC_ENPA;
                curReg &= ~PCC_FOPB;
                pcc->cmdr = curReg;
                break;
 
        case QIOVIDEOOFF:
                curReg |= PCC_ENPA;
                curReg &= ~PCC_FOPB;
                pcc->cmdr = curReg;
                break;
 
        case QIOVIDEOOFF:
-               if (!isMono)
-                       VDACInit();
+               if (!fp->isMono)
+                       pmVDACInit();
                curReg |= PCC_FOPB;
                curReg &= ~PCC_ENPA;
                pcc->cmdr = curReg;
                curReg |= PCC_FOPB;
                curReg &= ~PCC_ENPA;
                pcc->cmdr = curReg;
@@ -832,12 +316,13 @@ pmselect(dev, flag, p)
        int flag;
        struct proc *p;
 {
        int flag;
        struct proc *p;
 {
+       struct pmax_fb *fp = &pmfb;
 
        switch (flag) {
        case FREAD:
 
        switch (flag) {
        case FREAD:
-               if (pmu.scrInfo.qe.eHead != pmu.scrInfo.qe.eTail)
+               if (fp->fbu->scrInfo.qe.eHead != fp->fbu->scrInfo.qe.eTail)
                        return (1);
                        return (1);
-               selrecord(p, &pm_selp);
+               selrecord(p, &fp->selp);
                break;
        }
 
                break;
        }
 
@@ -847,29 +332,25 @@ pmselect(dev, flag, p)
 static u_char  bg_RGB[3];      /* background color for the cursor */
 static u_char  fg_RGB[3];      /* foreground color for the cursor */
 
 static u_char  bg_RGB[3];      /* background color for the cursor */
 static u_char  fg_RGB[3];      /* foreground color for the cursor */
 
-/*
- * The default cursor.
- */
-unsigned short defCursor[32] = { 
-/* plane A */ 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF,
-             0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF,
-/* plane B */ 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF,
-              0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF
-
-};
-
 /*
  * Test to see if device is present.
  * Return true if found and initialized ok.
  */
 pminit()
 {
 /*
  * Test to see if device is present.
  * Return true if found and initialized ok.
  */
 pminit()
 {
-       register PCCRegs *pcc = (PCCRegs *)MACH_CURSOR_REG_ADDR;
-
-       isMono = *(u_short *)MACH_SYS_CSR_ADDR & MACH_CSR_MONO;
-       if (isMono) {
+       register PCCRegs *pcc = (PCCRegs *)MACH_PHYS_TO_UNCACHED(KN01_SYS_PCC);
+       register struct pmax_fb *fp = &pmfb;
+
+       fp->isMono = *(volatile u_short *)MACH_PHYS_TO_UNCACHED(KN01_SYS_CSR) &
+               KN01_CSR_MONO;
+       fp->fr_addr = (char *)MACH_PHYS_TO_UNCACHED(KN01_PHYS_FBUF_START);
+       fp->fbu = &pmu;
+       fp->posCursor = pmPosCursor;
+       fp->KBDPutc = dcPutc;
+       fp->kbddev = makedev(DCDEV, DCKBD_PORT);
+       if (fp->isMono) {
                /* check for no frame buffer */
                /* check for no frame buffer */
-               if (badaddr((char *)MACH_UNCACHED_FRAME_BUFFER_ADDR, 4))
+               if (badaddr((char *)fp->fr_addr, 4))
                        return (0);
        }
 
                        return (0);
        }
 
@@ -886,38 +367,40 @@ pminit()
        /*
         * Initialize screen info.
         */
        /*
         * Initialize screen info.
         */
-       pmu.scrInfo.max_row = 56;
-       pmu.scrInfo.max_col = 80;
-       pmu.scrInfo.max_x = 1024;
-       pmu.scrInfo.max_y = 864;
-       pmu.scrInfo.max_cur_x = 1023;
-       pmu.scrInfo.max_cur_y = 863;
-       pmu.scrInfo.version = 11;
-       pmu.scrInfo.mthreshold = 4;     
-       pmu.scrInfo.mscale = 2;
-       pmu.scrInfo.min_cur_x = -15;
-       pmu.scrInfo.min_cur_y = -15;
-       pmu.scrInfo.qe.timestamp_ms = TO_MS(time);
-       pmu.scrInfo.qe.eSize = PM_MAXEVQ;
-       pmu.scrInfo.qe.eHead = pmu.scrInfo.qe.eTail = 0;
-       pmu.scrInfo.qe.tcSize = MOTION_BUFFER_SIZE;
-       pmu.scrInfo.qe.tcNext = 0;
+       fp->fbu->scrInfo.max_row = 56;
+       fp->fbu->scrInfo.max_col = 80;
+       fp->fbu->scrInfo.max_x = 1024;
+       fp->fbu->scrInfo.max_y = 864;
+       fp->fbu->scrInfo.max_cur_x = 1023;
+       fp->fbu->scrInfo.max_cur_y = 863;
+       fp->fbu->scrInfo.version = 11;
+       fp->fbu->scrInfo.mthreshold = 4;        
+       fp->fbu->scrInfo.mscale = 2;
+       fp->fbu->scrInfo.min_cur_x = -15;
+       fp->fbu->scrInfo.min_cur_y = -15;
+       fp->fbu->scrInfo.qe.timestamp_ms = TO_MS(time);
+       fp->fbu->scrInfo.qe.eSize = PM_MAXEVQ;
+       fp->fbu->scrInfo.qe.eHead = fp->fbu->scrInfo.qe.eTail = 0;
+       fp->fbu->scrInfo.qe.tcSize = MOTION_BUFFER_SIZE;
+       fp->fbu->scrInfo.qe.tcNext = 0;
 
        /*
         * Initialize the color map, the screen, and the mouse.
         */
 
        /*
         * Initialize the color map, the screen, and the mouse.
         */
-       InitColorMap();
-       ScreenInit();
-       Scroll();
+       pmInitColorMap();
+       pmScreenInit();
+       fbScroll(fp);
 
 
-       initialized = 1;
+       fp->initialized = 1;
+       if (cn_tab.cn_fb == (struct pmax_fb *)0)
+               cn_tab.cn_fb = fp;
        return (1);
 }      
 
 /*
  * ----------------------------------------------------------------------------
  *
        return (1);
 }      
 
 /*
  * ----------------------------------------------------------------------------
  *
- * ScreenInit --
+ * pmScreenInit --
  *
  *     Initialize the screen.
  *
  *
  *     Initialize the screen.
  *
@@ -930,28 +413,29 @@ pminit()
  * ----------------------------------------------------------------------------
  */
 static void
  * ----------------------------------------------------------------------------
  */
 static void
-ScreenInit()
+pmScreenInit()
 {
 {
+       register struct pmax_fb *fp = &pmfb;
 
        /*
         * Home the cursor.
         * We want an LSI terminal emulation.  We want the graphics
         * terminal to scroll from the bottom. So start at the bottom.
         */
 
        /*
         * Home the cursor.
         * We want an LSI terminal emulation.  We want the graphics
         * terminal to scroll from the bottom. So start at the bottom.
         */
-       row = 55;
-       col = 0;
+       fp->row = 55;
+       fp->col = 0;
 
        /*
         * Load the cursor with the default values
         *
         */
 
        /*
         * Load the cursor with the default values
         *
         */
-       LoadCursor(defCursor);
+       pmLoadCursor(defCursor);
 }
 
 /*
  * ----------------------------------------------------------------------------
  *
 }
 
 /*
  * ----------------------------------------------------------------------------
  *
- * LoadCursor --
+ * pmLoadCursor --
  *
  *     Routine to load the cursor Sprite pattern.
  *
  *
  *     Routine to load the cursor Sprite pattern.
  *
@@ -964,10 +448,10 @@ ScreenInit()
  * ----------------------------------------------------------------------------
  */
 static void
  * ----------------------------------------------------------------------------
  */
 static void
-LoadCursor(cur)
+pmLoadCursor(cur)
        unsigned short *cur;
 {
        unsigned short *cur;
 {
-       register PCCRegs *pcc = (PCCRegs *)MACH_CURSOR_REG_ADDR;
+       register PCCRegs *pcc = (PCCRegs *)MACH_PHYS_TO_UNCACHED(KN01_SYS_PCC);
        register int i;
 
        curReg |= PCC_LODSA;
        register int i;
 
        curReg |= PCC_LODSA;
@@ -983,7 +467,7 @@ LoadCursor(cur)
 /*
  * ----------------------------------------------------------------------------
  *
 /*
  * ----------------------------------------------------------------------------
  *
- * RestoreCursorColor --
+ * pmRestoreCursorColor --
  *
  *     Routine to restore the color of the cursor.
  *
  *
  *     Routine to restore the color of the cursor.
  *
@@ -996,9 +480,9 @@ LoadCursor(cur)
  * ----------------------------------------------------------------------------
  */
 static void
  * ----------------------------------------------------------------------------
  */
 static void
-RestoreCursorColor()
+pmRestoreCursorColor()
 {
 {
-       register VDACRegs *vdac = (VDACRegs *)MACH_COLOR_MAP_ADDR;
+       register VDACRegs *vdac = (VDACRegs *)MACH_PHYS_TO_UNCACHED(KN01_SYS_VDAC);
        register int i;
 
        vdac->overWA = 0x04;
        register int i;
 
        vdac->overWA = 0x04;
@@ -1028,7 +512,7 @@ RestoreCursorColor()
 /*
  * ----------------------------------------------------------------------------
  *
 /*
  * ----------------------------------------------------------------------------
  *
- * CursorColor --
+ * pmCursorColor --
  *
  *     Set the color of the cursor.
  *
  *
  *     Set the color of the cursor.
  *
@@ -1041,7 +525,7 @@ RestoreCursorColor()
  * ----------------------------------------------------------------------------
  */
 static void
  * ----------------------------------------------------------------------------
  */
 static void
-CursorColor(color)
+pmCursorColor(color)
        unsigned int color[];
 {
        register int i, j;
        unsigned int color[];
 {
        register int i, j;
@@ -1052,13 +536,13 @@ CursorColor(color)
        for (i = 3, j = 0; i < 6; i++, j++)
                fg_RGB[j] = (u_char)(color[i] >> 8);
 
        for (i = 3, j = 0; i < 6; i++, j++)
                fg_RGB[j] = (u_char)(color[i] >> 8);
 
-       RestoreCursorColor();
+       pmRestoreCursorColor();
 }
 
 /*
  * ----------------------------------------------------------------------------
  *
 }
 
 /*
  * ----------------------------------------------------------------------------
  *
- * InitColorMap --
+ * pmInitColorMap --
  *
  *     Initialize the color map.
  *
  *
  *     Initialize the color map.
  *
@@ -1072,15 +556,16 @@ CursorColor(color)
  * ----------------------------------------------------------------------------
  */
 static void
  * ----------------------------------------------------------------------------
  */
 static void
-InitColorMap()
+pmInitColorMap()
 {
 {
-       register VDACRegs *vdac = (VDACRegs *)MACH_COLOR_MAP_ADDR;
+       register VDACRegs *vdac = (VDACRegs *)MACH_PHYS_TO_UNCACHED(KN01_SYS_VDAC);
+       struct pmax_fb *fp = &pmfb;
        register int i;
 
        register int i;
 
-       *(char *)MACH_PLANE_MASK_ADDR = 0xff;
+       *(volatile char *)MACH_PHYS_TO_UNCACHED(KN01_PHYS_COLMASK_START) = 0xff;
        MachEmptyWriteBuffer();
 
        MachEmptyWriteBuffer();
 
-       if (isMono) {
+       if (fp->isMono) {
                vdac->mapWA = 0; MachEmptyWriteBuffer();
                for (i = 0; i < 256; i++) {
                        vdac->map = (i < 128) ? 0x00 : 0xff;
                vdac->mapWA = 0; MachEmptyWriteBuffer();
                for (i = 0; i < 256; i++) {
                        vdac->map = (i < 128) ? 0x00 : 0xff;
@@ -1107,13 +592,13 @@ InitColorMap()
                bg_RGB[i] = 0x00;
                fg_RGB[i] = 0xff;
        }
                bg_RGB[i] = 0x00;
                fg_RGB[i] = 0xff;
        }
-       RestoreCursorColor();
+       pmRestoreCursorColor();
 }
 
 /*
  * ----------------------------------------------------------------------------
  *
 }
 
 /*
  * ----------------------------------------------------------------------------
  *
- * VDACInit --
+ * pmVDACInit --
  *
  *     Initialize the VDAC.
  *
  *
  *     Initialize the VDAC.
  *
@@ -1126,9 +611,9 @@ InitColorMap()
  * ----------------------------------------------------------------------------
  */
 static void
  * ----------------------------------------------------------------------------
  */
 static void
-VDACInit()
+pmVDACInit()
 {
 {
-       register VDACRegs *vdac = (VDACRegs *)MACH_COLOR_MAP_ADDR;
+       register VDACRegs *vdac = (VDACRegs *)MACH_PHYS_TO_UNCACHED(KN01_SYS_VDAC);
 
        /*
         *
 
        /*
         *
@@ -1151,7 +636,7 @@ VDACInit()
 /*
  * ----------------------------------------------------------------------------
  *
 /*
  * ----------------------------------------------------------------------------
  *
- * LoadColorMap --
+ * pmLoadColorMap --
  *
  *     Load the color map.
  *
  *
  *     Load the color map.
  *
@@ -1164,10 +649,10 @@ VDACInit()
  * ----------------------------------------------------------------------------
  */
 static void
  * ----------------------------------------------------------------------------
  */
 static void
-LoadColorMap(ptr)
+pmLoadColorMap(ptr)
        ColorMap *ptr;
 {
        ColorMap *ptr;
 {
-       register VDACRegs *vdac = (VDACRegs *)MACH_COLOR_MAP_ADDR;
+       register VDACRegs *vdac = (VDACRegs *)MACH_PHYS_TO_UNCACHED(KN01_SYS_VDAC);
 
        if (ptr->index > 256)
                return;
 
        if (ptr->index > 256)
                return;
@@ -1181,7 +666,7 @@ LoadColorMap(ptr)
 /*
  *----------------------------------------------------------------------
  *
 /*
  *----------------------------------------------------------------------
  *
- * PosCursor --
+ * pmPosCursor --
  *
  *     Postion the cursor.
  *
  *
  *     Postion the cursor.
  *
@@ -1193,19 +678,45 @@ LoadColorMap(ptr)
  *
  *----------------------------------------------------------------------
  */
  *
  *----------------------------------------------------------------------
  */
-static void
-PosCursor(x, y)
+void
+pmPosCursor(x, y)
        register int x, y;
 {
        register int x, y;
 {
-       register PCCRegs *pcc = (PCCRegs *)MACH_CURSOR_REG_ADDR;
-
-       if (y < pmu.scrInfo.min_cur_y || y > pmu.scrInfo.max_cur_y)
-               y = pmu.scrInfo.max_cur_y;
-       if (x < pmu.scrInfo.min_cur_x || x > pmu.scrInfo.max_cur_x)
-               x = pmu.scrInfo.max_cur_x;
-       pmu.scrInfo.cursor.x = x;               /* keep track of real cursor */
-       pmu.scrInfo.cursor.y = y;               /* position, indep. of mouse */
+       register PCCRegs *pcc = (PCCRegs *)MACH_PHYS_TO_UNCACHED(KN01_SYS_PCC);
+       register struct pmax_fb *fp = &pmfb;
+
+       if (y < fp->fbu->scrInfo.min_cur_y || y > fp->fbu->scrInfo.max_cur_y)
+               y = fp->fbu->scrInfo.max_cur_y;
+       if (x < fp->fbu->scrInfo.min_cur_x || x > fp->fbu->scrInfo.max_cur_x)
+               x = fp->fbu->scrInfo.max_cur_x;
+       fp->fbu->scrInfo.cursor.x = x;          /* keep track of real cursor */
+       fp->fbu->scrInfo.cursor.y = y;          /* position, indep. of mouse */
        pcc->xpos = PCC_X_OFFSET + x;
        pcc->ypos = PCC_Y_OFFSET + y;
 }
        pcc->xpos = PCC_X_OFFSET + x;
        pcc->ypos = PCC_Y_OFFSET + y;
 }
-#endif
+
+/*
+ * pm keyboard and mouse input. Just punt to the generic ones in fb.c
+ */
+void
+pmKbdEvent(ch)
+       int ch;
+{
+       fbKbdEvent(ch, &pmfb);
+}
+
+void
+pmMouseEvent(newRepPtr)
+       MouseReport *newRepPtr;
+{
+       fbMouseEvent(newRepPtr, &pmfb);
+}
+
+void
+pmMouseButtons(newRepPtr)
+       MouseReport *newRepPtr;
+{
+       fbMouseButtons(newRepPtr, &pmfb);
+}
+#endif /* NDC */
+#endif /* NPM */
index 1c70921..3aa15c3 100644 (file)
@@ -1,13 +1,13 @@
-/*
- * Copyright (c) 1992 Regents of the University of California.
+/*-
+ * Copyright (c) 1992 The Regents of the University of California.
  * All rights reserved.
  *
  * This code is derived from software contributed to Berkeley by
  * All rights reserved.
  *
  * This code is derived from software contributed to Berkeley by
- * Ralph Campbell.
+ * Ralph Campbell and Rick Macklem.
  *
  * %sccs.include.redist.c%
  *
  *
  * %sccs.include.redist.c%
  *
- *     @(#)sii.c       7.6 (Berkeley) %G%
+ *     @(#)sii.c       7.7 (Berkeley) %G%
  *
  * from: $Header: /sprite/src/kernel/dev/ds3100.md/RCS/devSII.c,
  *     v 9.2 89/09/14 13:37:41 jhh Exp $ SPRITE (DECWRL)";
  *
  * from: $Header: /sprite/src/kernel/dev/ds3100.md/RCS/devSII.c,
  *     v 9.2 89/09/14 13:37:41 jhh Exp $ SPRITE (DECWRL)";
@@ -30,6 +30,8 @@
 #include <pmax/dev/scsi.h>
 #include <pmax/dev/siireg.h>
 
 #include <pmax/dev/scsi.h>
 #include <pmax/dev/siireg.h>
 
+#include <pmax/pmax/kn01.h>
+
 int    siiprobe();
 void   siistart();
 struct driver siidriver = {
 int    siiprobe();
 void   siistart();
 struct driver siidriver = {
@@ -121,15 +123,17 @@ u_char    sii_buf[256];   /* used for extended messages */
 #define WAIT   1
 
 /* define a safe address in the SCSI buffer for doing status & message DMA */
 #define WAIT   1
 
 /* define a safe address in the SCSI buffer for doing status & message DMA */
-#define SII_BUF_ADDR   (MACH_SCSI_BUFFER_ADDR + SII_MAX_DMA_XFER_LENGTH * 14)
-
-extern void sii_Reset();
-extern void sii_StartCmd();
-extern void sii_CmdDone();
-extern void sii_DoIntr();
-extern void sii_StateChg();
-extern void sii_DoSync();
-extern void sii_StartDMA();
+#define SII_BUF_ADDR   (MACH_PHYS_TO_UNCACHED(KN01_SYS_SII_B_START) \
+               + SII_MAX_DMA_XFER_LENGTH * 14)
+
+static void sii_Reset();
+static void sii_StartCmd();
+static void sii_CmdDone();
+static void sii_DoIntr();
+static void sii_StateChg();
+static void sii_DoSync();
+static void sii_StartDMA();
+static int sii_GetByte();
 
 /*
  * Test to see if device is present.
 
 /*
  * Test to see if device is present.
@@ -153,7 +157,8 @@ siiprobe(cp)
         * while we copy the data.
         */
        for (i = 0; i < SII_NCMD; i++) {
         * while we copy the data.
         */
        for (i = 0; i < SII_NCMD; i++) {
-               sc->sc_st[i].dmaAddr[0] = (u_short *)MACH_SCSI_BUFFER_ADDR +
+               sc->sc_st[i].dmaAddr[0] = (u_short *)
+                       MACH_PHYS_TO_UNCACHED(KN01_SYS_SII_B_START) +
                        2 * SII_MAX_DMA_XFER_LENGTH * i;
                sc->sc_st[i].dmaAddr[1] = sc->sc_st[i].dmaAddr[0] +
                        SII_MAX_DMA_XFER_LENGTH;
                        2 * SII_MAX_DMA_XFER_LENGTH * i;
                sc->sc_st[i].dmaAddr[1] = sc->sc_st[i].dmaAddr[0] +
                        SII_MAX_DMA_XFER_LENGTH;