1 ;****************************************************************************
3 ;* SciTech OS Portability Manager Library
5 ;* ========================================================================
7 ;* The contents of this file are subject to the SciTech MGL Public
8 ;* License Version 1.0 (the "License"); you may not use this file
9 ;* except in compliance with the License. You may obtain a copy of
10 ;* the License at http://www.scitechsoft.com/mgl-license.txt
12 ;* Software distributed under the License is distributed on an
13 ;* "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
14 ;* implied. See the License for the specific language governing
15 ;* rights and limitations under the License.
17 ;* The Original Code is Copyright (C) 1991-1998 SciTech Software, Inc.
19 ;* The Initial Developer of the Original Code is SciTech Software, Inc.
20 ;* All Rights Reserved.
22 ;* ========================================================================
24 ;* Language: 80386 Assembler, TASM 4.0 or NASM
25 ;* Environment: 32-bit SMX embedded systems development
27 ;* Description: Low level assembly support for the PM library specific to
30 ;****************************************************************************
34 include "scitech.mac" ; Memory model macros
36 header _pm ; Set up memory model
40 cextern _PM_savedDS,USHORT
42 intel_id db "GenuineIntel" ; Intel vendor ID
46 begcodeseg _pm ; Start of code segment
48 ;----------------------------------------------------------------------------
49 ; void PM_segread(PMSREGS *sregs)
50 ;----------------------------------------------------------------------------
51 ; Read the current value of all segment registers
52 ;----------------------------------------------------------------------------
53 cprocstartdll16 PM_segread
73 ; Create a table of the 256 different interrupt calls that we can jump
84 %assign intno intno + 1
104 ;----------------------------------------------------------------------------
105 ; _PM_genInt - Generate the appropriate interrupt
106 ;----------------------------------------------------------------------------
111 mov ebx,[UINT esp+12] ; EBX := interrupt number
112 mov _ax,offset intTable ; Point to interrupt generation table
113 shl _bx,2 ; _BX := index into table
114 add _ax,_bx ; _AX := pointer to interrupt code
115 xchg eax,[esp+4] ; Restore eax, and set for int
116 pop _bx ; restore _bx
121 ;----------------------------------------------------------------------------
122 ; int PM_int386x(int intno, PMREGS *in, PMREGS *out,PMSREGS *sregs)
123 ;----------------------------------------------------------------------------
124 ; Issues a software interrupt in protected mode. This routine has been
125 ; written to allow user programs to load CS and DS with different values
126 ; other than the default.
127 ;----------------------------------------------------------------------------
128 cprocstartdll16 PM_int386x
130 ARG intno:UINT, inptr:DPTR, outptr:DPTR, sregs:DPTR
132 LOCAL flags:UINT, sv_ds:UINT, sv_esi:ULONG = LocalSize
136 push es ; Save segment registers
140 _lds _si,[sregs] ; DS:_SI -> Load segment registers
143 mov [sv_ds],_bx ; Save value of user DS on stack
147 _lds _si,[inptr] ; Load CPU registers
155 push ds ; Save value of DS
156 push _bp ; Some interrupts trash this!
157 clc ; Generate the interrupt
159 mov ds,[WORD sv_ds] ; Set value of user's DS selector
161 pop _bp ; Pop intno from stack (flags unchanged)
162 pop _bp ; Restore value of stack frame pointer
163 pop ds ; Restore value of DS
165 pushf ; Save flags for later
167 push esi ; Save ESI for later
169 push ds ; Save DS for later
172 _lds _si,[outptr] ; Save CPU registers
181 mov _bx,[flags] ; Return flags
182 and ebx,1h ; Isolate carry flag
183 mov [_si+24],ebx ; Save carry flag status
185 _lds _si,[sregs] ; Save segment registers
188 mov [_si+6],bx ; Get returned DS from stack
192 pop gs ; Restore segment registers
201 ;----------------------------------------------------------------------------
202 ; void PM_saveDS(void)
203 ;----------------------------------------------------------------------------
204 ; Save the value of DS into a section of the code segment, so that we can
205 ; quickly load this value at a later date in the PM_loadDS() routine from
206 ; inside interrupt handlers etc. The method to do this is different
207 ; depending on the DOS extender being used.
208 ;----------------------------------------------------------------------------
209 cprocstartdll16 PM_saveDS
211 mov [_PM_savedDS],ds ; Store away in data segment
216 ;----------------------------------------------------------------------------
217 ; void PM_loadDS(void)
218 ;----------------------------------------------------------------------------
219 ; Routine to load the DS register with the default value for the current
220 ; DOS extender. Only the DS register is loaded, not the ES register, so
221 ; if you wish to call C code, you will need to also load the ES register
222 ; in 32 bit protected mode.
223 ;----------------------------------------------------------------------------
224 cprocstartdll16 PM_loadDS
226 mov ds,[cs:_PM_savedDS] ; We can access the proper DS through CS
231 ;----------------------------------------------------------------------------
232 ; void PM_setBankA(int bank)
233 ;----------------------------------------------------------------------------
234 cprocstart PM_setBankA
251 ;----------------------------------------------------------------------------
252 ; void PM_setBankAB(int bank)
253 ;----------------------------------------------------------------------------
254 cprocstart PM_setBankAB
275 ;----------------------------------------------------------------------------
276 ; void PM_setCRTStart(int x,int y,int waitVRT)
277 ;----------------------------------------------------------------------------
278 cprocstart PM_setCRTStart
280 ARG x:UINT, y:UINT, waitVRT:UINT
296 ;----------------------------------------------------------------------------
297 ; int _PM_inp(int port)
298 ;----------------------------------------------------------------------------
299 ; Reads a byte from the specified port
300 ;----------------------------------------------------------------------------
315 ;----------------------------------------------------------------------------
316 ; void _PM_outp(int port,int value)
317 ;----------------------------------------------------------------------------
318 ; Write a byte to the specified port.
319 ;----------------------------------------------------------------------------
322 ARG port:UINT, value:UINT
334 ; Macro to delay briefly to ensure that enough time has elapsed between
335 ; successive I/O accesses so that the device being accessed can respond
336 ; to both accesses even on a very fast PC.
362 ;----------------------------------------------------------------------------
363 ; uchar _PM_readCMOS(int index)
364 ;----------------------------------------------------------------------------
365 ; Read the value of a specific CMOS register. We do this with both
366 ; normal interrupts and NMI disabled.
367 ;----------------------------------------------------------------------------
368 cprocstart _PM_readCMOS
376 or al,80h ; Add disable NMI flag
384 out 70h,al ; Re-enable NMI
386 mov al,ah ; Return value in AL
393 ;----------------------------------------------------------------------------
394 ; void _PM_writeCMOS(int index,uchar value)
395 ;----------------------------------------------------------------------------
396 ; Read the value of a specific CMOS register. We do this with both
397 ; normal interrupts and NMI disabled.
398 ;----------------------------------------------------------------------------
399 cprocstart _PM_writeCMOS
401 ARG index:UINT, value:UCHAR
407 or al,80h ; Add disable NMI flag
415 out 70h,al ; Re-enable NMI
423 ;----------------------------------------------------------------------------
424 ; _PM_getPDB - Return the Page Table Directory Base address
425 ;----------------------------------------------------------------------------
426 cprocstart _PM_getPDB
434 ;----------------------------------------------------------------------------
435 ; _PM_flushTLB - Flush the Translation Lookaside buffer
436 ;----------------------------------------------------------------------------
437 cprocstart PM_flushTLB
439 wbinvd ; Flush the CPU cache
441 mov cr3,eax ; Flush the TLB