]> pd.if.org Git - mmurtl/commitdiff
autocommit for file dated 1994-12-29 21:58:20
authorRichard Burgess <>
Thu, 29 Dec 1994 21:58:20 +0000 (21:58 +0000)
committerNathan Wagner <nw@hydaspes.if.org>
Mon, 17 Oct 2016 14:03:47 +0000 (14:03 +0000)
ossource/devdrvr.asm [new file with mode: 0644]

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