$MOD186
$PAGELENGTH (95)
$PAGEWIDTH  (136)

;-- created on  11-Jan-85 17:48:39

;-- last edited by:

;--     Lichtenberg.pa                   26-Jul-85              ;Fixed mapvoidregion
;--     Lichtenberg.pa                   26-Jul-85              ;Hardware real mem size check
;--     Lichtenberg.pa			 15-Jul-85 14:00:00     ;Map the IOCBPage for new initial
;--     Lichtenberg.pa                    3-Jul-85 15:26:13     ;Off-by-one error  at vps 1FE to 2FE fixed
;--     Lichtenberg.pa			  3-Jul-85 13:51:39     ;B0 Upgrade and misc fixes.
;--	bokelman.pa			  8-Apr-85 14:53:34	;Update.
;--	bokelman.pa			 15-Jan-85  9:21:11	;First release.

NAME			LispVM
;--------------------------------------------------------------------------------
;
$NOLIST
$INCLUDE		(HardDefs.asm)	
$INCLUDE		(IOPDefs.asm)	
$INCLUDE		(IOPLRam.asm)
;$INCLUDE		(EEPDefs.asm)
$INCLUDE		(IOPMacro.asm)
$INCLUDE		(VMMDefs.asm)
$LIST

			


;--------------------------------------------------------------------------------

;********************************************************************************

;--------------------------------------------------------------------------------
IORegion		SEGMENT		COMMON 

EXTRN			loaderVirtualMemoryLocation  :DWORD ;from IORRAMBt.asm
EXTRN			bitMapOrg  :WORD 		;IORDisp.asm - =0 for Daybreak
							;with 512Kbyte display memory or
							;"n" Achip Daisy; 6000 for   
							;Daybreak with 128Kbyte display
							;memory and 40000 for Daisy with
							;one AChip. 

IORegion		ENDS

;--------------------------------------------------------------------------------

;********************************************************************************


IOPEInRAM		SEGMENT		PUBLIC

PUBLIC			LispVM 		;jmm:84-11-27:debug only.

			Assume CS:IOPEInRAM
			Assume DS:IORegion
			Assume ES:IOPELocalRAM


LispVMEntry:		JMP	EnterLispVM



;--------------------------------------------------------------------------------
;Local Constants:
;----------------
hardwareMaxRealPage	EQU	1FFFH

LispBigStretch		EQU	35EH
LispBigStretchReal	EQU	560H
lispVirtualPage		EQU	100H		;Lisp SYSOUT virtual page origin.

IFRegionVirtual		EQU	100H
IFRegionReal		EQU	2h
IFRegionSize		EQU	6

IOCBPageReal		equ	1
IOCBPageVirtual		equ	1

extraGroupReal		EQU	501H
extraGroupVirtual	EQU	2FFH
extraGroupSize		EQU	31DH-2FFH+1

extraVoidVirtual	EQU	31EH
extraVoidSize		EQU	35DH-31EH+1



;--------------------------------------------------------------------------------


;Register equates:

RealPage		EQU	BX
VMMOffset 		EQU	DI
VirtualPage		EQU	SI
request			EQU	SI

;Local Variables:
;----------------

firstRealPage		DW	0		;This is the location of the very first
lastRealPage		DW	0		;chunk of Dove memory.
sizeOfVMM		DW	0		
locationOfVMM		DW	0						
accessToVMM		DD	0						
sizeOfIORegion		DW	0						
locationOfIORegion	DW	0						
sizeOfDisplayMemory	DW	0						
locationOfDisplayMemory	DW	0						
two64KbBanksIn128Kb	DB	0
sizeOfPageInBytes	DW	pageSizeInBytes					
sizeOfPageInWords	DW	pageSizeInWords					
						
					
;--------------------------------------------------------------------------------



			
;-- Virtual Memory Initialization:
;
;Here we set up the VMM so that virtual memory is an approximation of DLion real memory.
;Initial will load the Lisp SYSOUT, which aliases for the Germ, into virtual memory, starting at page 100H.
;Since the SYSOUT is usally loaded into the second page of the display, Virtual Page 100h is mapped to
;Real Page 02H, which is currently the second page of the display.
;
;This map assume the IORegion Virtual address space does not overlap the the area into which Opie loads the Germ.
;
;This map is temporary.  The real VMMap is built by the Lisp Emulator.
;
;--------------------------------------------------------------------------------


LispVM			PROC	FAR

EnterLispVM:		%ReadEEPROM(EEPromVMMBitSize)		;jmm:84-12-26:MakeWordForVMMPageCount
			MOV	sizeOfVMM, AX		
			MOV	sizeOfVMM, 0100H		;jmm:85-01-04:Until we have EEPromVMM.		

