From: Richard Burgess <> Date: Thu, 29 Dec 1994 21:58:20 +0000 (+0000) Subject: autocommit for file dated 1994-12-29 21:58:20 X-Git-Url: https://pd.if.org/git/?p=mmurtl;a=commitdiff_plain;h=0169ff886d368154414295e1f91db7e179926a5b autocommit for file dated 1994-12-29 21:58:20 --- diff --git a/ossource/devdrvr.asm b/ossource/devdrvr.asm new file mode 100644 index 0000000..23faa3b --- /dev/null +++ b/ossource/devdrvr.asm @@ -0,0 +1,416 @@ +; MMURTL Operating System Source Code +; Copyright 1991,1992,1993,1994 Richard A. Burgess +; ALL RIGHTS RESERVED Version 1.0 +; +.DATA +.INCLUDE MOSEDF.INC +.ALIGN DWORD +;These are the Equates and data are for the device +;driver entry and exit code. + +nDevices EQU 24 ;Number of Device Control Blocks + +;Device Control Block. This structure defines the DCB layout for all +;device drivers. Each driver is responsible for creating and initially +;setting up a DCB prior to calling InitDevDr. The OS maintains an array +;of pointers to the device drivers. The physical device number +;(0-nDevices) is determined by the position in the array. An array +;position that contains a NULL pointer indicates a device is not installed. +;For instance, if the first pointer in the rgpDCBs is NULL, device "0" +;is not available. The DCB also maintains a 12 byte name for the device +;which the installer specifies. A PUBLIC call is provided to translate +;the name to a device number so callers and services can find the +;physical number from the name. +;The name of a device is case aware but NOT case sensitive +; +; The DCB structure layout follows: +; +sDevCB EQU 64 ;size of the Device Control Block + +;Define offsets into structure + +DevName EQU 0 ;DB 12 DUP (0) ;Device Name +sbDevName EQU 12 ;DB 0 ;Length of Devname +DevType EQU 13 ;DB 0 ;1 = RANDOM, 2 = SEQUENTIAL, 0 = No Device +nBPB EQU 14 ;DW 0 ;Bytes per Block (1 to 65535 max) +LastDevErc EQU 16 ;DD 0 ;Last error code from an operation +nDevBlocks EQU 20 ;DD 0 ;Number of blocks in device (0 for sequential) + ;24 +pDevOp EQU 24 ;DD 0 ;Offset to device Operation handler +pDevInit EQU 28 ;DD 0 ;Offset to device Init handler +pDevSt EQU 32 ;DD 0 ;Offset to device Status handler + ;36 +fDevReent EQU 36 ;DB 0 ;Is device handler reentrant? +fSingleUser EQU 37 ;DB 0 ;Is device assignable? +wJob EQU 38 ;DW 0 ;If assignable, is it? (0 for no, else Job Num) +DevSemExch EQU 40 ;DD 0 ;Exch for device semaphore (if not reentrant) +DevSemMsg EQU 44 ;DD 0 ;Msg holder for msg from WAIT on queued Tasks +DevSemMsg1 EQU 48 ;DD 0 ;Msg holder (second DWord) + ;52 + +rgpDCBs DD nDevices DUP (0) ; +rgReDIR DD nDevices DUP (0) ;For redirection of devices + +;Standard Devices are: + +;# Device Standard name + +;0 NULL device NUL (OS built-in) +;1 Keyboard (sequential) KBD (OS built-in, ReadOnly) +;2 Video (sequential) VID (OS built-in, WriteOnly) +;3 Printer (parallel 1) LPT (OS built-in) +;4 Printer (parallel 2) LPT2 (OS built-in) +;5 RS-232 1 COM1 (OS built-in) +;6 RS-232 2 COM2 (OS built-in) +;7 RS-232 3 COM3 (OS built-in) +;8 RS-232 4 COM4 (OS built-in) +;9 +;10 Floppy FD0 (OS built-in) +;11 Floppy FD1 (OS built-in) +;12 Hard disk HD0 (OS built-in) +;13 Hard disk HD1 (OS built-in) +;14 +;15 +;16 +;17 +;18 +;19 +;20 +;21 +;22 +;23 +;------------- End Device Driver Data, Begin Code ----------------- +.CODE +; +; +;InitDevDr is called ONCE by a device driver after loading. pDCBs points to +;an array of DCBs (one for each device the driver handles). The devices +;will be numbered dDevNum, dDevNum+1, etc. +;For example, if the hard disk driver controls two disks it calls it once +;pointing to an array of two DCBs. The DCb must be contiguous in RAM!! +; +; InitDevDr(dDevNum, pDCBs, nDevices, dfReplace):dError +; EBP+24 EBP+20 EBP+16 EBP+12 sParam 16 +; +;Local vars +dDevX EQU DWORD PTR [EBP-4] +prgDevs EQU DWORD PTR [EBP-8] +nDevs EQU DWORD PTR [EBP-12] +dExchTmp EQU DWORD PTR [EBP-16] + +PUBLIC __InitDevDr: + PUSH EBP ; + MOV EBP,ESP ; + SUB ESP, 16 + MOV EAX, [EBP+24] ;Set up local vars + MOV dDevX, EAX + MOV EAX, [EBP+20] + MOV prgDevs, EAX + MOV EAX, [EBP+16] + MOV nDevs, EAX + +InitDev00: + CMP dDevX, nDevices ;Valid DCB num? + JB InitDev01 + MOV EAX, ErcBadDevNum ;Not valid DCB number + JMP InitDevEnd + +InitDev01: ;Now check to see if device is already installed + ;and whether it's to be replaced + + LEA EBX, rgpDCBs ;Point EBX to rgpDCB + MOV EAX, dDevX ;dDevNum + SHL EAX, 2 + ADD EBX, EAX + CMP DWORD PTR [EBX], 0 ;pDCBx = 0 if not used yet + JZ InitDev02 ;Empty, OK to use + CMP DWORD PTR [EBP+12], 0 ;OK to replace existing driver? + JNZ InitDev02 ;Yes + MOV EAX, ErcDCBInUse ;No - error exit + JMP InitDevEnd + +InitDev02: ;If we got here, we can check DCB items then move ptr + + MOV EAX, prgDevs ;EAX points to DCB + CMP BYTE PTR [EAX+sbDevName],12 ;Check Device name size + JA InitDev03 + CMP BYTE PTR [EAX+sbDevName], 0 ;is Devname OK? + JA InitDev04 +InitDev03: + MOV EAX, ErcBadDevName + JMP InitDevEnd + +InitDev04: + ;Now see if there are more devices for this driver + + DEC nDevs ;Decrement nDevices + JZ InitDev05 ;NONE left + ADD prgDevs, 64 ;Next caller DCB + INC dDevX ;Next devnum + JMP SHORT InitDev00 ; + + ;All error checking on DCB(s) should be done at this point + +InitDev05: ;Alloc Exch if driver in NOT reentrant + MOV EBX, [EBP+20] ;pDCBs + CMP BYTE PTR [EBX+fDevReent], 0 + JNZ InitDev06 ;device IS reentrant! + LEA EAX, dExchTmp ;Allocate device Exchange + PUSH EAX ;into temp storage + CALL FWORD PTR _AllocExch + CMP EAX, 0 + JNZ SHORT InitDevEnd + +InitDev06: + ;All went OK so far, now move the DCB pointer(s) into array + ; and assign exchange from temp storage to each DCB + + MOV EAX, [EBP+16] ;nDevices + MOV nDevs, EAX ;Set nDev to number of devices again + LEA EBX, rgpDCBs ;Point EBX to OS rgpDCBs + MOV EAX, [EBP+24] ;dDevNum + SHL EAX, 2 + ADD EBX, EAX ;EBX now points to correct pointer + MOV EAX, [EBP+20] ;EAX points to first DCB + MOV ECX, dExchTmp ;ECX has semaphore exchange +InitDev07: + ;Now that EBX, EAX and ECX are set up, loop through each + ;DCB (if more than 1) and set up OS pointer to it, and + ;also place Exchange into DCB. This is the same exchange + ;for all devices that one driver controls. + + MOV [EAX+DevSemExch], ECX + MOV [EBX], EAX + ADD EBX, 4 ;next p in rgp of DCBs + ADD EAX, 64 ;next DCB + DEC nDevs + JNZ InitDev07 ;Any more DCBs?? + XOR EAX, EAX ;Set up for no error + + ;If the device driver was NOT reentrant + ;we send a semaphore message to the exchange for + ;the first customer to use. + + MOV EBX, [EBP+20] ;pDCBs + CMP BYTE PTR [EBX+fDevReent], 0 + JNZ InitDev06 ;device IS reentrant! + PUSH ECX ;ECX is still the exchange + PUSH 0FFFFFFFEh ;Dummy message + PUSH 0FFFFFFFEh + CALL FWORD PTR _SendMsg ;Let erc in EAX fall through (Was ISend) + +InitDevEnd: + MOV ESP,EBP ; + POP EBP ; + RETF 16 ; +; +;======================================================================= +; Device Driver call for DeviceInit. Some up-front checking is done and +; then this call is forwarded to the destination driver +; +; DeviceInit(dDevNum, pInitData, sdInitData); +; EBP+20 EBP+16 EBP+12 Count = 12 +; +PUBLIC __DeviceInit: ; + PUSH EBP ; + MOV EBP,ESP ; + CMP DWORD PTR [EBP+20], nDevices ;Valid Device number? + JB DevInit01 + MOV EAX, ErcBadDevNum ;Sorry no valid DCB + JMP DevInitEnd +DevInit01: + LEA EAX, rgpDCBs + MOV EBX, [EBP+20] ; + SHL EBX, 2 ; + ADD EAX, EBX ; + MOV EBX, [EAX] ;now EBX points to DCB (maybe) + CMP EBX, 0 ;Is there a pointer to a DCB? + JNZ DevInit1A ;Yes + MOV EAX, ErcNoDriver ;NO driver! + JMP DevInitEnd +DevInit1A: + CMP BYTE PTR [EBX+DevType], 0 ;Is there a physical device? + JNZ DevInit02 + MOV EAX, ErcNoDevice + JMP DevInitEnd + +DevInit02: ;All looks good with device number + ;so we check to see if driver is reentrant. If not we + ;call WAIT to get semaphore ticket... + + CMP BYTE PTR [EBX+fDevReent], 0 + JNZ DevInit03 ;Device IS reentrant + PUSH EBX ;save ptr to DCB + PUSH DWORD PTR [EBX+DevSemExch] ;Push exchange number + LEA EAX, [EBX+DevSemMsg] ;Ptr to message area + PUSH EAX + CALL FWORD PTR _WaitMsg ;Get semaphore ticket + POP EBX ;Get DCB ptr back + CMP EAX, 0 + JNE DevInitEnd ;Serious kernel error! + +DevInit03: + PUSH EBX ;Save ptr to DCB + PUSH DWORD PTR [EBP+20] ;Push all params for call to DD + PUSH DWORD PTR [EBP+16] + PUSH DWORD PTR [EBP+12] + CALL DWORD PTR [EBX+pDevInit] + POP EBX ;Get ptr to DCB back into EBX + PUSH EAX ;save error (if any) + + CMP BYTE PTR [EBX+fDevReent], 0 ;Reentrant? + JNZ DevInit04 ;YES + + PUSH DWORD PTR [EBX+DevSemExch] ;No, Send semaphore message to Exch + PUSH 0FFFFFFFEh ;Bogus Message + PUSH 0FFFFFFFEh ; + CALL FWORD PTR _SendMsg ;Ignore kernel error (unlikely) +DevInit04: + POP EAX ;Get device error back + +DevInitEnd: + MOV ESP,EBP ; + POP EBP ; + RETF 12 ;dump params + + +;======================================================================= +; Device Driver call for DeviceOp. Some up-front checking is done and +; then this call is forwarded to the destination driver +; +; DeviceOp(dDevice, dOpNum, dLBA, dnBlocks, pData); +; EBP+28 EBP+24 EBP+20 EBP+16 EBP+12 Count = 20 +; +PUBLIC __DeviceOp: + PUSH EBP ; + MOV EBP,ESP ; + CMP DWORD PTR [EBP+28], nDevices ;Valid Device number? + JB DevOp01 + MOV EAX, ErcBadDevNum ;Sorry no valid DCB + JMP DevOpEnd +DevOp01: + LEA EAX, rgpDCBs + MOV EBX, [EBP+28] ; + SHL EBX, 2 ; + ADD EAX, EBX ; + MOV EBX, [EAX] ;EBX points to DCB (maybe) + CMP EBX, 0 ;Is there a pointer to a DCB? + JNZ DevOp1A ;Yes + MOV EAX, ErcNoDriver ;NO driver! + JMP DevOpEnd +DevOp1A: + CMP BYTE PTR [EBX+DevType], 0 ;Is it valid Device + JNZ DevOp02 + MOV EAX, ErcNoDevice + JMP DevOpEnd + +DevOp02: ;All looks good with device number + ;so we check to see if driver is reentrant. If not we + ;call WAIT to get semaphore ticket... + + CMP BYTE PTR [EBX+fDevReent], 0 + JNZ DevOp03 ;Device IS reentrant + PUSH EBX ;save ptr to DCB + PUSH DWORD PTR [EBX+DevSemExch] ;Push exchange number + LEA EAX, [EBX+DevSemMsg] ;Ptr to message area + PUSH EAX + CALL FWORD PTR _WaitMsg ;Get semaphore ticket + POP EBX ;Get DCB ptr back + CMP EAX, 0 + JNE DevOpEnd ;Serious kernel error! + +DevOp03: + PUSH EBX ;Save ptr to DCB + PUSH DWORD PTR [EBP+28] ;Push all params for call to DD + PUSH DWORD PTR [EBP+24] ; + PUSH DWORD PTR [EBP+20] + PUSH DWORD PTR [EBP+16] + PUSH DWORD PTR [EBP+12] + CALL DWORD PTR [EBX+pDevOp] + POP EBX ;Get ptr to DCB back into EBX + PUSH EAX ;save error (if any) + + CMP BYTE PTR [EBX+fDevReent], 0 ;Reentrant? + JNZ DevOp04 ;YES + PUSH DWORD PTR [EBX+DevSemExch] ;Send semaphore message to Exch + PUSH 0FFFFFFFEh ;Bogus Message + PUSH 0FFFFFFFEh ; + CALL FWORD PTR _SendMsg ;Ignore kernel error +DevOp04: + POP EAX ;Get device error back + +DevOpEnd: + MOV ESP,EBP ; + POP EBP ; + RETF 20 ;dump params + +;======================================================================= +; Device Driver call for DeviceStat. Some up-front checking is done and +; then this call is forwarded to the destination driver +; +; DeviceStat(dDevNum, pStatRet, dStatMax, pdStatRet); +; EBP+24 EBP+20 EBP+16 EBP+12 Count = 16 +; +PUBLIC __DeviceStat: ; + PUSH EBP ; + MOV EBP,ESP ; + CMP DWORD PTR [EBP+24], nDevices ;Valid Device number? + JB DevStat01 + MOV EAX, ErcBadDevNum ;Sorry no valid DCB + JMP DevStatEnd +DevStat01: + LEA EAX, rgpDCBs ;Ptr to array of ptrs to DCBs + MOV EBX, [EBP+24] ;Device number + SHL EBX, 2 ;Times 4 (index into 4 byte ptrs) + ADD EAX, EBX ;Add em up so EAX points to a pointer! + MOV EBX, [EAX] ;now EBX points to DCB (maybe) + CMP EBX, 0 ;Is there a pointer to a DCB? + JNZ DevStat1A ;Yes + MOV EAX, ErcNoDriver ;NO driver! + JMP DevStatEnd +DevStat1A: + CMP BYTE PTR [EBX+DevType], 0 ;Is it valid Device + JNZ DevStat02 + MOV EAX, ErcNoDevice + JMP DevStatEnd + +DevStat02: ;All looks good with device driver DCB + ;so we check to see if driver is reentrant. If not we + ;call WAIT to get semaphore ticket... + + CMP BYTE PTR [EBX+fDevReent], 0 + JNZ DevStat03 ;Device IS reentrant + PUSH EBX ;save ptr to DCB + PUSH DWORD PTR [EBX+DevSemExch] ;Push exchange number + LEA EAX, [EBX+DevSemMsg] ;Ptr to message area + PUSH EAX + CALL FWORD PTR _WaitMsg ;Get semaphore ticket + POP EBX ;Get DCB ptr back + CMP EAX, 0 + JNE DevStatEnd ;Serious kernel error! + +DevStat03: + PUSH EBX ;Save ptr to DCB + PUSH DWORD PTR [EBP+24] ;Push all params for call to DD + PUSH DWORD PTR [EBP+20] + PUSH DWORD PTR [EBP+16] + PUSH DWORD PTR [EBP+12] + CALL DWORD PTR [EBX+pDevSt] + POP EBX ;Get ptr to DCB back into EBX + PUSH EAX ;save error (if any) + CMP BYTE PTR [EBX+fDevReent], 0 ;Reentrant? + JNZ DevStat04 ;YES + PUSH DWORD PTR [EBX+DevSemExch] ;Send semaphore message to Exch + PUSH 0FFFFFFFEh ;Bogus Message + PUSH 0FFFFFFFEh ;Bogus Message + CALL FWORD PTR _SendMsg ;Ignore kernel error (unlikely) +DevStat04: + POP EAX ;Get device error back + +DevStatEnd: + MOV ESP,EBP ; + POP EBP ; + RETF 16 ;dump params + + +;========= END of MODULE ================