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