;-----------------------
			
InitializeLispVMVariables:
			MOV	CS: sizeOfIORegion, doveIORegionSize 
			MOV	CS: locationOfVMM, fatDaybreakVMMBasePage 
			MOV	CS: locationOfIORegion, fatDaybreakIORegionBasePage 
			MOV	CS: locationOfDisplayMemory, fatDaybreakDisplayBasePage 
			MOV	CS: sizeOfDisplayMemory, fatDaybreakDisplayMemSize 
			MOV	CS: firstRealPage, firstDovePage ;We need to know what
			IN	AX, machineIDPort		;machine we are on because
			AND	AX, machineIDMask
			CMP	AX, Daisy			;VMM, IORegion and display
			JNE	DaybreakInitialization		;are in different places for
			MOV	CS: sizeOfDisplayMemory, daisyDisplayMemSize  
DaisyInitialization:	CMP	bitMapOrg, fatDaisy		;
			JE	FatDaisyVariables
SlimDaisyVariables:	MOV	CS: locationOfVMM, slimDaisyVMMBasePage
			MOV	CS: locationOfIORegion, slimDaisyIORegionBasePage
			MOV	CS: locationOfDisplayMemory, slimDaisyDisplayBasePage
			MOV	CS: sizeOfDisplayMemory, slimDaisyDisplayMemSize
			JMP	FindSizeOfMemory
FatDaisyVariables:	MOV	CS: locationOfVMM, fatDaisyVMMBasePage
			MOV	CS: locationOfIORegion, fatDaisyIORegionBasePage
			MOV	CS: locationOfDisplayMemory, fatDaisyDisplayBasePage
			MOV	CS: sizeOfDisplayMemory, fatDaisyDisplayMemSize
			JMP	FindSizeOfMemory
DaybreakInitialization:	CMP	bitMapOrg, fatDaybreak
			JE	FindSizeOfMemory
			MOV	CS: firstRealPage, firstSlimDaybreakPage
			MOV	CS: locationOfDisplayMemory, slimDaybreakDisplayBasePage
			MOV	CS: sizeOfDisplayMemory, slimDaybreakDisplayMemSize
			
;-----------------------
			
FindSizeOfMemory:	MOV	RealPage, firstRealPage ;Start writing to memory a
PointToNext128KbBank:	MOV	AX, RealPage		;page at a time until we have
			MUL	sizeOfPageInBytes		;a failure which will mean that
			XCHG	AX, DX				;we have reached the end of
			MOV	AH, extendedBusOpieAddress	;memory. We will set up the
			MOV	CX, AX				;the general Map register to
			%EstablishIOPAccess(generalMapRegister,CX-DX) ;point at 128Kbyte chunks.
			MOV	two64KbBanksIn128Kb, 2		;We will go through a 128Kb chunk
								;twice - index register restriction.
								
CheckIfMemoryExists:	;Read the contents of two consecutive memory locations on each page;
			;Invert the data read and store it; Read it back and compare;
			;If equal to value stored, memory is there, else we've found the end;
			;Return original contents.

			CMP	RealPage,hardwareMaxRealPage	;at end of addr space?
			JE	MemorySizeFound
			
			MOV	CX, ES: [DI]			;First word
			NOT	CX
			MOV	ES: [DI], CX			;Store invert
			MOV	DX, ES: 2 [DI]			;Second word
			NOT	DX
			MOV	ES: 2 [DI], DX			;Store invert
			CMP	CX, ES: [DI]			;Compare first
			JNE	MemorySizeFound			;All done.
			NOT	CX
			MOV	ES: [DI], CX			;Restore first
			CMP	DX, ES: 2 [DI]			;Compare second
			JNE	MemorySizeFound			;All done.
			NOT	DX
			MOV	ES: 2 [DI], DX			;Restore second
			INC	RealPage			;keep looking for end of memory.
			ADD	DI, pageSizeInBytes
			JNC	CheckIfMemoryExists
			DEC	two64KbBanksIn128Kb
			JZ	PointToNext128KbBank
			MOV	AX, ES				;Time to upgrade the segment register
			ADD	AX, crossover64KbBank		;and reinitialize the index register.
			MOV	ES, AX
			XOR	DI, DI
			JMP	CheckIfMemoryExists
			
;-----------------------
			
					
MemorySizeFound:
			MOV	lastRealPage, RealPage
			MOV	AX, locationOfVMM
			MUL	sizeOfPageInBytes
			XCHG	AX, DX
			MOV	AH, extendedBusOpieAddress
			MOV	CX, AX
			%EstablishIOPAccess(mesaVMMapRegister,CX-DX)
			MOV	WORD PTR accessToVMM[2], ES
			MOV	WORD PTR accessToVMM[0], DI
			
