| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871 |
- ;
- ; 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
|