--- /dev/null
+; MMURTL Operating System Source Code\r
+; Copyright 1991,1992,1993, Richard A. Burgess\r
+; ALL RIGHTS RESERVED\r
+; Version x0.8\r
+\r
+.DATA\r
+.INCLUDE MOSEDF.INC\r
+\r
+;=============================================================================\r
+.CODE\r
+;=============================================================================\r
+;\r
+; GetExchange\r
+;\r
+; This returns the exchange associated with a service name pointed to in EAX.\r
+; It scans the array of servce names and finds a match. ESI pts to the\r
+; SvcDesc if found and EAX has ercOk, else EAX has error code and ESI\r
+; is undefined.\r
+;\r
+; INPUT - EAX = Pointer to the Service Name (8 bytes long)\r
+; OUTPUT - EAX = result code\r
+; ESI = exchange\r
+; USED - EAX, EBX, ESI, EDX, EFlags\r
+;\r
+;=============================================================================\r
+\r
+PUBLIC GetExchange:\r
+ MOV EDX,[EAX] ; First DWORD of the SvcName in EDX\r
+ MOV EBX,[EAX+4] ; Second DWORD of the SvcName in EBX\r
+ MOV ESI,OFFSET rgSVC ; Get the address of rgSVC\r
+ MOV ECX,nSVC ; Get the number of Service Descriptors\r
+GE0000:\r
+ CMP EDX, [ESI] ; Compare first 4 bytes\r
+ JNE SHORT GE0001 ; Not equal.. JUMP\r
+ CMP EBX, [ESI+4] ; Compare first 4 bytes\r
+ JNE SHORT GE0001 ; Not equal.. JUMP\r
+ MOV ESI,[ESI+8] ; Get the Exchange in ESI\r
+ MOV EAX,ercOk ; Set EAX to ercOk\r
+ RETN ; return\r
+GE0001:\r
+ ADD ESI,sSVC ; Move Dest Ptr to Next rgSvc Element\r
+ LOOP GE0000 ; Loop until ECX = 0\r
+ MOV EAX,ErcNoSuchSvc ; set result code\r
+ RETN ; Get out\r
+\r
+;=============================================================================\r
+\r
+FindEmptySVC:\r
+;\r
+; INPUT : NONE\r
+; OUTPUT : EAX,ESI\r
+; REGISTERS : ECX\r
+; MODIFIES : NOTHING\r
+;\r
+; Searches the list of Service Descriptors and returns a ptr to an empty\r
+; Service Descriptor in ESI with ercOk in EAX.\r
+; If an empty Svc Desc in not found, an Error is returned in EAX\r
+; and ESI is undefined. Used by RegisterSvc (below)\r
+;\r
+ MOV ESI, OFFSET rgSVC ; Get address of the Service Descriptor Array\r
+ MOV ECX,nSVC ; Get number of Service Descriptors\r
+ CLI\r
+FELOOP:\r
+ CMP DWORD PTR [ESI],0 ; Is the lower dword empty?\r
+ JNE SHORT FENEXT ; NO\r
+ CMP DWORD PTR [ESI+4],0 ; Is the upper dword empty?\r
+ JNE SHORT FENEXT ; NO\r
+ XOR EAX,EAX ; No Error\r
+ STI\r
+ RETN ;\r
+FENEXT:\r
+ ADD ESI,sSVC ;\r
+ LOOP FELOOP ;\r
+ MOV EAX,ErcOutOfSvcDesc ;\r
+FEEXIT:\r
+ STI\r
+ RETN\r
+\r
+;==============================\r
+\r
+FindMatchSVC:\r
+;\r
+; INPUT : EDX:EBX contains name of service to search for\r
+; OUTPUT : EAX,ESI\r
+; REGISTERS : ECX\r
+; MODIFIES : NOTHING\r
+;\r
+; Searches the list of Service Descriptors and returns a ptr to the match\r
+; in ESI with ercOk in EAX.\r
+; If not found an Error is returned in EAX and ESI is undefined.\r
+; Used by RegisterSvc (below)\r
+;\r
+ MOV ESI, OFFSET rgSVC ; Get address of the Service Desc Array\r
+ MOV ECX,nSVC ; Get number of Service Descriptors\r
+ CLI\r
+FMLOOP:\r
+ CMP [ESI],EDX ; lower dword match?\r
+ JNE SHORT FMNEXT ; NO\r
+ CMP [ESI+4],EBX ; upper dword match?\r
+ JNE SHORT FMNEXT ; NO\r
+ XOR EAX,EAX ; No Error\r
+ STI\r
+ RETN ;\r
+FMNEXT:\r
+ ADD ESI,sSVC ;\r
+ LOOP FMLOOP ;\r
+ MOV EAX, ErcNoSuchSvc ;\r
+FMEXIT:\r
+ STI\r
+ RETN\r
+\r
+;=============================================================================\r
+;\r
+; RegisterSvc - The kernel system service name registery. This procedure will\r
+; identify a particular system service name with a particular exchange.\r
+; The name is an 8 byte (null padded) CASE SENSITIVE string. The name is\r
+; registered with the operating system along with a service exchange. Together\r
+; the information allows the OS to direct requests for system services without\r
+; the originator having to know where the actual exchange is located or on\r
+; what machine the request is being serviced.\r
+;\r
+; A result code in returned in the EAX register.\r
+;\r
+; Procedural Interface :\r
+;\r
+; RegisterName(pName,exch):ercType\r
+;\r
+; pName is a POINTER to the new Service Name\r
+\r
+; exch is a DWORD (4 BYTES) containing the exchange where the\r
+; service will accept messages.\r
+;\r
+pSVCName EQU [EBP+16]\r
+SVCExchange EQU [EBP+12]\r
+\r
+PUBLIC __RegisterSvc:\r
+ PUSH EBP ;\r
+ MOV EBP,ESP ;\r
+ MOV EAX,pSVCName ; in EAX\r
+ MOV EDX,[EAX] ; Get the Name into EDX:EBX for Find call\r
+ MOV EBX,[EAX+4] ;\r
+ CALL FindMatchSVC ; Is it already there? (if so, overwrite)\r
+ CMP EAX,ercOk ; ercOk if it is\r
+ JNE SHORT RSNew ; No, go get an empty one\r
+ JMP SHORT RSFill ; Yes, Overwrite it\r
+RSNew:\r
+ CALL FindEmptySVC ;\r
+ CMP EAX,ercOk ;\r
+ JNE SHORT RSDone ;\r
+RSFill:\r
+ MOV EAX,pSVCName ; pSVCName in EAX\r
+ MOV EDX, [EAX] ; Low DWORD of name into EDX\r
+ MOV [ESI], EDX ; Now into Svc Descriptor\r
+ MOV EBX,[EAX+4] ; Low DWORD of name into EBX\r
+ MOV [ESI+4], EBX ; Now into Svc Descriptor\r
+ MOV ECX,SVCExchange ;\r
+ MOV [ESI+SvcExch],ECX ;\r
+ XOR EAX,EAX ;\r
+RSDone:\r
+ MOV ESP,EBP ;\r
+ POP EBP ;\r
+ RETF 8 ;\r
+\r
+;=============================================================================\r
+;\r
+; UnRegisterSvc - This removes the service name from the name\r
+; name registry. The name must be an exact match for the one\r
+; supplied to RegisterSvc.\r
+; The name is an 8 byte (null padded) CASE SENSITIVE string.\r
+;\r
+; A result code in returned in the EAX register.\r
+;\r
+; Procedural Interface :\r
+;\r
+; UnRegisterName(pName):ercType\r
+;\r
+; pName is a POINTER to the existing Service Name\r
+\r
+; exch is a DWORD (4 BYTES) containing the exchange where the\r
+; service will accept messages.\r
+;\r
+pOldSVCName EQU [EBP+12]\r
+\r
+PUBLIC __UnRegisterSvc:\r
+ PUSH EBP ;\r
+ MOV EBP,ESP ;\r
+ MOV EAX,pOldSVCName ; in EAX\r
+ MOV EDX,[EAX] ; Get the Name into EDX:EBX for Find call\r
+ MOV EBX,[EAX+4] ;\r
+ CALL FindMatchSVC ; Is it already there? (if so, overwrite)\r
+ OR EAX, EAX ; ErcOK?\r
+ JZ SHORT URSKill ; Found it, go kill it\r
+ JMP SHORT URSDone ; ErcNoSuchSvc already in EAX\r
+URSKill:\r
+ XOR EAX, EAX ; Low DWORD of name into EDX\r
+ MOV [ESI], EAX ; Now into Svc Descriptor\r
+ MOV [ESI+4], EAX ; (EAX already zero for ErcOK)\r
+URSDone:\r
+ MOV ESP,EBP ;\r
+ POP EBP ;\r
+ RETF 4 ;\r
+\r
+;=========== End of Module ===================\r