;-----------------------

			LES	VMMOffset, accessToVMM
			MOV	CX, sizeOfVMM		;Number of pages of VMM.
StampAllPagesVacant:
			MOV	DX, pageSizeInWords
StampThisPageVacant:
			MOV	WORD PTR ES: [VMMOffset], (pageVacantMask SHL 8)
			INC	VMMOffset
			INC	VMMOffset
			JNZ	StayInThis64KbBank
			MOV	AX, ES
			ADD	AX, crossover64KbBank
			MOV	ES, AX
StayInThis64KbBank:
			DEC	DX
			JNZ	StampThisPageVacant
			LOOP	StampAllPagesVacant
			
;-----------------------

; don't need this anymore but just incase...

			mov	ax,0abbah
 			out	90h,ax

			
MapPresentPages:

			mov	VirtualPage,IOCBPageVirtual
			mov	RealPage,IOCBPageReal
			mov	cx,1   		; only one page
			CALL	MapRegion

			MOV	VirtualPage, IORegionFirstVirtualPage
			MOV	RealPage, locationOfIORegion
			MOV	CX, sizeOfIORegion
			CALL	MapRegion			;Establish map for IORegion.
			MOV	VirtualPage, lispVirtualPage
			MOV	CX, sizeOfDisplayMemory
			SUB	CX, 2
			CALL	MapVoidRegion			;Map Germ (AKA: Sysout) to Display page 2.
			MOV	CX, 257				;Map old VMM image in sysout to VOID
			CALL	MapVoidRegion
			
; We need the interface page, and the obvious choice for it will be real page 500H, since it's not mapped yet.

			MOV	VirtualPage,IFRegionVirtual
			MOV	RealPage,IFRegionReal
			MOV	CX,IFRegionSize
			CALL	MapRegion
			

; Map next group of pages in.  (Don't know what they're for)

			MOV	CX,extraGroupSize
			MOV	RealPage,extraGroupReal
			MOV	VirtualPage,extraGroupVirtual
			CALL	MapRegion

; Void where Lisp thinks the IORegion is.

			MOV	VirtualPage,extraVoidVirtual
			MOV	CX,extraVoidSize
			CALL	MapVoidRegion

; Map the rest of the pages in real memory in.

			MOV	VirtualPage, LispBigStretch
			MOV	RealPage, LispBigStretchReal
			
PageMappingLoop:	MOV	CX, 1				;One page region.
			CALL	MapRegion
			CMP	RealPage, lastRealPage	
			JNE	PageMappingLoop
			
			
			MOV     CX,0D000H			; Temp:  Do lots of pages.
			CALL	MapVoidRegion

;-----------------------

			
					
			MOV	WORD PTR loaderVirtualMemoryLocation[0], lispVirtualPage ;A virtual address
			MOV	WORD PTR loaderVirtualMemoryLocation[2], (mesaLogicalPageOpieAddress SHL 8)
								;has the page value appearing in
								;the highest sixteen bits of the
								;address. Here we forward the
								;Germ's virtual address.
								
			
LispVMFinished:	RET 

			
			
LispVM			ENDP


;-----------------------



MapRegion:		;Map (CX) VirtualPages into RealPages.
			;Return VirtualPage + (CX), and RealPage + (CX).
			LES	VMMOffset, accessToVMM
			ADD	VMMOffset, VirtualPage
			ADD	VMMOffset, VirtualPage		;Offset is 2*VirtualPage
			JNC	StayInCurrent64KbBank		;No carry if within '86 segment.
			MOV	AX, ES
			ADD	AX, crossover64KbBank		;Else, bump ES:
			MOV	ES, AX
StayInCurrent64KbBank:			
			MOV	AX, RealPage			;into the VMM and mask them
			MUL	sizeOfPageInWords		;accordingly.
			XCHG	AH, AL
			MOV	AH, DL				;Only bits (21)20-8 go into
			OR	AX, (pagePresentMask SHL 8)	;the map and a (2) 3 bit mask.
			MOV	ES: [VMMOffset], AX 		;() for large memory machines.
			INC	RealPage
			INC	VirtualPage
			LOOP	MapRegion
			RET			 
			
MapVoidRegion:		;Map (CX) VirtualPages into VOID (LastRealPage).
			;Return virtualPage + (CX).
			PUSH	CX				;Save region size.
			MOV	RealPage, LastRealPage		;Map region to LastRealPage
			INC	RealPage	
			MOV	CX, 1				;one page at a time.
			CALL	MapRegion
			POP	CX
			LOOP	MapVoidRegion




			RET

			
;-----------------------

			
IOPEInRAM		ENDS
			
;********************************************************************************
			
			
			END