⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 _pm.asm

📁 BIOS emulator and interface to Realmode X86 Emulator Library Can emulate a PCI Graphic Controller V
💻 ASM
字号:
;****************************************************************************;*;*					SciTech OS Portability Manager Library;*;*  ========================================================================;*;*    The contents of this file are subject to the SciTech MGL Public;*    License Version 1.0 (the "License"); you may not use this file;*    except in compliance with the License. You may obtain a copy of;*    the License at http://www.scitechsoft.com/mgl-license.txt;*;*    Software distributed under the License is distributed on an;*    "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or;*    implied. See the License for the specific language governing;*    rights and limitations under the License.;*;*    The Original Code is Copyright (C) 1991-1998 SciTech Software, Inc.;*;*    The Initial Developer of the Original Code is SciTech Software, Inc.;*    All Rights Reserved.;*;*  ========================================================================;*;* Language:	80386 Assembler, TASM 4.0 or NASM;* Environment:	IBM PC Real mode and 16/32 bit protected mode;*;* Description:	Low level assembly support for the PM library specific to;*				MSDOS.;*;****************************************************************************		IDEALinclude	"scitech.mac"				; Memory model macrosheader    	_pmdos             		; Set up memory modelbegdataseg	_pmdosifndef 	flatmodelstruc   rmregs_sax      	dw	?ax_high		dw	?bx			dw	?bx_high		dw	?cx			dw	?cx_high		dw	?dx			dw	?dx_high		dw	?si			dw	?si_high		dw	?di			dw	?di_high		dw	?cflag		dw	?cflag_high	dw	?ends	rmregs_sRMREGS	= (rmregs_s PTR es:bx)struc	rmsregs_ses		dw	?cs		dw	?ss		dw	?ds		dw	?ends	rmsregs_sRMSREGS	= (rmsregs_s PTR es:bx)endif	; !flatmodelifdef flatmodel	cextern	_PM_savedDS,USHORTendifintel_id		db	"GenuineIntel"	; Intel vendor IDenddataseg	_pmdosbegcodeseg  _pmdos					; Start of code segmentifndef 	flatmodel;----------------------------------------------------------------------------; void PM_callRealMode(unsigned s,unsigned o, RMREGS *regs,;	RMSREGS *sregs);----------------------------------------------------------------------------; Calls a real mode procedure, loading the appropriate registers values; from the passed in structures. Only the DS and ES register are loaded; from the SREGS structure.;----------------------------------------------------------------------------cprocstart	PM_callRealMode		ARG     s:WORD, o:WORD, regs:DWORD, sregs:DWORD		LOCAL	addr:DWORD, bxVal:WORD, esVal:WORD, flags:WORD = LocalSize		enter_c		push	ds		push	es		mov		ax,[o]				; Build the address to call in 'addr'		mov		[WORD addr],ax		mov		ax,[s]		mov		[WORD addr+2],ax		les		bx,[sregs]		mov     ax,[RMSREGS.ds]		mov     ds,ax				; DS := passed in value		mov		ax,[RMSREGS.es]		mov		[esVal],ax		les		bx,[regs]		mov		ax,[RMREGS.bx]		mov		[bxVal],ax		mov		ax,[RMREGS.ax]		; AX := passed in value		mov		cx,[RMREGS.cx]		; CX := passed in value		mov		dx,[RMREGS.dx]		; DX := passed in value		mov		si,[RMREGS.si] 		; SI := passed in value		mov		di,[RMREGS.di]		; DI := passed in value		push	bp		push	[esVal]		pop		es					; ES := passed in value		mov		bx,[bxVal]			; BX := passed in value		call	[addr]				; Call the specified routine		pushf						; Save flags for later		pop		[flags]		pop		bp		push	es		pop		[esVal]		push	bx		pop		[bxVal]		les		bx,[sregs]		push	ds		pop		[RMSREGS.ds]		; Save value of DS		push	[esVal]		pop		[RMSREGS.es]		; Save value of ES		les		bx,[regs]		mov		[RMREGS.ax],ax		; Save value of AX		mov		[RMREGS.cx],cx		; Save value of CX		mov		[RMREGS.dx],dx		; Save value of DX		mov		[RMREGS.si],si		; Save value of SI		mov		[RMREGS.di],di		; Save value of DI		mov		ax,[flags]			; Return flags		and		ax,1h				; Isolate carry flag		mov		[RMREGS.cflag],ax	; Save carry flag status		mov		ax,[bxVal]		mov     [RMREGS.bx],ax		; Save value of BX		pop		es		pop		ds		leave_c		retcprocendendif;----------------------------------------------------------------------------; void PM_segread(PMSREGS *sregs);----------------------------------------------------------------------------; Read the current value of all segment registers;----------------------------------------------------------------------------cprocstartdll16	PM_segread		ARG		sregs:DPTR		enter_c		mov		ax,es		_les	_si,[sregs]		mov		[_ES _si],ax		mov		[_ES _si+2],cs		mov		[_ES _si+4],ss		mov		[_ES _si+6],ds		mov		[_ES _si+8],fs		mov		[_ES _si+10],gs		leave_c		retcprocend; Create a table of the 256 different interrupt calls that we can jump; intoifdef	USE_NASM%assign	intno 0intTable:%rep	256		db      0CDh		db      intno%assign intno	intno + 1		ret		nop%endrepelseintno = 0intTable:		REPT    256		db      0CDh		db      intnointno = intno + 1		ret		nop		ENDMendif;----------------------------------------------------------------------------; _PM_genInt	- Generate the appropriate interrupt;----------------------------------------------------------------------------cprocnear	_PM_genInt		push	_ax						; Save _ax		push	_bx                 	; Save _bxifdef flatmodel		mov    	ebx,[UINT esp+12]		; EBX := interrupt numberelse		mov		bx,sp					; Make sure ESP is zeroed		mov    	bx,[UINT ss:bx+6]		; BX := interrupt numberendif		mov     _ax,offset intTable		; Point to interrupt generation table		shl     _bx,2					; _BX := index into table		add     _ax,_bx					; _AX := pointer to interrupt codeifdef flatmodel		xchg	eax,[esp+4]				; Restore eax, and set for intelse		mov		bx,sp		xchg	ax,[ss:bx+2]			; Restore ax, and set for intendif		pop		_bx						; restore _bx		retcprocend;----------------------------------------------------------------------------; int PM_int386x(int intno, PMREGS *in, PMREGS *out,PMSREGS *sregs);----------------------------------------------------------------------------; Issues a software interrupt in protected mode. This routine has been; written to allow user programs to load CS and DS with different values; other than the default.;----------------------------------------------------------------------------cprocstartdll16	PM_int386x		ARG		intno:UINT, inptr:DPTR, outptr:DPTR, sregs:DPTR		LOCAL	flags:UINT, sv_ds:UINT, sv_esi:ULONG = LocalSize		enter_c		push	ds		push	es					; Save segment registers		push	fs		push	gs		_lds	_si,[sregs]			; DS:_SI -> Load segment registers		mov		es,[_si]		mov		bx,[_si+6]		mov		[sv_ds],_bx			; Save value of user DS on stack		mov		fs,[_si+8]		mov		gs,[_si+10]		_lds	_si,[inptr]			; Load CPU registers		mov     eax,[_si]		mov		ebx,[_si+4]		mov		ecx,[_si+8]		mov		edx,[_si+12]		mov     edi,[_si+20]		mov		esi,[_si+16]		push	ds					; Save value of DS		push	_bp					; Some interrupts trash this!		clc							; Generate the interrupt		push	[UINT intno]		mov		ds,[WORD sv_ds]		; Set value of user's DS selector		call	_PM_genInt		pop		_bp					; Pop intno from stack (flags unchanged)		pop		_bp					; Restore value of stack frame pointer		pop		ds					; Restore value of DS		pushf                       ; Save flags for later		pop		[UINT flags]		push	esi					; Save ESI for later		pop		[DWORD sv_esi]		push	ds					; Save DS for later		pop		[UINT sv_ds]		_lds	_si,[outptr]		; Save CPU registers		mov     [_si],eax		mov		[_si+4],ebx		mov		[_si+8],ecx		mov		[_si+12],edx		push	[DWORD sv_esi]		pop		[DWORD _si+16]		mov     [_si+20],edi		mov		_bx,[flags]			; Return flags		and		ebx,1h				; Isolate carry flag		mov		[_si+24],ebx		; Save carry flag status		_lds	_si,[sregs]			; Save segment registers		mov		[_si],es		mov		_bx,[sv_ds]		mov		[_si+6],bx			; Get returned DS from stack		mov		[_si+8],fs		mov		[_si+10],gs		pop		gs					; Restore segment registers		pop		fs		pop		es		pop		ds		leave_c		retcprocendifndef flatmodel_PM_savedDS		dw	_DATA			; Saved value of DSendif;----------------------------------------------------------------------------; void PM_saveDS(void);----------------------------------------------------------------------------; Save the value of DS into a section of the code segment, so that we can; quickly load this value at a later date in the PM_loadDS() routine from; inside interrupt handlers etc. The method to do this is different; depending on the DOS extender being used.;----------------------------------------------------------------------------cprocstartdll16	PM_saveDSifdef flatmodel		mov		[_PM_savedDS],ds	; Store away in data segmentendif		retcprocend;----------------------------------------------------------------------------; void PM_loadDS(void);----------------------------------------------------------------------------; Routine to load the DS register with the default value for the current; DOS extender. Only the DS register is loaded, not the ES register, so; if you wish to call C code, you will need to also load the ES register; in 32 bit protected mode.;----------------------------------------------------------------------------cprocstartdll16	PM_loadDS		mov		ds,[cs:_PM_savedDS]	; We can access the proper DS through CS		retcprocendifdef flatmodel;----------------------------------------------------------------------------; void DPMI_allocateCallback(void (*pmcode)(), void *rmregs, long *RMCB);----------------------------------------------------------------------------cprocstart	_DPMI_allocateCallback		ARG		pmcode:CPTR, rmregs:DPTR, RMCB:DPTR		enter_c		push	ds		push	es		push	cs		pop		ds		mov		esi,[pmcode]	; DS:ESI -> protected mode code to call		mov		edi,[rmregs]	; ES:EDI -> real mode register buffer		mov		ax,303h			; AX := allocate realmode callback function		int		31h		mov     eax,[RMCB]		shl		ecx,16		mov		cx,dx		mov		[es:eax],ecx	; Return real mode address		pop		es		pop		ds		leave_c		retcprocend;----------------------------------------------------------------------------; void DPMI_freeCallback(long RMCB);----------------------------------------------------------------------------cprocstart	_DPMI_freeCallback		ARG		RMCB:ULONG		enter_c		mov     cx,[WORD RMCB+2]		mov		dx,[WORD RMCB]	; CX:DX := real mode callback		mov		ax,304h		int		31h		leave_c		retcprocendendif; Macro to delay briefly to ensure that enough time has elapsed between; successive I/O accesses so that the device being accessed can respond; to both accesses even on a very fast PC.ifdef	USE_NASM%macro	DELAY 0		jmp		short $+2		jmp		short $+2		jmp		short $+2%endmacro%macro	IODELAYN 1%rep	%1		DELAY%endrep%endmacroelsemacro	DELAY		jmp		short $+2		jmp		short $+2		jmp	    short $+2endmmacro	IODELAYN	N	rept	N		DELAY	endmendmendif;----------------------------------------------------------------------------; uchar _PM_readCMOS(int index);----------------------------------------------------------------------------; Read the value of a specific CMOS register. We do this with both; normal interrupts and NMI disabled.;----------------------------------------------------------------------------cprocstart	_PM_readCMOS		ARG		index:UINT		push	_bp		mov		_bp,_sp		pushfd		mov		al,[BYTE index]		or		al,80h				; Add disable NMI flag		cli		out		70h,al		IODELAYN 5		in		al,71h		mov		ah,al		xor		al,al		IODELAYN 5		out		70h,al				; Re-enable NMI		sti		mov		al,ah				; Return value in AL		popfd		pop		_bp		retcprocend;----------------------------------------------------------------------------; void _PM_writeCMOS(int index,uchar value);----------------------------------------------------------------------------; Read the value of a specific CMOS register. We do this with both; normal interrupts and NMI disabled.;----------------------------------------------------------------------------cprocstart	_PM_writeCMOS		ARG		index:UINT, value:UCHAR		push	_bp		mov		_bp,_sp		pushfd		mov		al,[BYTE index]		or		al,80h				; Add disable NMI flag		cli		out		70h,al		IODELAYN 5		mov		al,[value]		out		71h,al		xor		al,al		IODELAYN 5		out		70h,al				; Re-enable NMI		sti		popfd		pop		_bp		retcprocend;----------------------------------------------------------------------------; _PM_getPDB - Return the Page Table Directory Base address;----------------------------------------------------------------------------cprocstart	_PM_getPDBifdef	DOS4GW		mov     ax,cs		and   	eax,3		jnz		@@Fail		mov		eax,cr3		and		eax,0FFFFF000h		retendif@@Fail:	xor		eax,eax		retcprocend;----------------------------------------------------------------------------; _PM_flushTLB - Flush the Translation Lookaside buffer;----------------------------------------------------------------------------cprocstart	_PM_flushTLBifdef	DOS4GW		mov		eax,cr3		mov		cr3,eaxendif		retcprocendendcodeseg  _pmdos		END						; End of module

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -