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

diff --git a/ossource/misccode.asm b/ossource/misccode.asm
new file mode 100644 (file)
index 0000000..a63a065
--- /dev/null
@@ -0,0 +1,385 @@
+;   MMURTL Operating System Source Code\r
+;   Copyright 1991,1992,1993,1994 Richard A. Burgess\r
+;   ALL RIGHTS RESERVED   Version 1.0\r
+\r
+;===============================================\r
+.CODE\r
+\r
+;The following calls are miscellaneous support functions that\r
+;support I/O and high speed string functions on the 80386/486\r
+;processors. They are made accessible via call gates to all\r
+;users (except for the I/O ops which are limited to supervisor\r
+;level callers).\r
+\r
+; OutByte(Byte, dPort)\r
+; OutWord(Word,dPort)\r
+; OutWords(dPort,pDataOut,dBytes)\r
+; OutDWord(DWord, dPort)\r
+; InByte(dPort):Byte\r
+; InWord(dPort):Word\r
+; InWords(dPort, pDataIn,dBytes)\r
+; InDWord(dPort):DWord\r
+; ReadCMOS(bAddress):Byte\r
+; CopyData(pSource, pDestination, dBytes)\r
+; CopyDataR(pSource, pDestination, dBytes)\r
+; FillData(pDest, cBytes, bFill)\r
+; CompareNCS(pS1, pS2, dSize) : returned offset or -1\r
+; Compare(pS1, pS2, dSize) : returned offset or -1\r
+\r
+;===============================================\r
+; OutByte(Byte, wPort)\r
+; The Byte is sent out the I/O Port specified.\r
+; Byte  = [EBP+16]\r
+; wPort = [EBP+12]\r
+;\r
+PUBLIC __OutByte:\r
+               PUSH EBP\r
+               MOV EBP, ESP\r
+               MOV DX, WORD PTR [EBP+12]\r
+               MOV AL, BYTE PTR [EBP+16]\r
+               OUT DX, AL\r
+               POP EBP\r
+               RETF 8                  ;\r
+;\r
+;===============================================\r
+; OutWord(Word, wPort)\r
+; The Word is sent out the I/O Port specified.\r
+; Word  = [EBP+16]\r
+; wPort = [EBP+12]\r
+;\r
+PUBLIC __OutWord:\r
+               PUSH EBP\r
+               MOV EBP, ESP\r
+               MOV DX, WORD PTR [EBP+12]\r
+               MOV AX, WORD PTR [EBP+16]\r
+               OUT DX, AX\r
+               POP EBP\r
+               RETF 8                  ;\r
+\r
+;===============================================\r
+; OutWords(wPort, pDataOut, dBytes)\r
+; The dBytes/2 are sent out to wPort from the pDataOut address\r
+; wPort    = [EBP+20]\r
+; pDataOut = [EBP+16]\r
+; dBytes   = [EBP+12]\r
+;\r
+PUBLIC __OutWords:\r
+               PUSH EBP\r
+               MOV EBP, ESP\r
+               MOV DX, WORD PTR [EBP+20]\r
+               MOV ESI, DWORD PTR [EBP+16]\r
+               MOV ECX, DWORD PTR [EBP+12]\r
+               SHR ECX, 1                                      ;Make WORDS vice bytes\r
+               CLD\r
+               REP OUTSW\r
+               POP EBP\r
+               RETF 12                  ;\r
+;\r
+;===============================================\r
+; OutDWord(DWord, wPort)\r
+; The Word is sent out the I/O Port specified.\r
+; DWord  = [EBP+16]\r
+; wPort  = [EBP+12]\r
+;\r
+PUBLIC __OutDWord:\r
+               PUSH EBP\r
+               MOV EBP, ESP\r
+               MOV DX, WORD PTR [EBP+12]\r
+               MOV EAX, DWORD PTR [EBP+16]\r
+               OUT DX, EAX\r
+               POP EBP\r
+               RETF 8                  ;\r
+;\r
+;===============================================\r
+; InByte(wPort)\r
+; The Byte is read from the I/O Port specified and returned in AL\r
+; wPort = [EBP+12]\r
+;\r
+PUBLIC __InByte:\r
+               PUSH EBP\r
+               MOV EBP, ESP\r
+               MOV DX, WORD PTR [EBP+12]\r
+               IN AL, DX\r
+               AND EAX, 0FFh                   ;Only get the byte\r
+               POP EBP\r
+               RETF 4                  ;\r
+;\r
+;===============================================\r
+; InWord(wPort)\r
+; The Byte is read from the I/O Port specified and returned in AX\r
+; wPort = [EBP+12]\r
+;\r
+PUBLIC __InWord:\r
+               PUSH EBP\r
+               MOV EBP, ESP\r
+               MOV DX, WORD PTR [EBP+12]\r
+               IN AX, DX\r
+               AND EAX, 0FFFFh                 ;Only get the Word\r
+               POP EBP\r
+               RETF 4                  ;\r
+;\r
+;===============================================\r
+; InWords(wPort, pDataIn, dBytes)\r
+; The dBytes/2 are read in from wPort to pDataIn\r
+; wPort    = [EBP+20]\r
+; pDataIn  = [EBP+16]\r
+; dBytes   = [EBP+12]\r
+;\r
+; ASSUMES ES == DS !!!! (In MMURTL it always does...)\r
+;\r
+PUBLIC __InWords:\r
+               PUSH EBP\r
+               MOV EBP, ESP\r
+               MOV DX, WORD PTR [EBP+20]\r
+               MOV EDI, DWORD PTR [EBP+16]\r
+               MOV ECX, DWORD PTR [EBP+12]\r
+               SHR ECX, 1                                      ;Make WORDS vice bytes\r
+               CLD\r
+               REP INSW\r
+               POP EBP\r
+               RETF 12                  ;\r
+;\r
+;===============================================\r
+; InDWord(wPort)\r
+; The Byte is read from the I/O Port specified and returned in EAX\r
+; wPort = [EBP+12]\r
+;\r
+PUBLIC __InDWord:\r
+               PUSH EBP\r
+               MOV EBP, ESP\r
+               MOV DX, WORD PTR [EBP+12]\r
+               IN EAX, DX\r
+               POP EBP\r
+               RETF 4                  ;\r
+\r
+;===============================================\r
+; ReadCMOS(wAddress)\r
+; The Byte is read from the CMOS address specified and returned in AL\r
+; wAddress = [EBP+12]\r
+;\r
+PUBLIC __ReadCMOS:\r
+               PUSH EBP\r
+               MOV EBP, ESP\r
+               MOV AL, BYTE PTR [EBP+12]\r
+               OR AL, 80h\r
+               CLI\r
+               OUT 70h,AL\r
+               NOP\r
+               NOP\r
+               NOP\r
+               NOP\r
+               IN AL, 71h\r
+               STI\r
+               AND EAX, 0FFh\r
+               POP EBP\r
+               RETF 4                  ;\r
+\r
+;===============================================\r
+;\r
+; CopyData(pSource, pDestination, dBytes)\r
+;\r
+; pSource is address of place to copy from,\r
+; pDestination is address of place to copy to,\r
+; and cBytes is number of bytes to copy\r
+;\r
+; A usefull routine that ALWAYS moves DWORDS\r
+; when possible. We test to see if there is an\r
+; odd byte, if so we move it. Then check for an\r
+; odd word, if there, we move it. Then we move\r
+; the rest with MOVSD (whole DWORDS!).\r
+; WARNING: ASSUMES ES = DS  !!!!\r
+; Do NOT use to shift data in an array to the right,\r
+; use CopyDataR instead.  CopyData can be used\r
+; to shift data to the left in an array safely.\r
+;\r
+;pSource       [EBP + 20]\r
+;pDest         [EBP + 16]\r
+;cBytes                [EBP + 12]\r
+;\r
+PUBLIC __CopyData      PROC    FAR\r
+               PUSH EBP\r
+               MOV EBP,ESP\r
+               MOV EDI,[EBP+16]                ;Load destination address\r
+               MOV ESI,[EBP+20]                ;Load source address\r
+               MOV ECX,[EBP+12]                ;Load count of bytes to move\r
+               CLD                                             ;Auto incrementing move\r
+               SHR ECX,1                               ;Check odd byte\r
+               JNC NoByteC\r
+               MOVSB                                   ;Handle the odd byte\r
+NoByteC:\r
+               SHR ECX,1                               ;Check odd word\r
+               JNC NoWordC\r
+               MOVSW                                   ;Handle the odd word\r
+NoWordC:\r
+               REP MOVSD                               ;Move all DWORDS that are left\r
+               POP EBP\r
+               RETF 12                                 ;Pop args off the stack\r
+\r
+;===============================================\r
+;\r
+; CopyDataR(pSource, pDestination, dBytes)\r
+;\r
+; pSource is begining address of place to copy from,\r
+; pDestination is begining address of place to copy to,\r
+; and cBytes is number of bytes to copy\r
+;\r
+; Same as CopyData except data is copied from\r
+; the higest addresses of pSource and pDest first.\r
+; (e,g, pSource+dBytes => pDest+dBytes)\r
+; WARNING: ASSUMES ES = DS  !!!!\r
+; Do NOT use to shift data in an array to the left,\r
+; use CopyData instead.  CopyDataR can be used\r
+; to shift data to the left in an array safely.\r
+;\r
+;pSource       [EBP + 20]\r
+;pDest         [EBP + 16]\r
+;cBytes                [EBP + 12]\r
+;\r
+PUBLIC __CopyDataR:\r
+               PUSH EBP\r
+               MOV EBP,ESP\r
+               MOV EDI,[EBP+16]                ;Load destination address\r
+               MOV ESI,[EBP+20]                ;Load source address\r
+               MOV ECX,[EBP+12]                ;Load count of bytes to move\r
+               STD                                             ;Auto Decrement\r
+               ADD ESI, ECX                    ;Point to end of strings\r
+               ADD EDI, ECX\r
+               DEC ESI                                 ;correct addresses after addition\r
+               DEC EDI\r
+               SHR ECX,1                               ;Check odd byte\r
+               JNC NoByteR\r
+               MOVSB                                   ;Handle the odd byte\r
+NoByteR:\r
+               SHR ECX,1                               ;Check odd word\r
+               JNC NoWordC\r
+               MOVSW                                   ;Handle the odd word\r
+NoWordR:\r
+               REP MOVSD                               ;Move all DWORDS that are left\r
+               POP EBP\r
+               RETF 12                                 ;Pop args off the stack\r
+\r
+;===============================================\r
+;\r
+; FillData(pDest, cBytes, bFill)\r
+;\r
+; pDestination is begining address to fill\r
+; cBytes is the size of the fill area\r
+; bFill is the byte value to fill with\r
+;\r
+; Trys to use DWORDS if it can.\r
+;\r
+;pDest         [EBP + 20]\r
+;cBytes                [EBP + 16]\r
+;bFill         [EBP + 12]\r
+;\r
+PUBLIC __FillData:\r
+               PUSH EBP\r
+               MOV     EBP,ESP\r
+               MOV     AL, BYTE PTR [EBP+12]   ;Byte to fill with\r
+               MOV     AH,AL                                   ;Set up to store DWords\r
+               SHL EAX,8\r
+               MOV AL,AH\r
+               SHL EAX,8\r
+               MOV AL,AH                                       ;Byte is now in all four of EAX\r
+               MOV EDI, DWORD PTR [EBP+20]     ;Load destination address\r
+               MOV     ECX, DWORD PTR [EBP+16] ;Load count of bytes to fill\r
+               CLD                                                     ;Auto-increment\r
+               SHR     ECX,1                                   ;Check even/odd\r
+               JNC NoByteF\r
+               STOSB                                           ;Handle the odd byte\r
+NoByteF:\r
+               SHR     ECX,1                                   ;Check even/odd\r
+               JNC NoWordF\r
+               STOSW                                           ;Handle the odd word\r
+NoWordF:\r
+               REP     STOSD                                   ;Store FillCh in each DWORD\r
+               POP     EBP\r
+               RETF 12                                         ;Pop args off the stack\r
+\r
+;===============================================\r
+; This routine does a NON case sensitive comparison of two strings up to\r
+; the length specified.\r
+; It returns -1 (0FFFFFFFFh) if all of the bytes are the same,\r
+; otherwise it returns the offset of the first error.\r
+;\r
+; CompareNCS(pS1, pS2, dSize) :        returned offset or -1\r
+;\r
+; pS1 & pS2 pointer to strings to compare\r
+; dSize is length to compare out to\r
+;\r
+; Case is only ignored in the letters of the ASCII alphabet (A-Z).\r
+;\r
+; pS1   [EBP+20]\r
+; pS2   [EBP+16]\r
+; dSize [EBP+12]\r
+;\r
+PUBLIC __CompareNCS:\r
+               PUSH EBP                                        ;Save calling frame\r
+               MOV     EBP,ESP                                 ;Set up my own frame pointer\r
+               MOV ESI, [EBP+20]                       ;Load address of String1\r
+               MOV EDI, [EBP+16]                       ;Load address of String2\r
+               MOV     ECX, [EBP+12]                   ;Load count of bytes\r
+               CLD                                                     ;Set auto-increment\r
+CompNCS1:\r
+               REP     CMPSB                                   ;Compare strings...\r
+               JZ NCSMatch                                     ;If all bytes ok, .. go for it\r
+NCSCase:\r
+               MOV     AL,BYTE PTR [ESI-1]             ;Get the p1 byte that failed\r
+               OR      AL,20h                                  ;Force it lower case\r
+               CMP     AL,7Ah                                  ;Greater than Little z ?\r
+               JG NCSNoGo                                              ;If yes, Not character\r
+               CMP     AL,61h                                  ;Less than little a ?\r
+               JL NCSNoGo                                      ;If yes, Not character\r
+               MOV BL,BYTE PTR [EDI-1]         ;get the p2 byte that failed\r
+               OR BL,20h                                       ;Force it lower case\r
+               CMP AL,BL\r
+               JNE NCSNoGo                     ;Still no match\r
+               JECXZ SHORT NCSMatch            ;ECX=0 no chars left to check\r
+               JMP SHORT CompNCS1                      ;Back to the top\r
+NCSNoGo:\r
+               MOV EAX, [EBP+12]                       ;Calc offset of bad byte\r
+               INC ECX                                         ;Fix CX (DEC after LOOP)\r
+               SUB EAX,ECX                                     ;Leave in AX for return value\r
+               JMP SHORT NCSDone\r
+NCSMatch:\r
+               MOV     EAX, -1                                 ;Strings match\r
+NCSDone:\r
+               POP     EBP                                             ;Restore callers frame ptr\r
+               RETF 12                                         ;Pop args off the stack\r
+\r
+;===============================================\r
+; This routine does a CASE SENSITIVE comparison of two strings up to\r
+; the length specified.\r
+; It returns -1 (0FFFFFFFFh) if all of the bytes are the same,\r
+; otherwise it returns the offset of the first error.\r
+;\r
+; Compare(pS1, pS2, dSize) : returned offset or -1\r
+;\r
+; pDestination is begining address to fill\r
+; cBytes is the size of the fill area\r
+; bFill is the byte value to fill with\r
+;\r
+; pS1   [EBP+20]\r
+; pS2   [EBP+16]\r
+; dSize [EBP+12]\r
+;\r
+PUBLIC __Compare:\r
+               PUSH EBP                                        ;Save calling frame\r
+               MOV     EBP,ESP                                 ;Set up my own frame pointer\r
+               MOV ESI, [EBP+20]                       ;Load address of String1\r
+               MOV EDI, [EBP+16]                       ;Load address of String2\r
+               MOV     ECX, [EBP+12]                   ;Load count of bytes\r
+               CLD                                                     ;Set auto-increment\r
+               REP     CMPSB                                   ;Compare strings...\r
+               JZ CompMatch                            ;If all bytes ok, .. go for it\r
+               MOV EAX, [EBP+12]                       ;Calc offset of bad byte\r
+               INC ECX                                         ;Fix CX (DEC after LOOP)\r
+               SUB EAX,ECX                                     ;Leave in AX for return value\r
+               JMP SHORT CompDone\r
+CompMatch:\r
+               MOV     EAX, -1                                 ;Strings match\r
+CompDone:\r
+               POP     EBP                                             ;Restore callers frame ptr\r
+               RETF 12                                         ;Pop args off the stack\r
+\r
+;===================  Module End  ===============================\r