|
|
1.1 root 1: /*
2: * qq - sample device driver using absolute memory addressing
3: *
4: * All this device does is read/write video ram.
5: * It assumes that there is a monochrome adapter in use, so that video
6: * ram starts at segment B000; if color, this should be changed to B800.
7: *
8: * This driver does not do anything useful; it is intended to serve as
9: * an example.
10: *
11: * Here is how to make the driver and test it (you will need a COHERENT
12: * Driver Kit installed on your system):
13: * 1. put this file, "qq.c", in /usr/src/sys/i8086/drv/qq.c
14: * 2. cut out the make file and store it in /usr/src/sys/i8086/drv/Mf.qq
15: * 3. cut out the config file and store it at /usr/sys/confdrv/qq
16: * 4. execute the following commands
17: * cd /usr/src/sys/i8086/drv
18: * make -f Mf.qq
19: * cd /usr/sys
20: * ldconfig qq
21: * drvld ldrv/qq
22: * 5. the driver should now be loaded - try "date > /dev/qq" or
23: * "cat < /dev/qq" (you will have to use Ctrl-C to stop the "cat"
24: * command)
25: * 6. to unload the driver, do "ps -d" to get the PID number for the driver;
26: * then do "kill kill nnn" where nnn is the process number for "<qq>"
27: */
28: /****
29: Here is the makefile for the "qq" driver (cut it out of this file):
30: --------------- cut here -----------------
31: # Make file for a loadable driver
32:
33: AS=exec /bin/as
34: CC=exec /bin/cc
35: CPP=exec /lib/cpp
36: CFLAGS=-I.. -I../sys -I../.. -I../../sys \
37: -I/usr/include/sys
38: AFLAGS=-gx
39:
40: # Include directories
41: USRINC=/usr/include
42: SYSINC=/usr/include/sys
43: KERINC=/usr/src/sys/sys
44: DRVINC=/usr/src/sys/i8086/sys
45: USRSYS=/usr/sys
46:
47: DRVOBJ= objects/qq.o
48:
49: qq: objects/qq.o
50: rm -f $(USRSYS)/lib/qq.a
51: ar rc $(USRSYS)/lib/qq.a objects/qq.o
52:
53: objects/qq.o: \
54: $(KERINC)/coherent.h $(SYSINC)/types.h \
55: $(SYSINC)/machine.h $(SYSINC)/param.h \
56: $(SYSINC)/fun.h \
57: $(SYSINC)/con.h \
58: $(USRINC)/errno.h \
59: $(SYSINC)/sched.h \
60: $(SYSINC)/seg.h \
61: $(SYSINC)/stat.h \
62: $(SYSINC)/types.h \
63: $(SYSINC)/uproc.h \
64: qq.c
65: $(CC) $(CFLAGS) -c -o $@ qq.c
66: --------------- cut here -----------------
67:
68: Here is the configuration file for the "qq" driver.
69: Cut it out of this file and copy it to "/usr/sys/confdrv/qq".
70: When "ldconfig" is run, it will create a node for /dev/qq.
71: --------------- cut here -----------------
72: :
73: : 'Dummy driver for write to absolute RAM area'
74: :
75: UNDEF="${UNDEF} -u qqcon_ lib/qq.a"
76: PATCH="${PATCH} drvl_+70=qqcon_"
77: :
78: : devices
79: :
80: umask 0111
81: /etc/mknod -f ${DEV-/dev}/qq c 7 0 || exit 1
82: --------------- cut here -----------------
83: ****/
84: #include "coherent.h"
85: #include "ins8250.h"
86: #include <sys/stat.h>
87: #include <sys/uproc.h>
88: #include <sys/proc.h>
89: #include <sys/con.h>
90: #include <errno.h>
91: #include <sys/types.h>
92: #include <sys/mmu.h>
93:
94: /*
95: * Definitions.
96: *
97: */
98: #define MONOVIDEO 0xB000 /* monochrome text RAM segment */
99: #define VIDLENGTH (2048*2) /* screen locations (2 bytes each) */
100:
101: /*
102: * Export Functions.
103: */
104: int qqload();
105: int qqopen();
106: int qqclose();
107: int qqread();
108: int qqwrite();
109: int qqunload();
110:
111: /*
112: * Import Functions
113: */
114: int nulldev();
115: int nonedev();
116:
117: /*
118: * Configuration table.
119: */
120: CON qqcon ={
121: DFCHR, /* Flags */
122: 7, /* Major index */
123: qqopen, /* Open */
124: qqclose, /* Close */
125: nulldev, /* Block */
126: qqread, /* Read */
127: qqwrite, /* Write */
128: nulldev, /* Ioctl */
129: nulldev, /* Powerfail */
130: nulldev, /* Timeout */
131: qqload, /* Load */
132: qqunload, /* Unload */
133: nulldev /* Poll */
134: };
135:
136: /*
137: * Local variables.
138: */
139: static faddr_t screen_fp; /* (far *) to access screen */
140: static paddr_t screen_base; /* physical address of screen base */
141:
142: /*
143: * Load Routine.
144: */
145: static qqload()
146: {
147: /*
148: * Allocate a selector to map onto the video RAM. ptov() will
149: * return the first available selector of the 8,192 possible.
150: * This is time consuming, so we only want to do this as part
151: * of our initialization code and not on every access.
152: *
153: * Since we are operating in 286 protected mode (ugh), the
154: * second argument to ptov() must not exceed 0x10000L.
155: */
156: screen_base = (paddr_t)((long)(unsigned)MONOVIDEO << 4);
157: screen_fp = ptov(screen_base, (fsize_t)VIDLENGTH);
158: }
159:
160: static qqunload()
161: {
162: /*
163: * We have to free up the selector now that we're done using it.
164: */
165: vrelse(screen_fp);
166: }
167:
168: /*
169: * Open Routine.
170: */
171: qqopen( dev, mode )
172: dev_t dev;
173: {
174: }
175:
176: /*
177: * Close Routine.
178: */
179: qqclose( dev )
180: dev_t dev;
181: {
182: }
183:
184: /*
185: * Read Routine.
186: */
187: qqread( dev, iop )
188: dev_t dev;
189: register IO * iop;
190: {
191: static int offset;
192: int c;
193: /*
194: * Read a character code from video RAM
195: * Start reading RAM just after where previous read ended
196: *
197: * Note that "offset" is the value of the displacement into
198: * the screen RAM. Any expression which results in a value
199: * which is less than VIDLENGTH is OK here.
200: */
201: while(iop->io_ioc) {
202: c = ffbyte(screen_fp + offset); /* fetch a "far" byte */
203: if(ioputc(c, iop) == -1)
204: break;
205: offset += 2;
206: offset %= VIDLENGTH;
207: }
208: }
209:
210: /*
211: * Write Routine.
212: */
213: qqwrite( dev, iop )
214: dev_t dev;
215: register IO * iop;
216: {
217: int offset = 0;
218: int c;
219:
220: /*
221: * Write a character into the screen RAM
222: * Note that "offset" is the value of the displacement into
223: * the screen RAM. Any expression which results in a value
224: * which is less than VIDLENGTH is OK here.
225: */
226: while ((c = iogetc(iop)) >= 0 && offset < VIDLENGTH) {
227: sfbyte(screen_fp + offset, c); /* store a "far" byte */
228: offset += 2; /* skip attribute byte */
229: }
230: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.