| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845 |
- ;
- ; 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 **
- ;***************************************************************************
- ;* *
- ;* Project Name : Mono Screen system *
- ;* *
- ;* File Name : MONO.ASM *
- ;* *
- ;* Programmer : Jeff Wilson *
- ;* *
- ;* Start Date : March 28, 1994 *
- ;* *
- ;* Last Update : September 8, 1994 [IML] *
- ;* *
- ;*-------------------------------------------------------------------------*
- ;* Functions: *
- ;GLOBAL MonoScreen :DWORD
- ;GLOBAL MonoEnabled :DWORD
- ;
- ;GLOBAL C Mono_Set_Cursor :NEAR
- ;GLOBAL C Mono_Clear_Screen :NEAR
- ;GLOBAL C Mono_Scroll :NEAR
- ;GLOBAL C Mono_Put_Char :NEAR
- ;GLOBAL C Mono_Draw_Rect :NEAR
- ;
- ;GLOBAL C _Mono_Text_Print :NEAR
- ;GLOBAL C Mono_Text_Print :NEAR
- ;
- ;GLOBAL C Mono_Print :NEAR
- ;
- ;GLOBAL C Mono_View_Page :NEAR
- ;* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - *
- IDEAL
- P386
- MODEL USE32 FLAT
- LOCALS ??
- ;
- ; External declares so these functions can be called
- ;
- GLOBAL MonoScreen :DWORD
- GLOBAL MonoEnabled :DWORD
- GLOBAL Mono_Set_Cursor :NEAR ; done
- GLOBAL Mono_Clear_Screen :NEAR ; done
- GLOBAL Mono_Scroll :NEAR ; done
- GLOBAL Mono_Put_Char :NEAR ; done
- GLOBAL Mono_Draw_Rect :NEAR ; done
- GLOBAL _Mono_Text_Print :NEAR ; done
- GLOBAL Mono_Text_Print :NEAR ; done
- GLOBAL Mono_Print :NEAR ; done
- GLOBAL Mono_View_Page :NEAR ; done
- ;
- ; Equates used in this file
- ;
- NULL = 0 ; null code
- CR = 13 ; carriage return code
- CPL = 80 ; characters per line
- LPS = 25 ; lines per screen
- DATASEG
- MonoX DD 0
- MonoY DD 0
- MonoOff DD 0
- MonoScreen DD 0b0000h ;Deffault to Real mode!
- MonoEnabled DD 0 ; Is mono printing enabled?
- ;====================================================================
- 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.
- ; Mono page segment layout array.
- PageMap DD 0,1,2,3,4,5,6,7
- ;===================================================================
- CODESEG
- ;***************************************************************************
- ;* Map_Segment_To_Address_ -- Translate a 16bit Seg:Offset address to a *
- ;* Linear address. *
- ;* *
- ;* *
- ;* *
- ;* INPUT: *
- ;* *
- ;* OUTPUT: *
- ;* *
- ;* WARNINGS: *
- ;* *
- ;* HISTORY: *
- ;*=========================================================================*
- ; int Map_Segment_To_Address ( unsigned seg , unsigned offset );
- ;***************************************************************************
- ;* MONO_SET_CURSOR -- Sets the mono cursor to specified coordinates. *
- ;* *
- ;* *
- ;* *
- ;* INPUT: *
- ;* *
- ;* OUTPUT: *
- ;* *
- ;* WARNINGS: *
- ;* *
- ;* HISTORY: *
- ;*=========================================================================*
- ; void Mono_Set_Cursor(int x, int y);
- PROC Mono_Set_Cursor C near
- USES eax , ebx , edx
- ARG xpos : DWORD
- ARG ypos : DWORD
- cmp [MonoEnabled],0
- je ??exit
- ; mov ax,cs
- ; and ax,7
- ; or ax,SS_DATA
- ; mov ds,ax
- ; mov es,ax
- ; sub eax,eax
- mov eax,[ypos]
- ; mov ah,CPL
- ; imul ah
- lea eax , [ eax + 4 * eax ] ; multiply by CPL
- shl eax , 4
- ; sub ebx,ebx
- mov ebx,[xpos]
- add ebx,eax
- ; Update cursor position.
- mov edx,03B4h
- mov al,0Eh ; High byte register set.
- out dx,al
- inc edx
- mov al,bh
- out dx,al ; Set high byte.
- dec edx
- mov al,0Fh ; Low byte register set.
- out dx,al
- inc edx
- 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
- ??exit:
- ret
- ENDP Mono_Set_Cursor
- ;***************************************************************************
- ;* MONO_CLEAR_SCREEN -- Clears the mono screen and homes cursor. *
- ;* *
- ;* *
- ;* *
- ;* INPUT: *
- ;* *
- ;* OUTPUT: *
- ;* *
- ;* WARNINGS: *
- ;* *
- ;* HISTORY: *
- ;*=========================================================================*
- ; void Mono_Clear_Screen(void);
- PROC Mono_Clear_Screen C near
-
- USES eax , ecx , edi
- cmp [MonoEnabled],0
- je ??exit
- ; mov ax,cs
- ; and ax,7
- ; or ax,SS_DATA
- ; mov ds,ax
- ; mov es,ax
- ; mov eax,[MonoScreen] ; ES:DI = Mono RAM address.
- ; mov es,ax
- ; sub edi,edi
- mov edi , [ MonoScreen ]
- mov eax,02000200h ; Clear leave attrib bit normal.
- mov ecx,8000h/4 ; Number of longs to clear.
- rep stosd ; Clear the mono screen.
- push 0
- push 0
- call Mono_Set_Cursor
- add esp , 8
- ??exit:
- ret
- ENDP Mono_Clear_Screen
- ;***************************************************************************
- ;* MONO_SCROLL -- Scroll the mono screen up specified lines. *
- ;* *
- ;* *
- ;* *
- ;* INPUT: *
- ;* *
- ;* OUTPUT: *
- ;* *
- ;* WARNINGS: *
- ;* *
- ;* HISTORY: *
- ;*=========================================================================*
- ; void Mono_Scroll(DWORD lines);
- PROC Mono_Scroll C near
- USES eax , ebx , ecx , edx , edi , esi
- ARG lines : DWORD
- cmp [MonoEnabled],0
- je ??exit
- ; mov ax,cs
- ; and ax,7
- ; or ax,SS_DATA
- ; mov ds,ax
- ; mov es,ax
- ; xor eax,eax ; clear eax so no need for sign extend
- mov eax, [lines] ; get lines available
- or eax,eax ; any lines to scroll?
- je short ??fini ; =>NO
- mov ebx,eax ; set line counter
-
- mov edx,[MonoY] ; get row count
- ror edx,16 ; store it in high half of register
- mov dx,[WORD PTR MonoOff] ; get column offset
- ror edx,16
-
- ; mov eax,[MonoScreen] ; get selector for mono screen
- ; push ds ; save off data seg for later
- ; mov ds,ax ; set data source register
- ; mov es,ax ; and extra source register
- sub eax,eax ; set to clear clear line
-
- ??looper:
- mov ecx,(80*24) ; Number of words to move.
- ; xor edi,edi ; dst start at top of screen area
- ; mov esi,80*2 ; src start at next line down
- mov edi , [ MonoScreen ]
- lea esi , [ 80 * 2 + edi ]
- rep movsw ; Scroll the screen upward.
- dec dx ; decrement Y counter
- ror edx,16 ; switch to mono offset
- sub dx,80*2 ; fix MonoOffset
- ror edx,16 ; switch to y counter
- mov ecx,40 ; Clear out the last line.
- rep stosd ; by storing words across it
- dec ebx ; last line?
- jne ??looper ; =>NO
- ; reset data values
- ; pop ds ; restore the ds segment
- mov [WORD PTR MonoY],dx ; store of the mono y position
- ror edx,16 ; switch to screen offset
- mov [WORD PTR MonoOff],dx ; store of the mono offset
-
- ??fini:
- ??exit:
- ret
- ENDP Mono_Scroll
- ;***************************************************************************
- ;* MONO_PUT_CHAR -- Output a character to the mono screen. *
- ;* *
- ;* *
- ;* *
- ;* INPUT: *
- ;* *
- ;* OUTPUT: *
- ;* *
- ;* WARNINGS: *
- ;* *
- ;* HISTORY: *
- ;*=========================================================================*
- ; void Mono_Put_Char(char character, int attrib=2);
- PROC Mono_Put_Char C near
- USES eax , edi
- ARG character : BYTE
- ARG attrib : DWORD
- cmp [MonoEnabled],0
- je ??exit
-
- ; mov ax,cs
- ; and ax,7
- ; or ax,SS_DATA
- ; mov ds,ax
- mov edi,[MonoOff]
- ; mov eax,[MonoScreen]
- ; mov es,ax ; ES:DI = First character output pointer.
- add edi , [ MonoScreen ]
- ; Output character to monochrome monitor.
- mov al,[character]
- mov ah,[BYTE PTR attrib]
- ; stosw
- mov [ edi ] , ax
- ; Update cursor position.
- inc [MonoX] ; X position moves.
- mov eax,[MonoY]
- push eax
- mov eax,[MonoX]
- push eax
- call Mono_Set_Cursor
- add esp,8
- ??exit:
- ret
- ENDP Mono_Put_Char
- ;***************************************************************************
- ;* MONO_DRAW_RECT -- Draw a rectangle using mono characters. *
- ;* *
- ;* *
- ;* *
- ;* INPUT: *
- ;* *
- ;* OUTPUT: *
- ;* *
- ;* WARNINGS: *
- ;* *
- ;* HISTORY: *
- ;*=========================================================================*
- ; void Mono_Draw_Rect(int x, int y, int w, int h, int attrib=2, int thick=0);
- PROC Mono_Draw_Rect C near
- USES eax , ebx , ecx , esi , edi
- ARG xpos:DWORD
- ARG ypos:DWORD
- ARG width:DWORD
- ARG height:DWORD
- ARG attrib:DWORD
- ARG thick:DWORD
- cmp [MonoEnabled],0
- je ??exit
- ; mov ax,cs
- ; and ax,7
- ; or ax,SS_DATA
- ; mov ds,ax
- ; mov es,ax
- mov esi,OFFSET BoxData
- mov edi,OFFSET CharData
- ; mov cl,3
- ; sub eax,eax
- mov eax,[thick]
- and eax,011b
- shl eax,3
- add edi,eax
- ; Prep width and height.
- cmp [width],2
- jb ??fini
- cmp [height],2
- jb ??fini
- sub [width],2
- sub [height],2
- ; Preserve cursor position for later restore.
- mov ecx,[MonoX]
- push ecx
- mov ecx,[MonoY]
- push ecx
- ; Cursor starts at upper left corner.
- mov ecx,[ypos]
- push ecx
- mov ecx,[xpos]
- push ecx
- call Mono_Set_Cursor
- add esp,8
- ??drawloop:
- ; Determine the number of characters to output.
- 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:
- sub ebx,ebx
- mov bl,[BYTE PTR edi]
- ; mov ebx,eax
- sub eax,eax
- mov al,[BYTE PTR attrib]
- push eax
- push ebx
- call Mono_Put_Char
- add esp,8
- movsx eax,[BYTE PTR esi+1]
- ; cbw
- add eax,[MonoY]
- push eax
- movsx eax,[BYTE PTR esi]
- ; cbw
- add eax,[MonoX]
- dec eax ; Undo cursor advance.
- push eax
- call Mono_Set_Cursor ; Properly advance cursor.
- add esp,8
- loop ??runloop
- ??donerun:
- ; Advance to next control entry.
- add esi,3
- inc edi
- cmp [BYTE PTR esi+2],-1
- jne ??drawloop
- ; Restore cursor to original position.
- call Mono_Set_Cursor
- add esp,8
- ??fini:
- ??exit:
- ret
- ENDP Mono_Draw_Rect
- ;***************************************************************************
- ;* MONO_TEXT_PRINT -- Prints text to the mono screen at coordinates. *
- ;* *
- ;* *
- ;* *
- ;* INPUT: *
- ;* *
- ;* OUTPUT: *
- ;* *
- ;* WARNINGS: *
- ;* *
- ;* HISTORY: *
- ;*=========================================================================*
- ; void Mono_Text_Print(void *text, int x, int y, int attrib, int update);
- PROC _Mono_Text_Print C near
- USES eax,ebx,ecx,edx,edi,esi
- ARG text:DWORD
- ARG xpos:DWORD
- ARG ypos:DWORD
- ARG attrib:DWORD
- ARG update:DWORD
- cmp [MonoEnabled],0
- je ??exit
- ; mov ax,cs
- ; and ax,7
- ; or ax,SS_DATA
- ; mov ds,ax
- ; mov es,ax
- ; Preserve cursor coordinates for later restoration.
- mov eax,[MonoY]
- push eax
- mov eax,[MonoX]
- push eax
- cmp [text],NULL
- je ??fini
- mov eax,[ypos]
- push eax
- mov eax,[xpos]
- push eax
- call Mono_Set_Cursor
- add esp,8
- mov esi,[text]
- ??charloop:
- xor eax,eax
- mov al,[BYTE PTR esi] ; Fetch character to output.
- inc esi
- ; Stop processing on a NULL character.
- or eax,eax
- je short ??fini
- ; Special processing for a '\r' characters.
- cmp eax,CR
- je short ??cr
- ; Output character to monochrome monitor.
- ??normal:
- ; xor ah,ah
- mov ebx,eax
- mov eax,[attrib]
- push eax
- push ebx
- call Mono_Put_Char
- add esp,8
- ; Perform adjustments if wrapping past right margin.
- cmp [WORD PTR MonoX],CPL
- jb short ??nowrap
- inc [ypos]
- mov eax,[ypos]
- push eax
- ; sub eax,eax
- push 0
- call Mono_Set_Cursor
- add esp,8
- jmp short ??nowrap
- ; Move to start of next line.
- ??cr:
- inc [ypos]
- mov eax,[ypos]
- push eax
- mov eax,[xpos]
- push eax
- call Mono_Set_Cursor
- add esp,8
- ; Scroll the monochrome screen if necessary.
- ??nowrap:
- cmp [MonoY],LPS
- jb short ??noscroll
- push 1
- call Mono_Scroll
- add esp,4
- dec [ypos]
- ??noscroll:
- jmp short ??charloop
- ??fini:
- cmp [update],0
- jne short ??noupdate
- call Mono_Set_Cursor
- ??noupdate:
- add esp,8
- ??exit:
- ret
- ENDP _Mono_Text_Print
- ;=====================================================================
- PROC Mono_Text_Print C near
- USES eax
- ARG text:DWORD
- ARG xpos:DWORD
- ARG ypos:DWORD
- ARG attrib:DWORD
- cmp [MonoEnabled],0
- je ??exit
- ; sub eax,eax
- push 0
- mov eax,[attrib]
- push eax
- mov eax,[ypos]
- push eax
- mov eax,[xpos]
- push eax
- mov eax,[text]
- push eax
- call _Mono_Text_Print
- add esp,20
- ??exit:
- ret
- ENDP Mono_Text_Print
- ;***************************************************************************
- ;* MONO_PRINT -- Prints text to the mono screen at current pos. *
- ;* *
- ;* *
- ;* *
- ;* INPUT: *
- ;* *
- ;* OUTPUT: *
- ;* *
- ;* WARNINGS: *
- ;* *
- ;* HISTORY: *
- ;*=========================================================================*
- ; void Mono_Print(void *text);
- PROC Mono_Print C near
-
- USES eax
- ARG text:DWORD
- cmp [MonoEnabled],0
- je ??exit
- ; mov ax,cs
- ; and ax,7
- ; or ax,SS_DATA
- ; mov ds,ax
- ; mov es,ax
- ; mov eax,1
- push 1
- ; mov eax,2
- push 2
- mov eax,[MonoY]
- push eax
- mov eax,[MonoX]
- push eax
- mov eax,[text]
- push eax
- call _Mono_Text_Print
- add esp,20
- ??exit:
- ret
- ENDP Mono_Print
- ;***************************************************************************
- ;* Mono_View_Page -- page in a mono screen *
- ;* *
- ;* Displays the specified page in displayable mono memory area. *
- ;* *
- ;* INPUT: WORD page = which page of memory we will use for storage *
- ;* *
- ;* OUTPUT: old_page *
- ;* *
- ;* WARNINGS: none. *
- ;* *
- ;* HISTORY: *
- ;*=========================================================================*
- ; int cdecl Mono_View_Page(int page);
- PROC Mono_View_Page C near
- USES eax,ebx,ecx,edx,edi,esi
- ARG page:DWORD
- LOCAL oldpage:DWORD
- cmp [MonoEnabled],0
- je ??exit
- cld
- ; mov ax,cs
- ; and ax,7
- ; or ax,SS_DATA
- ; mov ds,ax
- ; mov es,ax
- ; Prepare the original page number for return to caller.
- mov ebx,[PageMap]
- mov [oldpage],ebx
- ; 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
- mov edi,OFFSET PageMap
- repne scasd
- neg ecx
- add ecx,7 ; ECX = 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
- ; Set DS and ES to point to each page.
- ; mov eax,[MonoScreen]
- ; mov ds,ax
- mov esi , [ MonoScreen ]
- ; shl ecx,8
- shl ecx , 12
- ; add ecx,edi ; NO Addition to selectors!
- lea edi , [ esi + ecx ]
- ; mov edi,ecx
- ; xor esi,esi
- ; 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:
- ??exit:
- mov eax,[oldpage]
- ret
-
- ENDP Mono_View_Page
- END
|