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

📄 memcode.inc

📁 MMURTL(tm) Computer Operating System Ver x0.8, source code.
💻 INC
📖 第 1 页 / 共 3 页
字号:
		CALL AddRun				;Does not return error
								;EAX still has new linear address
		MOV EBX, ppMemRet		;Get address of caller's pointer
		MOV [EBX], EAX			;Give em new LinAdd
		XOR EAX, EAX			;No error
ALOSPExit:			            ;
		PUSH EAX				;Save last error
		PUSH MemExch			;Send a Semaphore msg (so next guy can get in)
		PUSH 0FFFFFFF1h			;
		PUSH 0FFFFFFF1h			;
		CALL FAR PTR _SendMsg	;
		POP EAX					;Get original error back (ignore kernel erc)
		MOV ESP,EBP				;
		POP EBP                 ;
		RETF 8                  ;
_AllocOSPage ENDP

;=============================================================================
; AllocPage --
; This is identical to AllocOSPage except it's call gate is set to USER
; level and the PD base value is set to 3072.  See the call description
; for AllocOSPage

_AllocPage PROC FAR             ;
		PUSH EBP                ;
		MOV EBP,ESP             ;
		PUSH MemExch			;Wait at the MemExch for Msg
		MOV EAX, pRunTSS		;Put Msg in callers TSS Message Area
		ADD EAX, TSS_Msg
		PUSH EAX
		CALL FAR PTR _WaitMsg
		CMP EAX,0h				;Kernel Error??
		JNE SHORT ALPExit       ;Yes! Serious problem...
		MOV EAX,n4KPages		;size of request
		OR  EAX,EAX				;More than 0?
		JNZ ALP00				;Yes
		MOV EAX,ercBadMemReq    ;Can't be zero!
		JMP ALPExit				;
ALP00:
		MOV EAX,n4KPages		;size of request
		CMP EAX, _nPagesFree	;See if have enuf physical memory
		JBE ALP01				;Yes
		MOV EAX, ErcNoMem		;Sorry boss, we're maxed out
		JMP SHORT ALPExit
ALP01:
		MOV EBX, EAX			;nPages
		MOV EAX, 256			;PD base for USER mem (needed by FindRun)
		CALL FindRun
		OR EAX, EAX				;(0 = No Runs big enuf)
		JNZ SHORT ALP02			;No Error!

		CALL AddUserPT			;Add a new page table (we need it!)
		OR EAX, EAX				; 0 = NO Error
		JZ SHORT ALP01			; Go back & try again
		JMP SHORT ALPExit		; ERROR!!

ALP02:
		CALL AddRun				;Does not return error
		MOV EBX, ppMemRet		;Get address of caller's pointer
		MOV [EBX], EAX			;Give em new LinAdd
		XOR EAX, EAX			;No error
ALPExit:			            ;
		PUSH EAX				;Save last error
		PUSH MemExch			;Send a Semaphore msg (so next guy can get in)
		PUSH 0FFFFFFF1h			;
		PUSH 0FFFFFFF1h			;
		CALL FAR PTR _SendMsg	;
		POP EAX					;Get original error back (ignore kernel erc)
		MOV ESP,EBP				;
		POP EBP                 ;
		RETF 8                  ;
_AllocPage ENDP

;=============================================================================
; AliasMem --
; This creates alias pages in the current job's PD/PTs if the current
; PD is different than the PD for the job specified.  This allows
; system services to access a caller memory for messaging WITHOUT having
; to move data around.  The pages are create at USER protection level
; even if they are in OS memory space (a service installed in OS memory).
; Even if the address is only two bytes, if it crosses page boundries,
; we need two pages.
;
; STEPS:
; 1) See if the current PD = Specified Job PD. If so, Exit. (No alias needed).
; 2) Calculate how many entries (pages) will be needed.
; 3) See if they are available.
; 3) Make PTE entries and return alias address to caller.
;
; Procedureal Interface :
;
;   AliasMem(pMem, dcbMem, dJobNum, ppAliasRet): dError
;
;   pMem   is the address to alias.
;	dcbMem is the number of bytes needed for alias access.
;	JobNum is the job number that pMem belongs to.
;	ppAliasRet is the address to return the alias address to.
;
;
;pMem		EQU [EBP+24]		;
;dcbMem		EQU [EBP+20]		;
;JobNum		EQU [EBP+16]		;
;ppAliasRet EQU [EBP+12]		;

_AliasMem PROC FAR             ;
		PUSH EBP                ;
		MOV EBP,ESP             ;
		CALL GetCrntJobNum		;Puts Current Job Num in EAX
		MOV EBX, [EBP+16]		;Get Job number for pMem
		CMP EAX, EBX			;Are they the same Page Directory??
		JNE ALSPBegin			;No, alias it
		XOR EAX, EAX			;Yes, No Error
		JMP ALSPDone			;Exit, we're done

ALSPBegin:
		;Now wait our turn with memory management

;		PUSH MemExch			;Wait at the MemExch for Msg
;		MOV EAX, pRunTSS		;Put Msg in callers TSS Message Area
;		ADD EAX, TSS_Msg
;		PUSH EAX
;		CALL FAR PTR _WaitMsg
;		CMP EAX,0h				;Kernel Error??
;		JNE ALSPDone      		;Yes! Serious problem...

		; We're IN!

ALSP00:
		MOV EBX, [EBP+24]			;pMem into EAX
		AND EBX, 0FFFh				;MODULO 4096  (remainder)
		MOV EAX, [EBP+20]			;dcbMem
		ADD EAX, EBX				;Add the remainder of address
		ADD EAX, DWORD PTR [EBP+20] ;Add to dcbMem
		SHR EAX, 12				    ;EAX is nPages-1
		INC EAX						;EAX is now nPages we need!
		MOV ECX, EAX				;Save nPages in ECX

		;Now we find out whos memory we are in to make alias
		;EAX is 256 for user space, 0 for OS
		;EBX is number of pages for run

		CALL GetCrntJobNum			;See if it is OS based service
		CMP EAX, 1					;OS Job?
		JE SHORT ALSP011			;Yes
		MOV EAX, 256				;No, User memory
		JMP SHORT ALSP01
ALSP011:
		XOR EAX, EAX				;Set up for OS memory space
ALSP01:
		MOV EBX, ECX				;Number of pages we need into EBX
		CALL FindRun				;EAX has 0 or 256

		;EAX is now linear address or 0 if no run is large enough
		;EBX  still has count of pages

		OR EAX, EAX					;Was there enough PTEs?
		JNZ ALSP04					;Yes

		CALL GetCrntJobNum			;See if it is OS based service
		CMP EAX, 1					;OS Job?
		JE SHORT ALSP03				;Yes
		CALL AddUserPT				;No!  Add a new USER page table
		JMP SHORT ALSP03
ALSP02:
		CALL AddOSPT				;No!  Add a new OS page table
ALSP03:
		OR EAX, EAX					;0 = NO Error
		JZ SHORT ALSP00				;Go back & try again
		JMP SHORT ALSPExit			;ERROR!!

ALSP04:
		;EAX has linear address (from find run) Sve in EDI
		;EBX still has number of pages to alias
		;Set ESI to linear address of pages to alias (from other job)
		;Set EDX job number of job we are aliasing

		MOV EDI, EAX				;Save alias page address base
		MOV ESI, [EBP+24]			;Address to alias
		MOV EDX, [EBP+16]			;Job number
		CALL AddAliasRun

		;Now, take new alias mem and add trailing bits to address
		;and return to caller so he knows address (EDI is lin add)

		MOV EAX, [EBP+24]			;original pMem
		AND EAX, 0FFFh				;Get remaining bits
		ADD EDI, EAX
		MOV ESI, [EBP+12]			;pAliasRet
		MOV [ESI], EDI				;Returned address to caller!
		XOR EAX, EAX				;Set to 0 (no error)

		;We are done
ALSPExit:			            ;
;		PUSH EAX				;Save last error
;		PUSH MemExch			;Send a Semaphore msg (so next guy can get in)
;		PUSH 0FFFFFFF1h				;
;		PUSH 0FFFFFFF1h				;
;		CALL FAR PTR _SendMsg	;
;		POP EAX					;Get original error back (ignore kernel erc)
ALSPDone:
		MOV ESP,EBP				;
		POP EBP                 ;
		RETF 16                 ;
_AliasMem ENDP

;=============================================================================
; DeAliasMem --
;
; Procedureal Interface :
;
;		DeAliasMem(pAliasMem, dcbAliasBytes, JobNum):ercType
;
;   pAliasMem is the address which was given to you from the AliasMem call.
;   This zeros out the page entries that were made during the AliasMem
;   call. We do not need to go through the OS MEM semaphore exchange
;	because we are only zeroing out PTE's one at a time. This
;	WOULD NOT interfere with any memory allocation routines.
;
;	pAliasMem is the address to DeAlias
;	dcbAliasBytes is the size of the original memory aliased
;
;pAliasMem 		EQU [EBP+20]
;dcbAliasBytes	EQU [EBP+16]
;AliasJobNum	EQU [EBP+12]

_DeAliasMem PROC FAR           	;
		PUSH EBP                ;
		MOV EBP,ESP             ;

		;Calculate the number of pages to DeAlias

		MOV EBX, [EBP+20]			;pMem into EAX
		AND EBX, 0FFFh				;MODULO 4096  (remainder)
		MOV EAX, [EBP+16]			;dcbMem
		ADD EAX, EBX				;Add the remainder of address
		ADD EAX, DWORD PTR [EBP+20] ;Add to dcbMem
		SHR EAX, 12				    ;EAX is nPages-1
		INC EAX						;EAX is now nPages we need!
		MOV ECX, EAX				;Number of pages into EDI & ECX
		MOV EDI,ECX					;Save also in EDI (for compare)
		MOV EDX, [EBP+20]			;Linear Mem to DeAlias
