1 ; MMURTL Operating System Source Code
\r
2 ; Copyright 1991,1992,1993,1994 Richard A. Burgess
\r
3 ; ALL RIGHTS RESERVED Version 1.0
\r
5 ;===============================================
\r
8 ;The following calls are miscellaneous support functions that
\r
9 ;support I/O and high speed string functions on the 80386/486
\r
10 ;processors. They are made accessible via call gates to all
\r
11 ;users (except for the I/O ops which are limited to supervisor
\r
14 ; OutByte(Byte, dPort)
\r
15 ; OutWord(Word,dPort)
\r
16 ; OutWords(dPort,pDataOut,dBytes)
\r
17 ; OutDWord(DWord, dPort)
\r
18 ; InByte(dPort):Byte
\r
19 ; InWord(dPort):Word
\r
20 ; InWords(dPort, pDataIn,dBytes)
\r
21 ; InDWord(dPort):DWord
\r
22 ; ReadCMOS(bAddress):Byte
\r
23 ; CopyData(pSource, pDestination, dBytes)
\r
24 ; CopyDataR(pSource, pDestination, dBytes)
\r
25 ; FillData(pDest, cBytes, bFill)
\r
26 ; CompareNCS(pS1, pS2, dSize) : returned offset or -1
\r
27 ; Compare(pS1, pS2, dSize) : returned offset or -1
\r
29 ;===============================================
\r
30 ; OutByte(Byte, wPort)
\r
31 ; The Byte is sent out the I/O Port specified.
\r
38 MOV DX, WORD PTR [EBP+12]
\r
39 MOV AL, BYTE PTR [EBP+16]
\r
44 ;===============================================
\r
45 ; OutWord(Word, wPort)
\r
46 ; The Word is sent out the I/O Port specified.
\r
53 MOV DX, WORD PTR [EBP+12]
\r
54 MOV AX, WORD PTR [EBP+16]
\r
59 ;===============================================
\r
60 ; OutWords(wPort, pDataOut, dBytes)
\r
61 ; The dBytes/2 are sent out to wPort from the pDataOut address
\r
63 ; pDataOut = [EBP+16]
\r
69 MOV DX, WORD PTR [EBP+20]
\r
70 MOV ESI, DWORD PTR [EBP+16]
\r
71 MOV ECX, DWORD PTR [EBP+12]
\r
72 SHR ECX, 1 ;Make WORDS vice bytes
\r
78 ;===============================================
\r
79 ; OutDWord(DWord, wPort)
\r
80 ; The Word is sent out the I/O Port specified.
\r
87 MOV DX, WORD PTR [EBP+12]
\r
88 MOV EAX, DWORD PTR [EBP+16]
\r
93 ;===============================================
\r
95 ; The Byte is read from the I/O Port specified and returned in AL
\r
101 MOV DX, WORD PTR [EBP+12]
\r
103 AND EAX, 0FFh ;Only get the byte
\r
107 ;===============================================
\r
109 ; The Byte is read from the I/O Port specified and returned in AX
\r
115 MOV DX, WORD PTR [EBP+12]
\r
117 AND EAX, 0FFFFh ;Only get the Word
\r
121 ;===============================================
\r
122 ; InWords(wPort, pDataIn, dBytes)
\r
123 ; The dBytes/2 are read in from wPort to pDataIn
\r
125 ; pDataIn = [EBP+16]
\r
126 ; dBytes = [EBP+12]
\r
128 ; ASSUMES ES == DS !!!! (In MMURTL it always does...)
\r
133 MOV DX, WORD PTR [EBP+20]
\r
134 MOV EDI, DWORD PTR [EBP+16]
\r
135 MOV ECX, DWORD PTR [EBP+12]
\r
136 SHR ECX, 1 ;Make WORDS vice bytes
\r
142 ;===============================================
\r
144 ; The Byte is read from the I/O Port specified and returned in EAX
\r
150 MOV DX, WORD PTR [EBP+12]
\r
155 ;===============================================
\r
156 ; ReadCMOS(wAddress)
\r
157 ; The Byte is read from the CMOS address specified and returned in AL
\r
158 ; wAddress = [EBP+12]
\r
163 MOV AL, BYTE PTR [EBP+12]
\r
177 ;===============================================
\r
179 ; CopyData(pSource, pDestination, dBytes)
\r
181 ; pSource is address of place to copy from,
\r
182 ; pDestination is address of place to copy to,
\r
183 ; and cBytes is number of bytes to copy
\r
185 ; A usefull routine that ALWAYS moves DWORDS
\r
186 ; when possible. We test to see if there is an
\r
187 ; odd byte, if so we move it. Then check for an
\r
188 ; odd word, if there, we move it. Then we move
\r
189 ; the rest with MOVSD (whole DWORDS!).
\r
190 ; WARNING: ASSUMES ES = DS !!!!
\r
191 ; Do NOT use to shift data in an array to the right,
\r
192 ; use CopyDataR instead. CopyData can be used
\r
193 ; to shift data to the left in an array safely.
\r
195 ;pSource [EBP + 20]
\r
199 PUBLIC __CopyData PROC FAR
\r
202 MOV EDI,[EBP+16] ;Load destination address
\r
203 MOV ESI,[EBP+20] ;Load source address
\r
204 MOV ECX,[EBP+12] ;Load count of bytes to move
\r
205 CLD ;Auto incrementing move
\r
206 SHR ECX,1 ;Check odd byte
\r
208 MOVSB ;Handle the odd byte
\r
210 SHR ECX,1 ;Check odd word
\r
212 MOVSW ;Handle the odd word
\r
214 REP MOVSD ;Move all DWORDS that are left
\r
216 RETF 12 ;Pop args off the stack
\r
218 ;===============================================
\r
220 ; CopyDataR(pSource, pDestination, dBytes)
\r
222 ; pSource is begining address of place to copy from,
\r
223 ; pDestination is begining address of place to copy to,
\r
224 ; and cBytes is number of bytes to copy
\r
226 ; Same as CopyData except data is copied from
\r
227 ; the higest addresses of pSource and pDest first.
\r
228 ; (e,g, pSource+dBytes => pDest+dBytes)
\r
229 ; WARNING: ASSUMES ES = DS !!!!
\r
230 ; Do NOT use to shift data in an array to the left,
\r
231 ; use CopyData instead. CopyDataR can be used
\r
232 ; to shift data to the left in an array safely.
\r
234 ;pSource [EBP + 20]
\r
238 PUBLIC __CopyDataR:
\r
241 MOV EDI,[EBP+16] ;Load destination address
\r
242 MOV ESI,[EBP+20] ;Load source address
\r
243 MOV ECX,[EBP+12] ;Load count of bytes to move
\r
244 STD ;Auto Decrement
\r
245 ADD ESI, ECX ;Point to end of strings
\r
247 DEC ESI ;correct addresses after addition
\r
249 SHR ECX,1 ;Check odd byte
\r
251 MOVSB ;Handle the odd byte
\r
253 SHR ECX,1 ;Check odd word
\r
255 MOVSW ;Handle the odd word
\r
257 REP MOVSD ;Move all DWORDS that are left
\r
259 RETF 12 ;Pop args off the stack
\r
261 ;===============================================
\r
263 ; FillData(pDest, cBytes, bFill)
\r
265 ; pDestination is begining address to fill
\r
266 ; cBytes is the size of the fill area
\r
267 ; bFill is the byte value to fill with
\r
269 ; Trys to use DWORDS if it can.
\r
278 MOV AL, BYTE PTR [EBP+12] ;Byte to fill with
\r
279 MOV AH,AL ;Set up to store DWords
\r
283 MOV AL,AH ;Byte is now in all four of EAX
\r
284 MOV EDI, DWORD PTR [EBP+20] ;Load destination address
\r
285 MOV ECX, DWORD PTR [EBP+16] ;Load count of bytes to fill
\r
286 CLD ;Auto-increment
\r
287 SHR ECX,1 ;Check even/odd
\r
289 STOSB ;Handle the odd byte
\r
291 SHR ECX,1 ;Check even/odd
\r
293 STOSW ;Handle the odd word
\r
295 REP STOSD ;Store FillCh in each DWORD
\r
297 RETF 12 ;Pop args off the stack
\r
299 ;===============================================
\r
300 ; This routine does a NON case sensitive comparison of two strings up to
\r
301 ; the length specified.
\r
302 ; It returns -1 (0FFFFFFFFh) if all of the bytes are the same,
\r
303 ; otherwise it returns the offset of the first error.
\r
305 ; CompareNCS(pS1, pS2, dSize) : returned offset or -1
\r
307 ; pS1 & pS2 pointer to strings to compare
\r
308 ; dSize is length to compare out to
\r
310 ; Case is only ignored in the letters of the ASCII alphabet (A-Z).
\r
316 PUBLIC __CompareNCS:
\r
317 PUSH EBP ;Save calling frame
\r
318 MOV EBP,ESP ;Set up my own frame pointer
\r
319 MOV ESI, [EBP+20] ;Load address of String1
\r
320 MOV EDI, [EBP+16] ;Load address of String2
\r
321 MOV ECX, [EBP+12] ;Load count of bytes
\r
322 CLD ;Set auto-increment
\r
324 REP CMPSB ;Compare strings...
\r
325 JZ NCSMatch ;If all bytes ok, .. go for it
\r
327 MOV AL,BYTE PTR [ESI-1] ;Get the p1 byte that failed
\r
328 OR AL,20h ;Force it lower case
\r
329 CMP AL,7Ah ;Greater than Little z ?
\r
330 JG NCSNoGo ;If yes, Not character
\r
331 CMP AL,61h ;Less than little a ?
\r
332 JL NCSNoGo ;If yes, Not character
\r
333 MOV BL,BYTE PTR [EDI-1] ;get the p2 byte that failed
\r
334 OR BL,20h ;Force it lower case
\r
336 JNE NCSNoGo ;Still no match
\r
337 JECXZ SHORT NCSMatch ;ECX=0 no chars left to check
\r
338 JMP SHORT CompNCS1 ;Back to the top
\r
340 MOV EAX, [EBP+12] ;Calc offset of bad byte
\r
341 INC ECX ;Fix CX (DEC after LOOP)
\r
342 SUB EAX,ECX ;Leave in AX for return value
\r
345 MOV EAX, -1 ;Strings match
\r
347 POP EBP ;Restore callers frame ptr
\r
348 RETF 12 ;Pop args off the stack
\r
350 ;===============================================
\r
351 ; This routine does a CASE SENSITIVE comparison of two strings up to
\r
352 ; the length specified.
\r
353 ; It returns -1 (0FFFFFFFFh) if all of the bytes are the same,
\r
354 ; otherwise it returns the offset of the first error.
\r
356 ; Compare(pS1, pS2, dSize) : returned offset or -1
\r
358 ; pDestination is begining address to fill
\r
359 ; cBytes is the size of the fill area
\r
360 ; bFill is the byte value to fill with
\r
367 PUSH EBP ;Save calling frame
\r
368 MOV EBP,ESP ;Set up my own frame pointer
\r
369 MOV ESI, [EBP+20] ;Load address of String1
\r
370 MOV EDI, [EBP+16] ;Load address of String2
\r
371 MOV ECX, [EBP+12] ;Load count of bytes
\r
372 CLD ;Set auto-increment
\r
373 REP CMPSB ;Compare strings...
\r
374 JZ CompMatch ;If all bytes ok, .. go for it
\r
375 MOV EAX, [EBP+12] ;Calc offset of bad byte
\r
376 INC ECX ;Fix CX (DEC after LOOP)
\r
377 SUB EAX,ECX ;Leave in AX for return value
\r
380 MOV EAX, -1 ;Strings match
\r
382 POP EBP ;Restore callers frame ptr
\r
383 RETF 12 ;Pop args off the stack
\r
385 ;=================== Module End ===============================
\r