]> pd.if.org Git - mmurtl/blob - ossource/devdrvr.asm
autocommit for file dated 1995-01-04 08:31:30
[mmurtl] / ossource / devdrvr.asm
1 ;   MMURTL Operating System Source Code\r
2 ;   Copyright 1991,1992,1993,1994 Richard A. Burgess\r
3 ;   ALL RIGHTS RESERVED    Version 1.0\r
4 ;\r
5 .DATA\r
6 .INCLUDE MOSEDF.INC\r
7 .ALIGN DWORD\r
8 ;These are the Equates and data are for the device\r
9 ;driver entry and exit code.\r
10 \r
11 nDevices                EQU     24              ;Number of Device Control Blocks\r
12 \r
13 ;Device Control Block.  This structure defines the DCB layout for all\r
14 ;device drivers.  Each driver is responsible for creating and initially\r
15 ;setting up a DCB prior to calling InitDevDr.  The OS maintains an array\r
16 ;of pointers to the device drivers.  The physical device number\r
17 ;(0-nDevices) is determined by the position in the array. An array\r
18 ;position that contains a NULL pointer indicates a device is not installed.\r
19 ;For instance, if the first pointer in the rgpDCBs is NULL, device "0"\r
20 ;is not available. The DCB also maintains a 12 byte name for the device\r
21 ;which the installer specifies.  A PUBLIC call is provided to translate\r
22 ;the name to a device number so callers and services can find the\r
23 ;physical number from the name.\r
24 ;The name of a device is case aware but NOT case sensitive\r
25 ;\r
26 ; The DCB structure layout follows:\r
27 ;\r
28 sDevCB          EQU 64          ;size of the Device Control Block\r
29 \r
30 ;Define offsets into structure\r
31 \r
32 DevName         EQU 0  ;DB 12 DUP (0)   ;Device Name\r
33 sbDevName       EQU 12 ;DB 0            ;Length of Devname\r
34 DevType         EQU 13 ;DB 0            ;1 = RANDOM, 2 = SEQUENTIAL, 0 = No Device\r
35 nBPB            EQU 14 ;DW 0            ;Bytes per Block (1 to 65535 max)\r
36 LastDevErc      EQU 16 ;DD 0            ;Last error code from an operation\r
37 nDevBlocks      EQU 20 ;DD 0            ;Number of blocks in device (0 for sequential)\r
38                         ;24\r
39 pDevOp          EQU 24 ;DD 0            ;Offset to device Operation handler\r
40 pDevInit        EQU 28 ;DD 0            ;Offset to device Init handler\r
41 pDevSt          EQU 32 ;DD 0            ;Offset to device Status handler\r
42                         ;36\r
43 fDevReent       EQU 36 ;DB 0            ;Is device handler reentrant?\r
44 fSingleUser     EQU 37 ;DB 0            ;Is device assignable?\r
45 wJob            EQU 38 ;DW 0            ;If assignable, is it? (0 for no, else Job Num)\r
46 DevSemExch      EQU 40 ;DD 0            ;Exch for device semaphore (if not reentrant)\r
47 DevSemMsg       EQU 44 ;DD 0            ;Msg holder for msg from WAIT on queued Tasks\r
48 DevSemMsg1      EQU 48 ;DD 0            ;Msg holder (second DWord)\r
49                         ;52\r
50 \r
51 rgpDCBs         DD nDevices DUP (0)             ;\r
52 rgReDIR         DD nDevices DUP (0)             ;For redirection of devices\r
53 \r
54 ;Standard Devices are:\r
55 \r
56 ;#              Device                                  Standard name\r
57 \r
58 ;0              NULL device                     NUL             (OS built-in)\r
59 ;1              Keyboard (sequential)   KBD             (OS built-in, ReadOnly)\r
60 ;2              Video (sequential)              VID             (OS built-in, WriteOnly)\r
61 ;3              Printer (parallel 1)    LPT             (OS built-in)\r
62 ;4              Printer (parallel 2)    LPT2    (OS built-in)\r
63 ;5              RS-232 1                                COM1    (OS built-in)\r
64 ;6              RS-232 2                                COM2    (OS built-in)\r
65 ;7              RS-232 3                                COM3    (OS built-in)\r
66 ;8              RS-232 4                                COM4    (OS built-in)\r
67 ;9\r
68 ;10             Floppy                                  FD0     (OS built-in)\r
69 ;11             Floppy                                  FD1     (OS built-in)\r
70 ;12             Hard disk                               HD0     (OS built-in)\r
71 ;13             Hard disk                               HD1     (OS built-in)\r
72 ;14\r
73 ;15\r
74 ;16\r
75 ;17\r
76 ;18\r
77 ;19\r
78 ;20\r
79 ;21\r
80 ;22\r
81 ;23\r
82 ;------------- End Device Driver Data, Begin Code -----------------\r
83 .CODE\r
84 ;\r
85 ;\r
86 ;InitDevDr is called ONCE by a device driver after loading. pDCBs points to\r
87 ;an array of DCBs (one for each device the driver handles).  The devices\r
88 ;will be numbered dDevNum, dDevNum+1, etc.\r
89 ;For example, if the hard disk driver controls two disks it calls it once\r
90 ;pointing to an array of two DCBs. The DCb must be contiguous in RAM!!\r
91 ;\r
92 ;  InitDevDr(dDevNum,  pDCBs,  nDevices, dfReplace):dError\r
93 ;            EBP+24    EBP+20  EBP+16    EBP+12     sParam 16\r
94 ;\r
95 ;Local vars\r
96 dDevX    EQU DWORD PTR [EBP-4]\r
97 prgDevs  EQU DWORD PTR [EBP-8]\r
98 nDevs    EQU DWORD PTR [EBP-12]\r
99 dExchTmp EQU DWORD PTR [EBP-16]\r
100 \r
101 PUBLIC __InitDevDr:\r
102                 PUSH EBP                                ;\r
103                 MOV EBP,ESP                             ;\r
104                 SUB ESP, 16\r
105                 MOV EAX, [EBP+24]                               ;Set up local vars\r
106                 MOV dDevX, EAX\r
107                 MOV EAX, [EBP+20]\r
108                 MOV prgDevs, EAX\r
109                 MOV EAX, [EBP+16]\r
110                 MOV nDevs, EAX\r
111 \r
112 InitDev00:\r
113                 CMP dDevX, nDevices                             ;Valid DCB num?\r
114                 JB InitDev01\r
115                 MOV EAX, ErcBadDevNum                   ;Not valid DCB number\r
116                 JMP InitDevEnd\r
117 \r
118 InitDev01:      ;Now check to see if device is already installed\r
119                 ;and whether it's to be replaced\r
120 \r
121                 LEA EBX, rgpDCBs                                ;Point EBX to rgpDCB\r
122                 MOV EAX, dDevX                                  ;dDevNum\r
123                 SHL EAX, 2\r
124                 ADD EBX, EAX\r
125                 CMP DWORD PTR [EBX], 0                  ;pDCBx = 0 if not used yet\r
126                 JZ InitDev02                                    ;Empty, OK to use\r
127                 CMP DWORD PTR [EBP+12], 0               ;OK to replace existing driver?\r
128                 JNZ InitDev02                                   ;Yes\r
129                 MOV EAX, ErcDCBInUse                    ;No - error exit\r
130                 JMP InitDevEnd\r
131 \r
132 InitDev02:      ;If we got here, we can check DCB items then move ptr\r
133 \r
134                 MOV EAX, prgDevs                                ;EAX points to DCB\r
135                 CMP BYTE PTR [EAX+sbDevName],12 ;Check Device name size\r
136                 JA InitDev03\r
137                 CMP BYTE PTR [EAX+sbDevName], 0 ;is Devname OK?\r
138                 JA InitDev04\r
139 InitDev03:\r
140                 MOV EAX, ErcBadDevName\r
141                 JMP InitDevEnd\r
142 \r
143 InitDev04:\r
144                 ;Now see if there are more devices for this driver\r
145 \r
146                 DEC nDevs                                               ;Decrement nDevices\r
147                 JZ InitDev05                                    ;NONE left\r
148                 ADD prgDevs, 64                                 ;Next caller DCB\r
149                 INC dDevX                                               ;Next devnum\r
150                 JMP SHORT InitDev00                             ;\r
151 \r
152                 ;All error checking on DCB(s) should be done at this point\r
153 \r
154 InitDev05:                                                              ;Alloc Exch if driver in NOT reentrant\r
155                 MOV EBX, [EBP+20]                               ;pDCBs\r
156                 CMP BYTE PTR [EBX+fDevReent], 0\r
157                 JNZ InitDev06                                   ;device IS reentrant!\r
158                 LEA EAX, dExchTmp                               ;Allocate device Exchange\r
159                 PUSH EAX                                                ;into temp storage\r
160                 CALL FWORD PTR _AllocExch\r
161                 CMP EAX, 0\r
162                 JNZ SHORT InitDevEnd\r
163 \r
164 InitDev06:\r
165                 ;All went OK so far, now move the DCB pointer(s) into array\r
166                 ; and assign exchange from temp storage to each DCB\r
167 \r
168                 MOV EAX, [EBP+16]                               ;nDevices\r
169                 MOV nDevs, EAX                                  ;Set nDev to number of devices again\r
170                 LEA EBX, rgpDCBs                                ;Point EBX to OS rgpDCBs\r
171                 MOV EAX, [EBP+24]                               ;dDevNum\r
172                 SHL EAX, 2\r
173                 ADD EBX, EAX                                    ;EBX now points to correct pointer\r
174                 MOV EAX, [EBP+20]                               ;EAX points to first DCB\r
175                 MOV ECX, dExchTmp                               ;ECX has semaphore exchange\r
176 InitDev07:\r
177                 ;Now that EBX, EAX and ECX are set up, loop through each\r
178                 ;DCB (if more than 1) and set up OS pointer to it, and\r
179                 ;also place Exchange into DCB.  This is the same exchange\r
180                 ;for all devices that one driver controls.\r
181 \r
182                 MOV [EAX+DevSemExch], ECX\r
183                 MOV     [EBX], EAX\r
184                 ADD EBX, 4                                              ;next p in rgp of DCBs\r
185                 ADD EAX, 64                                             ;next DCB\r
186                 DEC     nDevs\r
187                 JNZ InitDev07                                   ;Any more DCBs??\r
188                 XOR EAX, EAX                                    ;Set up for no error\r
189 \r
190                 ;If the device driver was NOT reentrant\r
191                 ;we send a semaphore message to the exchange for\r
192                 ;the first customer to use.\r
193 \r
194                 MOV EBX, [EBP+20]                               ;pDCBs\r
195                 CMP BYTE PTR [EBX+fDevReent], 0\r
196                 JNZ InitDev06                                   ;device IS reentrant!\r
197                 PUSH ECX                                                ;ECX is still the exchange\r
198                 PUSH 0FFFFFFFEh                                 ;Dummy message\r
199                 PUSH 0FFFFFFFEh\r
200                 CALL FWORD PTR _SendMsg                 ;Let erc in EAX fall through (Was ISend)\r
201 \r
202 InitDevEnd:\r
203                 MOV ESP,EBP                             ;\r
204                 POP EBP                                 ;\r
205                 RETF 16                                                 ;\r
206 ;\r
207 ;=======================================================================\r
208 ; Device Driver call for DeviceInit.  Some up-front checking is done and\r
209 ; then this call is forwarded to the destination driver\r
210 ;\r
211 ;  DeviceInit(dDevNum, pInitData,  sdInitData);\r
212 ;             EBP+20   EBP+16      EBP+12         Count = 12\r
213 ;\r
214 PUBLIC __DeviceInit:                                    ;\r
215                 PUSH EBP                                ;\r
216                 MOV EBP,ESP                     ;\r
217                 CMP DWORD PTR [EBP+20], nDevices                ;Valid Device number?\r
218                 JB DevInit01\r
219                 MOV EAX, ErcBadDevNum                   ;Sorry no valid DCB\r
220                 JMP DevInitEnd\r
221 DevInit01:\r
222                 LEA EAX, rgpDCBs\r
223                 MOV EBX, [EBP+20]                               ;\r
224                 SHL EBX, 2                                              ;\r
225                 ADD EAX, EBX                                    ;\r
226                 MOV EBX, [EAX]                                  ;now EBX points to DCB (maybe)\r
227                 CMP EBX, 0                                              ;Is there a pointer to a DCB?\r
228                 JNZ DevInit1A                                   ;Yes\r
229                 MOV EAX, ErcNoDriver                    ;NO driver!\r
230                 JMP DevInitEnd\r
231 DevInit1A:\r
232                 CMP BYTE PTR [EBX+DevType], 0   ;Is there a physical device?\r
233                 JNZ DevInit02\r
234                 MOV EAX, ErcNoDevice\r
235                 JMP DevInitEnd\r
236 \r
237 DevInit02:      ;All looks good with device number\r
238                 ;so we check to see if driver is reentrant. If not we\r
239                 ;call WAIT to get semaphore ticket...\r
240 \r
241                 CMP BYTE PTR [EBX+fDevReent], 0\r
242                 JNZ DevInit03                                   ;Device IS reentrant\r
243                 PUSH EBX                                                ;save ptr to DCB\r
244                 PUSH DWORD PTR [EBX+DevSemExch]         ;Push exchange number\r
245                 LEA EAX, [EBX+DevSemMsg]                ;Ptr to message area\r
246                 PUSH EAX\r
247                 CALL FWORD PTR _WaitMsg                 ;Get semaphore ticket\r
248                 POP EBX                                                 ;Get DCB ptr back\r
249                 CMP EAX, 0\r
250                 JNE DevInitEnd                                  ;Serious kernel error!\r
251 \r
252 DevInit03:\r
253                 PUSH EBX                                                ;Save ptr to DCB\r
254                 PUSH DWORD PTR [EBP+20]                 ;Push all params for call to DD\r
255                 PUSH DWORD PTR [EBP+16]\r
256                 PUSH DWORD PTR [EBP+12]\r
257                 CALL DWORD PTR [EBX+pDevInit]\r
258                 POP EBX                                                 ;Get ptr to DCB back into EBX\r
259                 PUSH EAX                                                ;save error (if any)\r
260 \r
261                 CMP BYTE PTR [EBX+fDevReent], 0 ;Reentrant?\r
262                 JNZ DevInit04                                   ;YES\r
263 \r
264                 PUSH DWORD PTR [EBX+DevSemExch]         ;No, Send semaphore message to Exch\r
265                 PUSH 0FFFFFFFEh                                 ;Bogus Message\r
266                 PUSH 0FFFFFFFEh                                 ;\r
267                 CALL FWORD PTR _SendMsg                 ;Ignore kernel error (unlikely)\r
268 DevInit04:\r
269                 POP EAX                                                 ;Get device error back\r
270 \r
271 DevInitEnd:\r
272                 MOV ESP,EBP                             ;\r
273                 POP EBP                                 ;\r
274                 RETF 12                                 ;dump params\r
275 \r
276 \r
277 ;=======================================================================\r
278 ; Device Driver call for DeviceOp.  Some up-front checking is done and\r
279 ; then this call is forwarded to the destination driver\r
280 ;\r
281 ;  DeviceOp(dDevice, dOpNum, dLBA,   dnBlocks, pData);\r
282 ;           EBP+28   EBP+24  EBP+20  EBP+16    EBP+12         Count = 20\r
283 ;\r
284 PUBLIC __DeviceOp:\r
285                 PUSH EBP                        ;\r
286                 MOV EBP,ESP                     ;\r
287                 CMP DWORD PTR [EBP+28], nDevices  ;Valid Device number?\r
288                 JB DevOp01\r
289                 MOV EAX, ErcBadDevNum                   ;Sorry no valid DCB\r
290                 JMP DevOpEnd\r
291 DevOp01:\r
292                 LEA EAX, rgpDCBs\r
293                 MOV EBX, [EBP+28]                               ;\r
294                 SHL EBX, 2                                              ;\r
295                 ADD EAX, EBX                                    ;\r
296                 MOV EBX, [EAX]                                  ;EBX points to DCB (maybe)\r
297                 CMP EBX, 0                                              ;Is there a pointer to a DCB?\r
298                 JNZ DevOp1A                                             ;Yes\r
299                 MOV EAX, ErcNoDriver                    ;NO driver!\r
300                 JMP DevOpEnd\r
301 DevOp1A:\r
302                 CMP BYTE PTR [EBX+DevType], 0   ;Is it valid Device\r
303                 JNZ DevOp02\r
304                 MOV EAX, ErcNoDevice\r
305                 JMP DevOpEnd\r
306 \r
307 DevOp02:        ;All looks good with device number\r
308                         ;so we check to see if driver is reentrant. If not we\r
309                         ;call WAIT to get semaphore ticket...\r
310 \r
311                 CMP BYTE PTR [EBX+fDevReent], 0\r
312                 JNZ DevOp03                                             ;Device IS reentrant\r
313                 PUSH EBX                                                ;save ptr to DCB\r
314                 PUSH DWORD PTR [EBX+DevSemExch] ;Push exchange number\r
315                 LEA EAX, [EBX+DevSemMsg]                ;Ptr to message area\r
316                 PUSH EAX\r
317                 CALL FWORD PTR _WaitMsg                 ;Get semaphore ticket\r
318                 POP EBX                                                 ;Get DCB ptr back\r
319                 CMP EAX, 0\r
320                 JNE DevOpEnd                                    ;Serious kernel error!\r
321 \r
322 DevOp03:\r
323                 PUSH EBX                                                ;Save ptr to DCB\r
324                 PUSH DWORD PTR [EBP+28]                 ;Push all params for call to DD\r
325                 PUSH DWORD PTR [EBP+24]                 ;\r
326                 PUSH DWORD PTR [EBP+20]\r
327                 PUSH DWORD PTR [EBP+16]\r
328                 PUSH DWORD PTR [EBP+12]\r
329                 CALL DWORD PTR [EBX+pDevOp]\r
330                 POP EBX                                                 ;Get ptr to DCB back into EBX\r
331                 PUSH EAX                                                ;save error (if any)\r
332 \r
333                 CMP BYTE PTR [EBX+fDevReent], 0 ;Reentrant?\r
334                 JNZ DevOp04                                             ;YES\r
335                 PUSH DWORD PTR [EBX+DevSemExch] ;Send semaphore message to Exch\r
336                 PUSH 0FFFFFFFEh                                 ;Bogus Message\r
337                 PUSH 0FFFFFFFEh                                 ;\r
338                 CALL FWORD PTR _SendMsg                 ;Ignore kernel error\r
339 DevOp04:\r
340                 POP EAX                                                 ;Get device error back\r
341 \r
342 DevOpEnd:\r
343                 MOV ESP,EBP                             ;\r
344                 POP EBP                                 ;\r
345                 RETF 20                                 ;dump params\r
346 \r
347 ;=======================================================================\r
348 ; Device Driver call for DeviceStat.  Some up-front checking is done and\r
349 ; then this call is forwarded to the destination driver\r
350 ;\r
351 ;  DeviceStat(dDevNum, pStatRet,  dStatMax, pdStatRet);\r
352 ;             EBP+24   EBP+20     EBP+16    EBP+12      Count = 16\r
353 ;\r
354 PUBLIC __DeviceStat:                                    ;\r
355                 PUSH EBP                        ;\r
356                 MOV EBP,ESP                     ;\r
357                 CMP DWORD PTR [EBP+24], nDevices        ;Valid Device number?\r
358                 JB DevStat01\r
359                 MOV EAX, ErcBadDevNum                   ;Sorry no valid DCB\r
360                 JMP DevStatEnd\r
361 DevStat01:\r
362                 LEA EAX, rgpDCBs                                ;Ptr to array of ptrs to DCBs\r
363                 MOV EBX, [EBP+24]                               ;Device number\r
364                 SHL EBX, 2                                              ;Times 4 (index into 4 byte ptrs)\r
365                 ADD EAX, EBX                                    ;Add em up so EAX points to a pointer!\r
366                 MOV EBX, [EAX]                                  ;now EBX points to DCB (maybe)\r
367                 CMP EBX, 0                                              ;Is there a pointer to a DCB?\r
368                 JNZ DevStat1A                                   ;Yes\r
369                 MOV EAX, ErcNoDriver                    ;NO driver!\r
370                 JMP DevStatEnd\r
371 DevStat1A:\r
372                 CMP BYTE PTR [EBX+DevType], 0   ;Is it valid Device\r
373                 JNZ DevStat02\r
374                 MOV EAX, ErcNoDevice\r
375                 JMP DevStatEnd\r
376 \r
377 DevStat02:      ;All looks good with device driver DCB\r
378                 ;so we check to see if driver is reentrant. If not we\r
379                 ;call WAIT to get semaphore ticket...\r
380 \r
381                 CMP BYTE PTR [EBX+fDevReent], 0\r
382                 JNZ DevStat03                                   ;Device IS reentrant\r
383                 PUSH EBX                                                ;save ptr to DCB\r
384                 PUSH DWORD PTR [EBX+DevSemExch] ;Push exchange number\r
385                 LEA EAX, [EBX+DevSemMsg]                ;Ptr to message area\r
386                 PUSH EAX\r
387                 CALL FWORD PTR _WaitMsg                 ;Get semaphore ticket\r
388                 POP EBX                                                 ;Get DCB ptr back\r
389                 CMP EAX, 0\r
390                 JNE DevStatEnd                                  ;Serious kernel error!\r
391 \r
392 DevStat03:\r
393                 PUSH EBX                                                ;Save ptr to DCB\r
394                 PUSH DWORD PTR [EBP+24]                 ;Push all params for call to DD\r
395                 PUSH DWORD PTR [EBP+20]\r
396                 PUSH DWORD PTR [EBP+16]\r
397                 PUSH DWORD PTR [EBP+12]\r
398                 CALL DWORD PTR [EBX+pDevSt]\r
399                 POP EBX                                                 ;Get ptr to DCB back into EBX\r
400                 PUSH EAX                                                ;save error (if any)\r
401                 CMP BYTE PTR [EBX+fDevReent], 0 ;Reentrant?\r
402                 JNZ DevStat04                                   ;YES\r
403                 PUSH DWORD PTR [EBX+DevSemExch] ;Send semaphore message to Exch\r
404                 PUSH 0FFFFFFFEh                                 ;Bogus Message\r
405                 PUSH 0FFFFFFFEh                                 ;Bogus Message\r
406                 CALL FWORD PTR _SendMsg                 ;Ignore kernel error (unlikely)\r
407 DevStat04:\r
408                 POP EAX                                         ;Get device error back\r
409 \r
410 DevStatEnd:\r
411                 MOV ESP,EBP                     ;\r
412                 POP EBP                         ;\r
413                 RETF 16                         ;dump params\r
414 \r
415 \r
416 ;========= END of MODULE ================\r