|
|
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: qq.c
64: $(CC) $(CFLAGS) -c -o $@ qq.c
65: --------------- cut here -----------------
66:
67: Here is the configuration file for the "qq" driver.
68: Cut it out of this file and copy it to "/usr/sys/confdrv/qq".
69: When "ldconfig" is run, it will create a node for /dev/qq.
70: --------------- cut here -----------------
71: :
72: : 'Dummy driver for write to absolute RAM area'
73: :
74: UNDEF="${UNDEF} -u qqcon_ lib/qq.a"
75: PATCH="${PATCH} drvl_+70=qqcon_"
76: :
77: : devices
78: :
79: umask 0111
80: /etc/mknod -f ${DEV-/dev}/qq c 7 0 || exit 1
81: --------------- cut here -----------------
82: ****/
83: #include "coherent.h"
84: #include "ins8250.h"
85: #include <sys/stat.h>
86: #include <sys/uproc.h>
87: #include <sys/proc.h>
88: #include <sys/con.h>
89: #include <errno.h>
90: #include <sys/types.h>
91: #include <sys/mmu.h>
92:
93: /*
94: * Definitions.
95: *
96: */
97: #define MONOVIDEO 0xB000 /* monochrome text RAM segment */
98: #define VIDLENGTH (2048*2) /* screen locations (2 bytes each) */
99:
100: /*
101: * Export Functions.
102: */
103: int qqload();
104: int qqopen();
105: int qqclose();
106: int qqread();
107: int qqwrite();
108: int qqunload();
109:
110: /*
111: * Import Functions
112: */
113: int nulldev();
114: int nonedev();
115:
116: /*
117: * Configuration table.
118: */
119: CON qqcon ={
120: DFCHR, /* Flags */
121: 7, /* Major index */
122: qqopen, /* Open */
123: qqclose, /* Close */
124: nulldev, /* Block */
125: qqread, /* Read */
126: qqwrite, /* Write */
127: nulldev, /* Ioctl */
128: nulldev, /* Powerfail */
129: nulldev, /* Timeout */
130: qqload, /* Load */
131: qqunload, /* Unload */
132: nulldev /* Poll */
133: };
134:
135: /*
136: * Local variables.
137: */
138: static faddr_t screen_fp; /* (far *) to access screen */
139: static paddr_t screen_base; /* physical address of screen base */
140:
141: /*
142: * Load Routine.
143: */
144: static qqload()
145: {
146: /*
147: * Allocate a selector to map onto the video RAM. ptov() will
148: * return the first available selector of the 8,192 possible.
149: * This is time consuming, so we only want to do this as part
150: * of our initialization code and not on every access.
151: *
152: * Since we are operating in 286 protected mode (ugh), the
153: * second argument to ptov() must not exceed 0x10000L.
154: */
155: screen_base = (paddr_t)((long)(unsigned)MONOVIDEO << 4);
156: screen_fp = ptov(screen_base, (fsize_t)VIDLENGTH);
157: }
158:
159: static qqunload()
160: {
161: /*
162: * We have to free up the selector now that we're done using it.
163: */
164: vrelse(screen_fp);
165: }
166:
167: /*
168: * Open Routine.
169: */
170: qqopen( dev, mode )
171: dev_t dev;
172: {
173: }
174:
175: /*
176: * Close Routine.
177: */
178: qqclose( dev )
179: dev_t dev;
180: {
181: }
182:
183: /*
184: * Read Routine.
185: */
186: qqread( dev, iop )
187: dev_t dev;
188: register IO * iop;
189: {
190: static int offset;
191: int c;
192: /*
193: * Read a character code from video RAM
194: * Start reading RAM just after where previous read ended
195: *
196: * Note that "offset" is the value of the displacement into
197: * the screen RAM. Any expression which results in a value
198: * which is less than VIDLENGTH is OK here.
199: */
200: while(iop->io_ioc) {
201: c = ffbyte(screen_fp + offset); /* fetch a "far" byte */
202: if(ioputc(c, iop) == -1)
203: break;
204: offset += 2;
205: offset %= VIDLENGTH;
206: }
207: }
208:
209: /*
210: * Write Routine.
211: */
212: qqwrite( dev, iop )
213: dev_t dev;
214: register IO * iop;
215: {
216: int offset = 0;
217: int c;
218:
219: /*
220: * Write a character into the screen RAM
221: * Note that "offset" is the value of the displacement into
222: * the screen RAM. Any expression which results in a value
223: * which is less than VIDLENGTH is OK here.
224: */
225: while ((c = iogetc(iop)) >= 0 && offset < VIDLENGTH) {
226: sfbyte(screen_fp + offset, c); /* store a "far" byte */
227: offset += 2; /* skip attribute byte */
228: }
229: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.