DALM01:
		MOV EBX, EDX			;Address of next page to deallocate
		MOV EAX, [EBP+12]		;Job num into EAX for LinToPhy
		CALL LinToPhy			;Call this to get address of PTE into ESI

		;Now we have Physical Address in EAX (we don't really need it)
		;and pointer to PTE in ESI (We NEEDED THIS).
		;See if PTE is an alias, if so just ZERO PTE.
		;DO NOT deallocate the physical page

		MOV EBX, [ESI]			;Get PTE into EBX
		TEST EBX, PRSNTBIT		;Is page present (valid)???
		JNZ DALM02				;Yes, it's page is present

		CMP ECX, EDI			;NO! (did we do any at all)
		JNE DALM011				;We did some..
		MOV EAX, ErcBadLinAdd	;None at all!
		JMP SHORT DALMExit

DALM011:
		MOV EAX, ErcBadAlias	;We dealiased what we could,
		JMP SHORT DALMExit		;but less than you asked for!

DALM02:
		TEST EBX, ALIASBIT		;Is page an ALIAS?
		JZ DALM03				;NO - DO not zero it!

		;If we got here the page is presnt and IS an alias
		;so we zero out the page.

		XOR EAX, EAX			;
		MOV [ESI], EAX			;ZERO PTE entry
DALM03:

		ADD EDX, 4096			;Next linear page
		LOOP DALM01
								;If we fall out EAX = ErcOK already
DALMExit:
		MOV ESP,EBP             ;
		POP EBP                 ;
		RETF 12	                ;

_DeAliasMem ENDP

;=============================================================================
; DeAllocPage --
;
; Procedureal Interface :
;
;		DeAllocPage(pOrigMem, n4KPages):ercType
;
;   pOrigMem is a POINTER which should be point to memory page(s) to be
;   deallocate.	 The lower 12 bits of the pointer is actually ignored
;   because we deallocate 4K pages.  This will free physical pages unless
;   the page is marked as an alias. It will always free linear memory
;   providing it is valid.  Even if you specify more pages than are valid
;   this will deallocate or dealias as much as it can before reaching
;   an invalid page.
;
;	n4KPages is the number of 4K pages to deallocate
;
pOrigMem 	EQU [EBP+10h]
n4KPagesD	EQU [EBP+0Ch]		;

_DeAllocPage PROC FAR           ;
		PUSH EBP                ;
		MOV EBP,ESP             ;

		PUSH MemExch			;Wait at the MemExch for Msg
		MOV EAX, pRunTSS		;Put Msg in callers TSS Message Area
		ADD EAX, TSS_Msg
		PUSH EAX
		CALL FAR PTR _WaitMsg
		CMP EAX,0h				;Error??
		JNE DAMExit             ;Yes!

		MOV EDX, pOrigMem		;Linear Mem to deallocate
		AND EDX, 0FFFFF000h		;Drop odd bits from address (MOD 4096)
		MOV ECX, n4KPagesD		;Number of pages to deallocate

DAP01:
		MOV EBX, EDX			;Address of next page to deallocate
		CALL GetCrntJobNum		;Leave Job# in EAX for LinToPhy
		CALL LinToPhy			;

		;Now we have Physical Address in EAX
		;and pointer to PTE in ESI.
		;See if PTE is an alias, if so just ZERO PTE,
		;else deallocate physical page THEN zero PTE

		MOV EBX, [ESI]			;Get PTE into EBX
		TEST EBX, PRSNTBIT		;Is page present (valid)???
		JNZ DAP02				;Yes, it's page is present

		CMP ECX, n4KPagesD		;NO! (did we do any at all)
		JNE DAP011				;We did some..
		MOV EAX, ErcBadLinAdd	;None at all!
		JMP SHORT DAMExit

DAP011:
		MOV EAX, ErcShortMem	;We deallocated what we could,
		JMP SHORT DAMExit		;but less than you asked for!

DAP02:
		TEST EBX, ALIASBIT		;Is page an ALIAS?
		JNZ DAP03				;Yes, it's an Alias

		;If we got here the page is presnt and NOT an alias
		;so we must unmark (release) the physical page.

		AND EBX, 0FFFFF000h		;get rid of OS bits
		CALL UnMarkPage			;

DAP03:
		XOR EAX, EAX			;
		MOV [ESI], EAX			;ZERO PTE entry

		ADD EDX, 4096			;Next linear page
		LOOP DAP01
								;If we fall out EAX = ErcOK already
DAMExit:
		PUSH EAX				;save Memory error

		PUSH MemExch			;Send a dummy message to pick up
		PUSH 0FFFFFFF1h			; so next guy can get in
		PUSH 0FFFFFFF1h
		CALL FAR PTR _SendMsg	;
		CMP EAX, 0				;Kernel error has priority
		JNE DAMExit1			; over memory error

		POP EAX					;get Memory error back

DAMExit1:
		MOV ESP,EBP             ;
		POP EBP                 ;
		RETF 8 	                ;

_DeAllocPage ENDP


;=============================================================================
; QueryMemPages --
;
; Procedureal Interface :
;
;		QueryMemPages(pdnPagesRet):ercType
;
;	pdnPagesRet is a pointer where you want the count of pages
;   left available returned
;
pMemleft 	EQU [EBP+0Ch]

_QueryPages PROC FAR            ;
		PUSH EBP                ;
		MOV EBP,ESP             ;

		MOV ESI, pMemLeft
		MOV EAX,  _nPagesFree
		MOV [ESI], EAX
		XOR EAX, EAX			;No Error

		MOV ESP,EBP             ;
		POP EBP                 ;
		RETF 4 	                ;

_QueryPages ENDP

;==============================================================================
;
; GetPhyAdd -- This returns the phyical address for a linear address
;
;
; Procedureal Interface :
;
;		GetPhyAdd(JobNum, LinAdd, pPhyRet):ercType
;
;	LinAdd is the Linear address you want the physical address for
;	pPhyRet points to the unsigned long where Phyadd is returned
;
;
;JobNum  EQU [EBP+20]
;LinAdd  EQU [EBP+16]
;pPhyRet EQU [EBP+12]
;

_GetPhyAdd PROC FAR      		;
		PUSH EBP                ;
		MOV EBP,ESP             ;
		MOV EBX, [EBP+16]		; Linear Address
		MOV EAX, [EBP+20]		; Job Number
		CALL LinToPhy
		MOV ESI, [EBP+12]		; pPhyRet
		MOV [ESI], EAX			;
		XOR EAX, EAX			; No Error
		MOV ESP,EBP             ;
		POP EBP                 ;
		RETF 12	                ;

_GetPhyAdd ENDP

;==============================================================================

⌨️ 快捷键说明

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