872 lines
16 KiB
NASM
872 lines
16 KiB
NASM
;
|
|
; Command & Conquer Red Alert(tm)
|
|
; Copyright 2025 Electronic Arts Inc.
|
|
;
|
|
; This program is free software: you can redistribute it and/or modify
|
|
; it under the terms of the GNU General Public License as published by
|
|
; the Free Software Foundation, either version 3 of the License, or
|
|
; (at your option) any later version.
|
|
;
|
|
; This program is distributed in the hope that it will be useful,
|
|
; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
; GNU General Public License for more details.
|
|
;
|
|
; You should have received a copy of the GNU General Public License
|
|
; along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
;
|
|
|
|
;****************************************************************************
|
|
;*
|
|
;* C O N F I D E N T I A L -- W E S T W O O D S T U D I O S
|
|
;*
|
|
;*---------------------------------------------------------------------------
|
|
;*
|
|
;* FILE
|
|
;* mono.asm
|
|
;*
|
|
;* DESCRIPTION
|
|
;* Mono screen print and output routines. (32-Bit protected mode)
|
|
;*
|
|
;* PROGRAMMER
|
|
;* Denzil E. Long, Jr.
|
|
;*
|
|
;* DATE
|
|
;* Febuary 8, 1995
|
|
;*
|
|
;*---------------------------------------------------------------------------
|
|
;*
|
|
;* PUBLIC
|
|
;* Mono_Enable - Enable mono output.
|
|
;* Mono_Disable - Disable mono output.
|
|
;* Mono_X - Get mono cursors X position.
|
|
;* Mono_Y - Get mono cursors Y position.
|
|
;* Mono_Set_Cursor - Set the mono cursor to specified coordinates.
|
|
;* Mono_Clear_Screen - Clear the mono screen.
|
|
;* Mono_Scroll - Scroll the mono screen up.
|
|
;* Mono_Put_Char - Ouput a character to the mono screen.
|
|
;* Mono_Draw_Rect - Draw a box on the mono screen.
|
|
;* Mono_Text_Print - Print a string to the mono screen at a specified
|
|
;* position.
|
|
;* Mono_Print - Print a string to the mono screen.
|
|
;* Mono_View_Page - View a mono page.
|
|
;*
|
|
;****************************************************************************
|
|
|
|
IDEAL
|
|
P386
|
|
MODEL USE32 FLAT
|
|
LOCALS ??
|
|
|
|
DATASEG
|
|
|
|
MonoEnabled DD 1
|
|
MonoX DD 0
|
|
MonoY DD 0
|
|
MonoOff DD 0
|
|
|
|
CharData DB 0DAh,0C4h,0BFh,0B3h,0D9h,0C4h,0C0h,0B3h ; Single line
|
|
DB 0D5h,0CDh,0B8h,0B3h,0BEh,0CDh,0D4h,0B3h ; Double horz.
|
|
DB 0D6h,0C4h,0B7h,0BAh,0BDh,0C4h,0D3h,0BAh ; Double vert.
|
|
DB 0C9h,0CDh,0BBh,0BAh,0BCh,0CDh,0C8h,0BAh ; Double line.
|
|
|
|
|
|
; x,y,dist
|
|
BoxData DB 1,0,0 ; Upper left corner.
|
|
DB 1,0,1 ; Top edge.
|
|
DB 0,1,0 ; Upper right corner.
|
|
DB 0,1,2 ; Right edge.
|
|
DB -1,0,0 ; Bottom right corner.
|
|
DB -1,0,1 ; Bottom edge.
|
|
DB 0,-1,0 ; Bottom left corner.
|
|
DB 0,-1,2 ; Left edge.
|
|
DB 0,0,-1 ; End of list.
|
|
|
|
PageMap DD 0,1,2,3,4,5,6,7
|
|
|
|
CODESEG
|
|
|
|
;****************************************************************************
|
|
;*
|
|
;* NAME
|
|
;* Mono_Enable - Enable mono output.
|
|
;*
|
|
;* SYNOPSIS
|
|
;* Mono_Enable()
|
|
;*
|
|
;* void Mono_Enable(void);
|
|
;*
|
|
;* FUNCTION
|
|
;* Turn on the MonoEnabled flag.
|
|
;*
|
|
;* INPUTS
|
|
;* NONE
|
|
;*
|
|
;* RESULT
|
|
;* NONE
|
|
;*
|
|
;****************************************************************************
|
|
|
|
GLOBAL C Mono_Enable:NEAR
|
|
PROC Mono_Enable C NEAR
|
|
|
|
mov [MonoEnabled],1
|
|
ret
|
|
|
|
ENDP Mono_Enable
|
|
|
|
|
|
;****************************************************************************
|
|
;*
|
|
;* NAME
|
|
;* Mono_Disable - Disable mono output.
|
|
;*
|
|
;* SYNOPSIS
|
|
;* Mono_Disable()
|
|
;*
|
|
;* void Mono_Disable(void);
|
|
;*
|
|
;* FUNCTION
|
|
;* Turn off the MonoEnabled flag.
|
|
;*
|
|
;* INPUTS
|
|
;* NONE
|
|
;*
|
|
;* RESULT
|
|
;* NONE
|
|
;*
|
|
;****************************************************************************
|
|
|
|
GLOBAL C Mono_Disable:NEAR
|
|
PROC Mono_Disable C NEAR
|
|
|
|
mov [MonoEnabled],0
|
|
ret
|
|
|
|
ENDP Mono_Disable
|
|
|
|
|
|
;****************************************************************************
|
|
;*
|
|
;* NAME
|
|
;* Mono_X - Get mono cursors X position.
|
|
;*
|
|
;* SYNOPSIS
|
|
;* X = Mono_X()
|
|
;*
|
|
;* long Mono_X(void);
|
|
;*
|
|
;* FUNCTION
|
|
;* Return the X position of the mono screen cursor.
|
|
;*
|
|
;* INPUTS
|
|
;* NONE
|
|
;*
|
|
;* RESULT
|
|
;* X - X coordinate position.
|
|
;*
|
|
;****************************************************************************
|
|
|
|
GLOBAL C Mono_X:NEAR
|
|
PROC Mono_X C NEAR
|
|
|
|
mov eax,[MonoX]
|
|
ret
|
|
|
|
ENDP Mono_X
|
|
|
|
|
|
;****************************************************************************
|
|
;*
|
|
;* NAME
|
|
;* Mono_Y - Get mono cursors Y position.
|
|
;*
|
|
;* SYNOPSIS
|
|
;* Y = Mono_Y()
|
|
;*
|
|
;* long Mono_Y(void);
|
|
;*
|
|
;* FUNCTION
|
|
;* Return the Y position of the mono screen cursor.
|
|
;*
|
|
;* INPUTS
|
|
;* NONE
|
|
;*
|
|
;* RESULT
|
|
;* Y - Y coordinate position.
|
|
;*
|
|
;****************************************************************************
|
|
|
|
GLOBAL C Mono_Y:NEAR
|
|
PROC Mono_Y C NEAR
|
|
|
|
mov eax,[MonoY]
|
|
ret
|
|
|
|
ENDP Mono_Y
|
|
|
|
|
|
;****************************************************************************
|
|
;*
|
|
;* NAME
|
|
;* Mono_Set_Cursor - Set the mono cursor to specified coordinates.
|
|
;*
|
|
;* SYNOPSIS
|
|
;* Mono_Set_Cursor(X, Y)
|
|
;*
|
|
;* void Mono_Set_Cursor(long, long);
|
|
;*
|
|
;* FUNCTION
|
|
;*
|
|
;* INPUTS
|
|
;* X - X coordinate position.
|
|
;* Y - Y coordinate position.
|
|
;*
|
|
;* RESULT
|
|
;* NONE
|
|
;*
|
|
;****************************************************************************
|
|
|
|
GLOBAL C Mono_Set_Cursor:NEAR
|
|
PROC Mono_Set_Cursor C NEAR USES eax ebx edx
|
|
|
|
ARG xpos:DWORD
|
|
ARG ypos:DWORD
|
|
|
|
cmp [MonoEnabled],0
|
|
je short ??fini
|
|
|
|
mov eax,[ypos]
|
|
mov ah,80
|
|
imul ah
|
|
add eax,[xpos]
|
|
mov ebx,eax
|
|
|
|
; Update cursor position.
|
|
|
|
mov dx,03B4h
|
|
mov al,0Eh ;High byte register set.
|
|
out dx,al
|
|
inc dx
|
|
mov al,bh
|
|
out dx,al ;Set high byte.
|
|
|
|
dec dx
|
|
mov al,0Fh ;Low byte register set.
|
|
out dx,al
|
|
inc dx
|
|
mov al,bl
|
|
out dx,al ;Set low byte.
|
|
|
|
; Update the globals.
|
|
|
|
add ebx,ebx
|
|
mov [MonoOff],ebx
|
|
mov eax,[xpos]
|
|
mov [MonoX],eax
|
|
mov eax,[ypos]
|
|
mov [MonoY],eax
|
|
|
|
??fini:
|
|
ret
|
|
|
|
ENDP Mono_Set_Cursor
|
|
|
|
|
|
;****************************************************************************
|
|
;*
|
|
;* NAME
|
|
;* Mono_Clear_Screen - Clear the mono screen.
|
|
;*
|
|
;* SYNOPSIS
|
|
;* Mono_Clear_Screen()
|
|
;*
|
|
;* void Mono_Clear_Screen(void);
|
|
;*
|
|
;* FUNCTION
|
|
;* Clear the mono screen and set the mono cursor to the upperleft corner
|
|
;* of the screen.
|
|
;*
|
|
;* INPUTS
|
|
;* NONE
|
|
;*
|
|
;* RESULT
|
|
;* NONE
|
|
;*
|
|
;****************************************************************************
|
|
|
|
GLOBAL C Mono_Clear_Screen:NEAR
|
|
PROC Mono_Clear_Screen C NEAR USES es eax ecx edi
|
|
|
|
; Exit if mono disabled
|
|
|
|
cmp [MonoEnabled],0
|
|
je short ??fini
|
|
|
|
; Clear the mono screen
|
|
|
|
IF PHARLAP_TNT
|
|
mov ax,034h
|
|
mov es,ax ;Set ES selector to first MB
|
|
ENDIF
|
|
|
|
mov edi,0B0000h ;EDI = Mono screen address
|
|
xor eax,eax ;Set char & attributes to 0
|
|
mov ecx,8000h/4 ;Number of longwords to clear
|
|
rep stosd ;Clear the mono screen.
|
|
call Mono_Set_Cursor C,eax,eax
|
|
|
|
??fini:
|
|
ret
|
|
|
|
ENDP Mono_Clear_Screen
|
|
|
|
|
|
;****************************************************************************
|
|
;*
|
|
;* NAME
|
|
;* Mono_Scroll - Scroll the mono screen up.
|
|
;*
|
|
;* SYNOPSIS
|
|
;* Mono_Scroll(Lines)
|
|
;*
|
|
;* void Mono_Scroll(long);
|
|
;*
|
|
;* FUNCTION
|
|
;* Move the contents of the mono screen up the specified number of lines
|
|
;* while clearing out the bottom lines.
|
|
;*
|
|
;* INPUTS
|
|
;* Lines - Number of lines to scroll the screen up.
|
|
;*
|
|
;* RESULT
|
|
;* NONE
|
|
;*
|
|
;****************************************************************************
|
|
|
|
GLOBAL C Mono_Scroll:NEAR
|
|
PROC Mono_Scroll C NEAR USES es eax ebx ecx esi edi
|
|
ARG lines:DWORD
|
|
|
|
; Exit if mono disabled
|
|
|
|
cmp [MonoEnabled],0
|
|
je short ??fini
|
|
|
|
; Exit if lines to scroll is 0.
|
|
|
|
mov eax,[lines]
|
|
or eax,eax
|
|
je short ??fini
|
|
|
|
; Move the screen data up the specified lines
|
|
|
|
mov ebx,eax
|
|
|
|
??looper:
|
|
IF PHARLAP_TNT
|
|
mov ax,034h
|
|
mov es,ax ;Set ES selector to first MB
|
|
ENDIF
|
|
|
|
push ds ;Save DS selector
|
|
mov ds,ax ;Set DS selector to first MB
|
|
|
|
mov ecx,((80*24)/2) ;Number of DWORDs to move
|
|
mov esi,0B00A0h
|
|
mov edi,0B0000h
|
|
rep movsd
|
|
|
|
pop ds ;Restore DS selector
|
|
dec [MonoY]
|
|
sub [MonoOff],(80*2)
|
|
|
|
xor eax,eax
|
|
mov ecx,(80/2)
|
|
rep stosd
|
|
|
|
dec ebx
|
|
jne ??looper
|
|
|
|
??fini:
|
|
ret
|
|
|
|
ENDP Mono_Scroll
|
|
|
|
|
|
;****************************************************************************
|
|
;*
|
|
;* NAME
|
|
;* Mono_Put_Char - Ouput a character to the mono screen.
|
|
;*
|
|
;* SYNOPSIS
|
|
;* Mono_Put_Char(Character, Attributes)
|
|
;*
|
|
;* void Mono_Put_Char(long, long);
|
|
;*
|
|
;* FUNCTION
|
|
;*
|
|
;* INPUTS
|
|
;* Character - ASCII character to output.
|
|
;* Attributes - Display attributes
|
|
;*
|
|
;* RESULT
|
|
;* NONE
|
|
;*
|
|
;****************************************************************************
|
|
|
|
GLOBAL C Mono_Put_Char:NEAR
|
|
PROC Mono_Put_Char C NEAR USES es eax edi
|
|
ARG character:DWORD
|
|
ARG attrib:DWORD
|
|
|
|
; Exit if mono disabled
|
|
|
|
cmp [MonoEnabled],0
|
|
je short ??fini
|
|
|
|
; Output character to the mono screen
|
|
|
|
cld
|
|
|
|
IF PHARLAP_TNT
|
|
mov ax,034h
|
|
mov es,ax ;Set ES selector to first MB
|
|
ENDIF
|
|
|
|
mov edi,0B0000h ;EDI = mono screen
|
|
add edi,[MonoOff] ;Add cursor offset
|
|
mov eax,[character]
|
|
mov ah,[BYTE PTR attrib]
|
|
stosw
|
|
|
|
; Update cursor position.
|
|
|
|
inc [MonoX] ; X position moves.
|
|
call Mono_Set_Cursor C,[MonoX],[MonoY]
|
|
|
|
??fini:
|
|
ret
|
|
|
|
ENDP Mono_Put_Char
|
|
|
|
|
|
;****************************************************************************
|
|
;*
|
|
;* NAME
|
|
;* Mono_Draw_Rect - Draw a box on the mono screen.
|
|
;*
|
|
;* SYNOPSIS
|
|
;* Mono_Draw_Rect(X, Y, Width, Height, Attributes, Thickness)
|
|
;*
|
|
;* void Mono_Draw_Rect();
|
|
;*
|
|
;* FUNCTION
|
|
;* Draw a rectangle text box on the mono screen.
|
|
;*
|
|
;* INPUTS
|
|
;* X - X coordinate position of upperleft corner.
|
|
;* Y - Y coordinate position of upperleft corner.
|
|
;* Width - Desired width.
|
|
;* Height - Desired height.
|
|
;* Attributes - Display attributes.
|
|
;* Thickness - Line thickness.
|
|
;*
|
|
;* RESULT
|
|
;* NONE
|
|
;*
|
|
;****************************************************************************
|
|
|
|
GLOBAL C Mono_Draw_Rect:NEAR
|
|
PROC Mono_Draw_Rect C NEAR
|
|
ARG xpos:DWORD
|
|
ARG ypos:DWORD
|
|
ARG width:DWORD
|
|
ARG height:DWORD
|
|
ARG attrib:DWORD
|
|
ARG thick:DWORD
|
|
|
|
; Exit if mono disabled
|
|
|
|
pushad
|
|
cmp [MonoEnabled],0
|
|
je ??fini
|
|
|
|
; Select the character table for the desired line thickness
|
|
|
|
mov edi,OFFSET CharData
|
|
mov cl,3
|
|
mov eax,[thick]
|
|
and eax,011b
|
|
shl eax,cl
|
|
add edi,eax
|
|
|
|
; Prep width and height.
|
|
|
|
cmp [width],2
|
|
jb ??fini
|
|
|
|
cmp [height],2
|
|
jb ??fini
|
|
|
|
sub [width],2
|
|
sub [height],2
|
|
|
|
; Set cursor position to upperleft corner of box
|
|
|
|
push [MonoY]
|
|
push [MonoX] ;Save current cursor position
|
|
call Mono_Set_Cursor C,[xpos],[ypos]
|
|
|
|
; Draw the rectangle
|
|
|
|
mov esi,OFFSET BoxData
|
|
|
|
; Determine the number of characters to output
|
|
|
|
??drawloop:
|
|
mov ecx,[width]
|
|
cmp [BYTE PTR esi+2],1
|
|
je short ??gotlen
|
|
|
|
mov ecx,[height]
|
|
cmp [BYTE PTR esi+2],2
|
|
je short ??gotlen
|
|
|
|
mov ecx,1
|
|
|
|
??gotlen:
|
|
jecxz ??donerun
|
|
|
|
??runloop:
|
|
xor eax,eax
|
|
mov al,[BYTE PTR edi]
|
|
call Mono_Put_Char C,eax,[attrib] ;Output the character.
|
|
|
|
mov al,[BYTE PTR esi+1]
|
|
cbw
|
|
cwde
|
|
add eax,[MonoY]
|
|
push eax
|
|
mov al,[BYTE PTR esi]
|
|
cbw
|
|
cwde
|
|
add eax,[MonoX]
|
|
dec eax ; Undo cursor advance.
|
|
push eax
|
|
call Mono_Set_Cursor ; Properly advance cursor.
|
|
add sp,8
|
|
loop ??runloop
|
|
|
|
; Advance to next control entry.
|
|
|
|
??donerun:
|
|
add esi,3
|
|
inc edi
|
|
cmp [BYTE PTR esi+2],-1
|
|
jne ??drawloop
|
|
|
|
; Restore cursor to original position.
|
|
|
|
call Mono_Set_Cursor
|
|
add sp,8
|
|
|
|
??fini:
|
|
popad
|
|
ret
|
|
|
|
ENDP Mono_Draw_Rect
|
|
|
|
|
|
;****************************************************************************
|
|
;*
|
|
;* NAME
|
|
;* Mono_Text_Print - Print a string to the mono screen at a specified
|
|
;* position.
|
|
;*
|
|
;* SYNOPSIS
|
|
;* Mono_Text_Print(String, X, Y, Attributes, Update)
|
|
;*
|
|
;* void Mono_Text_Print(char *, long, long, long, long);
|
|
;*
|
|
;* FUNCTION
|
|
;* Print a NULL terminated string to the mono screen at the specified
|
|
;* cooridinates and attributes.
|
|
;*
|
|
;* INPUTS
|
|
;* String - Pointer to NULL terminated string.
|
|
;* X - X coordinate position.
|
|
;* Y - Y coordinate position.
|
|
;* Attributes - Display attributes
|
|
;* Update - Update cursor position flag.
|
|
;*
|
|
;* RESULT
|
|
;* NONE
|
|
;*
|
|
;****************************************************************************
|
|
|
|
GLOBAL C _Mono_Text_Print:NEAR
|
|
PROC _Mono_Text_Print C NEAR USES eax esi
|
|
ARG text:NEAR PTR
|
|
ARG xpos:DWORD
|
|
ARG ypos:DWORD
|
|
ARG attrib:DWORD
|
|
ARG update:DWORD
|
|
|
|
; Save the current cursor position.
|
|
|
|
push [MonoY]
|
|
push [MonoX]
|
|
cmp [text],0 ;Exit if the string is NULL
|
|
je short ??fini
|
|
|
|
call Mono_Set_Cursor C,[xpos],[ypos]
|
|
|
|
; Print string to the mono screen
|
|
|
|
mov esi,[text] ;Text pointer
|
|
|
|
??charloop:
|
|
mov eax,[esi]
|
|
inc esi
|
|
or al,al ;Stop on a NULL
|
|
je short ??fini
|
|
|
|
cmp al,13 ;Special processing for '\r'
|
|
je short ??cr
|
|
|
|
; Output character to mono screen
|
|
|
|
??normal:
|
|
xor ah,ah
|
|
call Mono_Put_Char C,eax,[attrib]
|
|
|
|
; Perform adjustments if wrapping past right margin.
|
|
|
|
cmp [MonoX],80
|
|
jb short ??nowrap
|
|
|
|
inc [ypos]
|
|
call Mono_Set_Cursor C,0,[ypos]
|
|
jmp short ??nowrap
|
|
|
|
; Move to start of next line.
|
|
|
|
??cr:
|
|
inc [ypos]
|
|
call Mono_Set_Cursor C,[xpos],[ypos]
|
|
|
|
; Scroll the monochrome screen if necessary.
|
|
|
|
??nowrap:
|
|
cmp [MonoY],25
|
|
jb short ??noscroll
|
|
|
|
call Mono_Scroll C,1
|
|
dec [ypos]
|
|
|
|
??noscroll:
|
|
jmp short ??charloop
|
|
|
|
??fini:
|
|
cmp [update],0
|
|
jne short ??noupdate
|
|
|
|
call Mono_Set_Cursor
|
|
|
|
??noupdate:
|
|
pop eax
|
|
pop eax
|
|
ret
|
|
|
|
ENDP _Mono_Text_Print
|
|
|
|
|
|
;****************************************************************************
|
|
;*
|
|
;* NAME
|
|
;* Mono_Text_Print - Print a string to the mono screen. (ASM call)
|
|
;*
|
|
;* SYNOPSIS
|
|
;* Mono_Text_Print(String, X, Y, Attributes)
|
|
;*
|
|
;* void Mono_Text_Print(char *, long, long, long);
|
|
;*
|
|
;* FUNCTION
|
|
;* Print a NULL terminated string to the mono screen at the specified
|
|
;* cooridinates and attributes.
|
|
;*
|
|
;* INPUTS
|
|
;* String - Pointer to NULL terminated string.
|
|
;* X - X coordinate position.
|
|
;* Y - Y coordinate position.
|
|
;* Attributes - Display attributes
|
|
;*
|
|
;* RESULT
|
|
;* NONE
|
|
;*
|
|
;* SEE ALSO
|
|
;* _Mono_Text_Print
|
|
;*
|
|
;****************************************************************************
|
|
|
|
GLOBAL C Mono_Text_Print:NEAR
|
|
PROC Mono_Text_Print C NEAR USES
|
|
ARG text:NEAR PTR
|
|
ARG xpos:DWORD
|
|
ARG ypos:DWORD
|
|
ARG attrib:DWORD
|
|
|
|
; Exit if mono disabled
|
|
|
|
cmp [MonoEnabled],0
|
|
je short ??fini
|
|
|
|
call _Mono_Text_Print C,[text],[xpos],[ypos],[attrib],0
|
|
|
|
??fini:
|
|
ret
|
|
|
|
ENDP Mono_Text_Print
|
|
|
|
|
|
;****************************************************************************
|
|
;*
|
|
;* NAME
|
|
;* Mono_Print - Print a string to the mono screen.
|
|
;*
|
|
;* SYNOPSIS
|
|
;* Mono_Print(String)
|
|
;*
|
|
;* void Mono_Print(char *);
|
|
;*
|
|
;* FUNCTION
|
|
;* Print a string to the mono screen at the current cursor position and
|
|
;* update the cursor position.
|
|
;*
|
|
;* INPUTS
|
|
;* String - Pointer to NULL terminated string.
|
|
;*
|
|
;* RESULT
|
|
;* NONE
|
|
;*
|
|
;****************************************************************************
|
|
|
|
GLOBAL C Mono_Print:NEAR
|
|
PROC Mono_Print C NEAR
|
|
ARG text:NEAR PTR
|
|
|
|
; Exit if mono disabled
|
|
|
|
cmp [MonoEnabled],0
|
|
je short ??fini
|
|
|
|
call _Mono_Text_Print C,[text],[MonoX],[MonoY],2,1
|
|
|
|
??fini:
|
|
ret
|
|
|
|
ENDP Mono_Print
|
|
|
|
|
|
;****************************************************************************
|
|
;*
|
|
;* NAME
|
|
;* Mono_View_Page - View a mono page.
|
|
;*
|
|
;* SYNOPSIS
|
|
;* Oldpage = Mono_View_Page(Page)
|
|
;*
|
|
;* long Mono_View_Page(long);
|
|
;*
|
|
;* FUNCTION
|
|
;* Displays the specified page in displayable mono memory.
|
|
;*
|
|
;* INPUTS
|
|
;* Page - Page to view.
|
|
;*
|
|
;* RESULT
|
|
;* Oldpage - Previous page.
|
|
;*
|
|
;****************************************************************************
|
|
|
|
GLOBAL C Mono_View_Page:NEAR
|
|
PROC Mono_View_Page C NEAR USES ds es eax ebx ecx edi esi
|
|
ARG page:DWORD
|
|
LOCAL oldpage:DWORD
|
|
|
|
; Prepare the original page number for return to caller.
|
|
|
|
cld
|
|
mov ebx,[PageMap]
|
|
mov [oldpage],ebx
|
|
|
|
; Exit of mono disabled
|
|
|
|
cmp [MonoEnabled],0
|
|
je short ??fini
|
|
|
|
; If the desired page is already displayed, then don't do anything.
|
|
|
|
mov eax,[page]
|
|
cmp eax,ebx
|
|
je short ??fini
|
|
|
|
; Verify that page specified is legal.
|
|
|
|
cmp eax,7
|
|
ja short ??fini
|
|
|
|
; Find where the logical page to display is actually located.
|
|
|
|
mov ecx,8
|
|
push ds
|
|
pop es
|
|
lea edi,[PageMap]
|
|
repne scasw
|
|
neg ecx
|
|
add ecx,7 ; CX = where desired page is located.
|
|
|
|
; Swap the page ID bytes in the PageMap array.
|
|
|
|
sub edi,4
|
|
mov ebx,[PageMap]
|
|
mov eax,[edi]
|
|
mov [edi],ebx
|
|
mov [PageMap],eax
|
|
|
|
shl ecx,8
|
|
add ecx,eax
|
|
mov esi,ecx
|
|
|
|
IF PHARLAP_TNT
|
|
mov ax,034h
|
|
mov ds,ax
|
|
ENDIF
|
|
|
|
mov edi,0B0000h
|
|
|
|
; Exchange the two pages.
|
|
|
|
mov ecx,1000H/4
|
|
|
|
??looper:
|
|
mov edx,[edi]
|
|
mov ebx,[esi]
|
|
mov [edi],ebx
|
|
mov [esi],edx
|
|
add esi,4
|
|
add edi,4
|
|
loop ??looper
|
|
|
|
; Return with the original page number.
|
|
|
|
??fini:
|
|
mov eax,[oldpage]
|
|
ret
|
|
|
|
ENDP Mono_View_Page
|
|
|
|
END
|
|
|