]> pd.if.org Git - mmurtl/blob - ossource/misccode.asm
autocommit for file dated 2003-12-29 17:36:54
[mmurtl] / ossource / misccode.asm
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
4 \r
5 ;===============================================\r
6 .CODE\r
7 \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
12 ;level callers).\r
13 \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
28 \r
29 ;===============================================\r
30 ; OutByte(Byte, wPort)\r
31 ; The Byte is sent out the I/O Port specified.\r
32 ; Byte  = [EBP+16]\r
33 ; wPort = [EBP+12]\r
34 ;\r
35 PUBLIC __OutByte:\r
36                 PUSH EBP\r
37                 MOV EBP, ESP\r
38                 MOV DX, WORD PTR [EBP+12]\r
39                 MOV AL, BYTE PTR [EBP+16]\r
40                 OUT DX, AL\r
41                 POP EBP\r
42                 RETF 8                  ;\r
43 ;\r
44 ;===============================================\r
45 ; OutWord(Word, wPort)\r
46 ; The Word is sent out the I/O Port specified.\r
47 ; Word  = [EBP+16]\r
48 ; wPort = [EBP+12]\r
49 ;\r
50 PUBLIC __OutWord:\r
51                 PUSH EBP\r
52                 MOV EBP, ESP\r
53                 MOV DX, WORD PTR [EBP+12]\r
54                 MOV AX, WORD PTR [EBP+16]\r
55                 OUT DX, AX\r
56                 POP EBP\r
57                 RETF 8                  ;\r
58 \r
59 ;===============================================\r
60 ; OutWords(wPort, pDataOut, dBytes)\r
61 ; The dBytes/2 are sent out to wPort from the pDataOut address\r
62 ; wPort    = [EBP+20]\r
63 ; pDataOut = [EBP+16]\r
64 ; dBytes   = [EBP+12]\r
65 ;\r
66 PUBLIC __OutWords:\r
67                 PUSH EBP\r
68                 MOV EBP, ESP\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
73                 CLD\r
74                 REP OUTSW\r
75                 POP EBP\r
76                 RETF 12                  ;\r
77 ;\r
78 ;===============================================\r
79 ; OutDWord(DWord, wPort)\r
80 ; The Word is sent out the I/O Port specified.\r
81 ; DWord  = [EBP+16]\r
82 ; wPort  = [EBP+12]\r
83 ;\r
84 PUBLIC __OutDWord:\r
85                 PUSH EBP\r
86                 MOV EBP, ESP\r
87                 MOV DX, WORD PTR [EBP+12]\r
88                 MOV EAX, DWORD PTR [EBP+16]\r
89                 OUT DX, EAX\r
90                 POP EBP\r
91                 RETF 8                  ;\r
92 ;\r
93 ;===============================================\r
94 ; InByte(wPort)\r
95 ; The Byte is read from the I/O Port specified and returned in AL\r
96 ; wPort = [EBP+12]\r
97 ;\r
98 PUBLIC __InByte:\r
99                 PUSH EBP\r
100                 MOV EBP, ESP\r
101                 MOV DX, WORD PTR [EBP+12]\r
102                 IN AL, DX\r
103                 AND EAX, 0FFh                   ;Only get the byte\r
104                 POP EBP\r
105                 RETF 4                  ;\r
106 ;\r
107 ;===============================================\r
108 ; InWord(wPort)\r
109 ; The Byte is read from the I/O Port specified and returned in AX\r
110 ; wPort = [EBP+12]\r
111 ;\r
112 PUBLIC __InWord:\r
113                 PUSH EBP\r
114                 MOV EBP, ESP\r
115                 MOV DX, WORD PTR [EBP+12]\r
116                 IN AX, DX\r
117                 AND EAX, 0FFFFh                 ;Only get the Word\r
118                 POP EBP\r
119                 RETF 4                  ;\r
120 ;\r
121 ;===============================================\r
122 ; InWords(wPort, pDataIn, dBytes)\r
123 ; The dBytes/2 are read in from wPort to pDataIn\r
124 ; wPort    = [EBP+20]\r
125 ; pDataIn  = [EBP+16]\r
126 ; dBytes   = [EBP+12]\r
127 ;\r
128 ; ASSUMES ES == DS !!!! (In MMURTL it always does...)\r
129 ;\r
130 PUBLIC __InWords:\r
131                 PUSH EBP\r
132                 MOV EBP, ESP\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
137                 CLD\r
138                 REP INSW\r
139                 POP EBP\r
140                 RETF 12                  ;\r
141 ;\r
142 ;===============================================\r
143 ; InDWord(wPort)\r
144 ; The Byte is read from the I/O Port specified and returned in EAX\r
145 ; wPort = [EBP+12]\r
146 ;\r
147 PUBLIC __InDWord:\r
148                 PUSH EBP\r
149                 MOV EBP, ESP\r
150                 MOV DX, WORD PTR [EBP+12]\r
151                 IN EAX, DX\r
152                 POP EBP\r
153                 RETF 4                  ;\r
154 \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
159 ;\r
160 PUBLIC __ReadCMOS:\r
161                 PUSH EBP\r
162                 MOV EBP, ESP\r
163                 MOV AL, BYTE PTR [EBP+12]\r
164                 OR AL, 80h\r
165                 CLI\r
166                 OUT 70h,AL\r
167                 NOP\r
168                 NOP\r
169                 NOP\r
170                 NOP\r
171                 IN AL, 71h\r
172                 STI\r
173                 AND EAX, 0FFh\r
174                 POP EBP\r
175                 RETF 4                  ;\r
176 \r
177 ;===============================================\r
178 ;\r
179 ; CopyData(pSource, pDestination, dBytes)\r
180 ;\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
184 ;\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
194 ;\r
195 ;pSource        [EBP + 20]\r
196 ;pDest          [EBP + 16]\r
197 ;cBytes         [EBP + 12]\r
198 ;\r
199 PUBLIC __CopyData       PROC    FAR\r
200                 PUSH EBP\r
201                 MOV EBP,ESP\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
207                 JNC NoByteC\r
208                 MOVSB                                   ;Handle the odd byte\r
209 NoByteC:\r
210                 SHR ECX,1                               ;Check odd word\r
211                 JNC NoWordC\r
212                 MOVSW                                   ;Handle the odd word\r
213 NoWordC:\r
214                 REP MOVSD                               ;Move all DWORDS that are left\r
215                 POP EBP\r
216                 RETF 12                                 ;Pop args off the stack\r
217 \r
218 ;===============================================\r
219 ;\r
220 ; CopyDataR(pSource, pDestination, dBytes)\r
221 ;\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
225 ;\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
233 ;\r
234 ;pSource        [EBP + 20]\r
235 ;pDest          [EBP + 16]\r
236 ;cBytes         [EBP + 12]\r
237 ;\r
238 PUBLIC __CopyDataR:\r
239                 PUSH EBP\r
240                 MOV EBP,ESP\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
246                 ADD EDI, ECX\r
247                 DEC ESI                                 ;correct addresses after addition\r
248                 DEC EDI\r
249                 SHR ECX,1                               ;Check odd byte\r
250                 JNC NoByteR\r
251                 MOVSB                                   ;Handle the odd byte\r
252 NoByteR:\r
253                 SHR ECX,1                               ;Check odd word\r
254                 JNC NoWordC\r
255                 MOVSW                                   ;Handle the odd word\r
256 NoWordR:\r
257                 REP MOVSD                               ;Move all DWORDS that are left\r
258                 POP EBP\r
259                 RETF 12                                 ;Pop args off the stack\r
260 \r
261 ;===============================================\r
262 ;\r
263 ; FillData(pDest, cBytes, bFill)\r
264 ;\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
268 ;\r
269 ; Trys to use DWORDS if it can.\r
270 ;\r
271 ;pDest          [EBP + 20]\r
272 ;cBytes         [EBP + 16]\r
273 ;bFill          [EBP + 12]\r
274 ;\r
275 PUBLIC __FillData:\r
276                 PUSH EBP\r
277                 MOV     EBP,ESP\r
278                 MOV     AL, BYTE PTR [EBP+12]   ;Byte to fill with\r
279                 MOV     AH,AL                                   ;Set up to store DWords\r
280                 SHL EAX,8\r
281                 MOV AL,AH\r
282                 SHL EAX,8\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
288                 JNC NoByteF\r
289                 STOSB                                           ;Handle the odd byte\r
290 NoByteF:\r
291                 SHR     ECX,1                                   ;Check even/odd\r
292                 JNC NoWordF\r
293                 STOSW                                           ;Handle the odd word\r
294 NoWordF:\r
295                 REP     STOSD                                   ;Store FillCh in each DWORD\r
296                 POP     EBP\r
297                 RETF 12                                         ;Pop args off the stack\r
298 \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
304 ;\r
305 ; CompareNCS(pS1, pS2, dSize) : returned offset or -1\r
306 ;\r
307 ; pS1 & pS2 pointer to strings to compare\r
308 ; dSize is length to compare out to\r
309 ;\r
310 ; Case is only ignored in the letters of the ASCII alphabet (A-Z).\r
311 ;\r
312 ; pS1   [EBP+20]\r
313 ; pS2   [EBP+16]\r
314 ; dSize [EBP+12]\r
315 ;\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
323 CompNCS1:\r
324                 REP     CMPSB                                   ;Compare strings...\r
325                 JZ NCSMatch                                     ;If all bytes ok, .. go for it\r
326 NCSCase:\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
335                 CMP AL,BL\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
339 NCSNoGo:\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
343                 JMP SHORT NCSDone\r
344 NCSMatch:\r
345                 MOV     EAX, -1                                 ;Strings match\r
346 NCSDone:\r
347                 POP     EBP                                             ;Restore callers frame ptr\r
348                 RETF 12                                         ;Pop args off the stack\r
349 \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
355 ;\r
356 ; Compare(pS1, pS2, dSize) : returned offset or -1\r
357 ;\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
361 ;\r
362 ; pS1   [EBP+20]\r
363 ; pS2   [EBP+16]\r
364 ; dSize [EBP+12]\r
365 ;\r
366 PUBLIC __Compare:\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
378                 JMP SHORT CompDone\r
379 CompMatch:\r
380                 MOV     EAX, -1                                 ;Strings match\r
381 CompDone:\r
382                 POP     EBP                                             ;Restore callers frame ptr\r
383                 RETF 12                                         ;Pop args off the stack\r
384 \r
385 ;===================  Module End  ===============================\r