MONO.ASM 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845
  1. ;
  2. ; Command & Conquer Red Alert(tm)
  3. ; Copyright 2025 Electronic Arts Inc.
  4. ;
  5. ; This program is free software: you can redistribute it and/or modify
  6. ; it under the terms of the GNU General Public License as published by
  7. ; the Free Software Foundation, either version 3 of the License, or
  8. ; (at your option) any later version.
  9. ;
  10. ; This program is distributed in the hope that it will be useful,
  11. ; but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. ; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. ; GNU General Public License for more details.
  14. ;
  15. ; You should have received a copy of the GNU General Public License
  16. ; along with this program. If not, see <http://www.gnu.org/licenses/>.
  17. ;
  18. ;***************************************************************************
  19. ;** 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 **
  20. ;***************************************************************************
  21. ;* *
  22. ;* Project Name : Mono Screen system *
  23. ;* *
  24. ;* File Name : MONO.ASM *
  25. ;* *
  26. ;* Programmer : Jeff Wilson *
  27. ;* *
  28. ;* Start Date : March 28, 1994 *
  29. ;* *
  30. ;* Last Update : September 8, 1994 [IML] *
  31. ;* *
  32. ;*-------------------------------------------------------------------------*
  33. ;* Functions: *
  34. ;GLOBAL MonoScreen :DWORD
  35. ;GLOBAL MonoEnabled :DWORD
  36. ;
  37. ;GLOBAL C Mono_Set_Cursor :NEAR
  38. ;GLOBAL C Mono_Clear_Screen :NEAR
  39. ;GLOBAL C Mono_Scroll :NEAR
  40. ;GLOBAL C Mono_Put_Char :NEAR
  41. ;GLOBAL C Mono_Draw_Rect :NEAR
  42. ;
  43. ;GLOBAL C _Mono_Text_Print :NEAR
  44. ;GLOBAL C Mono_Text_Print :NEAR
  45. ;
  46. ;GLOBAL C Mono_Print :NEAR
  47. ;
  48. ;GLOBAL C Mono_View_Page :NEAR
  49. ;* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - *
  50. IDEAL
  51. P386
  52. MODEL USE32 FLAT
  53. LOCALS ??
  54. ;
  55. ; External declares so these functions can be called
  56. ;
  57. GLOBAL MonoScreen :DWORD
  58. GLOBAL MonoEnabled :DWORD
  59. GLOBAL Mono_Set_Cursor :NEAR ; done
  60. GLOBAL Mono_Clear_Screen :NEAR ; done
  61. GLOBAL Mono_Scroll :NEAR ; done
  62. GLOBAL Mono_Put_Char :NEAR ; done
  63. GLOBAL Mono_Draw_Rect :NEAR ; done
  64. GLOBAL _Mono_Text_Print :NEAR ; done
  65. GLOBAL Mono_Text_Print :NEAR ; done
  66. GLOBAL Mono_Print :NEAR ; done
  67. GLOBAL Mono_View_Page :NEAR ; done
  68. ;
  69. ; Equates used in this file
  70. ;
  71. NULL = 0 ; null code
  72. CR = 13 ; carriage return code
  73. CPL = 80 ; characters per line
  74. LPS = 25 ; lines per screen
  75. DATASEG
  76. MonoX DD 0
  77. MonoY DD 0
  78. MonoOff DD 0
  79. MonoScreen DD 0b0000h ;Deffault to Real mode!
  80. MonoEnabled DD 0 ; Is mono printing enabled?
  81. ;====================================================================
  82. CharData DB 0DAh,0C4h,0BFh,0B3h,0D9h,0C4h,0C0h,0B3h ; Single line
  83. DB 0D5h,0CDh,0B8h,0B3h,0BEh,0CDh,0D4h,0B3h ; Double horz.
  84. DB 0D6h,0C4h,0B7h,0BAh,0BDh,0C4h,0D3h,0BAh ; Double vert.
  85. DB 0C9h,0CDh,0BBh,0BAh,0BCh,0CDh,0C8h,0BAh ; Double line.
  86. ; x,y,dist
  87. BoxData DB 1,0,0 ; Upper left corner.
  88. DB 1,0,1 ; Top edge.
  89. DB 0,1,0 ; Upper right corner.
  90. DB 0,1,2 ; Right edge.
  91. DB -1,0,0 ; Bottom right corner.
  92. DB -1,0,1 ; Bottom edge.
  93. DB 0,-1,0 ; Bottom left corner.
  94. DB 0,-1,2 ; Left edge.
  95. DB 0,0,-1 ; End of list.
  96. ; Mono page segment layout array.
  97. PageMap DD 0,1,2,3,4,5,6,7
  98. ;===================================================================
  99. CODESEG
  100. ;***************************************************************************
  101. ;* Map_Segment_To_Address_ -- Translate a 16bit Seg:Offset address to a *
  102. ;* Linear address. *
  103. ;* *
  104. ;* *
  105. ;* *
  106. ;* INPUT: *
  107. ;* *
  108. ;* OUTPUT: *
  109. ;* *
  110. ;* WARNINGS: *
  111. ;* *
  112. ;* HISTORY: *
  113. ;*=========================================================================*
  114. ; int Map_Segment_To_Address ( unsigned seg , unsigned offset );
  115. ;***************************************************************************
  116. ;* MONO_SET_CURSOR -- Sets the mono cursor to specified coordinates. *
  117. ;* *
  118. ;* *
  119. ;* *
  120. ;* INPUT: *
  121. ;* *
  122. ;* OUTPUT: *
  123. ;* *
  124. ;* WARNINGS: *
  125. ;* *
  126. ;* HISTORY: *
  127. ;*=========================================================================*
  128. ; void Mono_Set_Cursor(int x, int y);
  129. PROC Mono_Set_Cursor C near
  130. USES eax , ebx , edx
  131. ARG xpos : DWORD
  132. ARG ypos : DWORD
  133. cmp [MonoEnabled],0
  134. je ??exit
  135. ; mov ax,cs
  136. ; and ax,7
  137. ; or ax,SS_DATA
  138. ; mov ds,ax
  139. ; mov es,ax
  140. ; sub eax,eax
  141. mov eax,[ypos]
  142. ; mov ah,CPL
  143. ; imul ah
  144. lea eax , [ eax + 4 * eax ] ; multiply by CPL
  145. shl eax , 4
  146. ; sub ebx,ebx
  147. mov ebx,[xpos]
  148. add ebx,eax
  149. ; Update cursor position.
  150. mov edx,03B4h
  151. mov al,0Eh ; High byte register set.
  152. out dx,al
  153. inc edx
  154. mov al,bh
  155. out dx,al ; Set high byte.
  156. dec edx
  157. mov al,0Fh ; Low byte register set.
  158. out dx,al
  159. inc edx
  160. mov al,bl
  161. out dx,al ; Set low byte.
  162. ; Update the globals.
  163. add ebx,ebx
  164. mov [MonoOff],ebx
  165. mov eax,[xpos]
  166. mov [MonoX],eax
  167. mov eax,[ypos]
  168. mov [MonoY],eax
  169. ??exit:
  170. ret
  171. ENDP Mono_Set_Cursor
  172. ;***************************************************************************
  173. ;* MONO_CLEAR_SCREEN -- Clears the mono screen and homes cursor. *
  174. ;* *
  175. ;* *
  176. ;* *
  177. ;* INPUT: *
  178. ;* *
  179. ;* OUTPUT: *
  180. ;* *
  181. ;* WARNINGS: *
  182. ;* *
  183. ;* HISTORY: *
  184. ;*=========================================================================*
  185. ; void Mono_Clear_Screen(void);
  186. PROC Mono_Clear_Screen C near
  187. USES eax , ecx , edi
  188. cmp [MonoEnabled],0
  189. je ??exit
  190. ; mov ax,cs
  191. ; and ax,7
  192. ; or ax,SS_DATA
  193. ; mov ds,ax
  194. ; mov es,ax
  195. ; mov eax,[MonoScreen] ; ES:DI = Mono RAM address.
  196. ; mov es,ax
  197. ; sub edi,edi
  198. mov edi , [ MonoScreen ]
  199. mov eax,02000200h ; Clear leave attrib bit normal.
  200. mov ecx,8000h/4 ; Number of longs to clear.
  201. rep stosd ; Clear the mono screen.
  202. push 0
  203. push 0
  204. call Mono_Set_Cursor
  205. add esp , 8
  206. ??exit:
  207. ret
  208. ENDP Mono_Clear_Screen
  209. ;***************************************************************************
  210. ;* MONO_SCROLL -- Scroll the mono screen up specified lines. *
  211. ;* *
  212. ;* *
  213. ;* *
  214. ;* INPUT: *
  215. ;* *
  216. ;* OUTPUT: *
  217. ;* *
  218. ;* WARNINGS: *
  219. ;* *
  220. ;* HISTORY: *
  221. ;*=========================================================================*
  222. ; void Mono_Scroll(DWORD lines);
  223. PROC Mono_Scroll C near
  224. USES eax , ebx , ecx , edx , edi , esi
  225. ARG lines : DWORD
  226. cmp [MonoEnabled],0
  227. je ??exit
  228. ; mov ax,cs
  229. ; and ax,7
  230. ; or ax,SS_DATA
  231. ; mov ds,ax
  232. ; mov es,ax
  233. ; xor eax,eax ; clear eax so no need for sign extend
  234. mov eax, [lines] ; get lines available
  235. or eax,eax ; any lines to scroll?
  236. je short ??fini ; =>NO
  237. mov ebx,eax ; set line counter
  238. mov edx,[MonoY] ; get row count
  239. ror edx,16 ; store it in high half of register
  240. mov dx,[WORD PTR MonoOff] ; get column offset
  241. ror edx,16
  242. ; mov eax,[MonoScreen] ; get selector for mono screen
  243. ; push ds ; save off data seg for later
  244. ; mov ds,ax ; set data source register
  245. ; mov es,ax ; and extra source register
  246. sub eax,eax ; set to clear clear line
  247. ??looper:
  248. mov ecx,(80*24) ; Number of words to move.
  249. ; xor edi,edi ; dst start at top of screen area
  250. ; mov esi,80*2 ; src start at next line down
  251. mov edi , [ MonoScreen ]
  252. lea esi , [ 80 * 2 + edi ]
  253. rep movsw ; Scroll the screen upward.
  254. dec dx ; decrement Y counter
  255. ror edx,16 ; switch to mono offset
  256. sub dx,80*2 ; fix MonoOffset
  257. ror edx,16 ; switch to y counter
  258. mov ecx,40 ; Clear out the last line.
  259. rep stosd ; by storing words across it
  260. dec ebx ; last line?
  261. jne ??looper ; =>NO
  262. ; reset data values
  263. ; pop ds ; restore the ds segment
  264. mov [WORD PTR MonoY],dx ; store of the mono y position
  265. ror edx,16 ; switch to screen offset
  266. mov [WORD PTR MonoOff],dx ; store of the mono offset
  267. ??fini:
  268. ??exit:
  269. ret
  270. ENDP Mono_Scroll
  271. ;***************************************************************************
  272. ;* MONO_PUT_CHAR -- Output a character to the mono screen. *
  273. ;* *
  274. ;* *
  275. ;* *
  276. ;* INPUT: *
  277. ;* *
  278. ;* OUTPUT: *
  279. ;* *
  280. ;* WARNINGS: *
  281. ;* *
  282. ;* HISTORY: *
  283. ;*=========================================================================*
  284. ; void Mono_Put_Char(char character, int attrib=2);
  285. PROC Mono_Put_Char C near
  286. USES eax , edi
  287. ARG character : BYTE
  288. ARG attrib : DWORD
  289. cmp [MonoEnabled],0
  290. je ??exit
  291. ; mov ax,cs
  292. ; and ax,7
  293. ; or ax,SS_DATA
  294. ; mov ds,ax
  295. mov edi,[MonoOff]
  296. ; mov eax,[MonoScreen]
  297. ; mov es,ax ; ES:DI = First character output pointer.
  298. add edi , [ MonoScreen ]
  299. ; Output character to monochrome monitor.
  300. mov al,[character]
  301. mov ah,[BYTE PTR attrib]
  302. ; stosw
  303. mov [ edi ] , ax
  304. ; Update cursor position.
  305. inc [MonoX] ; X position moves.
  306. mov eax,[MonoY]
  307. push eax
  308. mov eax,[MonoX]
  309. push eax
  310. call Mono_Set_Cursor
  311. add esp,8
  312. ??exit:
  313. ret
  314. ENDP Mono_Put_Char
  315. ;***************************************************************************
  316. ;* MONO_DRAW_RECT -- Draw a rectangle using mono characters. *
  317. ;* *
  318. ;* *
  319. ;* *
  320. ;* INPUT: *
  321. ;* *
  322. ;* OUTPUT: *
  323. ;* *
  324. ;* WARNINGS: *
  325. ;* *
  326. ;* HISTORY: *
  327. ;*=========================================================================*
  328. ; void Mono_Draw_Rect(int x, int y, int w, int h, int attrib=2, int thick=0);
  329. PROC Mono_Draw_Rect C near
  330. USES eax , ebx , ecx , esi , edi
  331. ARG xpos:DWORD
  332. ARG ypos:DWORD
  333. ARG width:DWORD
  334. ARG height:DWORD
  335. ARG attrib:DWORD
  336. ARG thick:DWORD
  337. cmp [MonoEnabled],0
  338. je ??exit
  339. ; mov ax,cs
  340. ; and ax,7
  341. ; or ax,SS_DATA
  342. ; mov ds,ax
  343. ; mov es,ax
  344. mov esi,OFFSET BoxData
  345. mov edi,OFFSET CharData
  346. ; mov cl,3
  347. ; sub eax,eax
  348. mov eax,[thick]
  349. and eax,011b
  350. shl eax,3
  351. add edi,eax
  352. ; Prep width and height.
  353. cmp [width],2
  354. jb ??fini
  355. cmp [height],2
  356. jb ??fini
  357. sub [width],2
  358. sub [height],2
  359. ; Preserve cursor position for later restore.
  360. mov ecx,[MonoX]
  361. push ecx
  362. mov ecx,[MonoY]
  363. push ecx
  364. ; Cursor starts at upper left corner.
  365. mov ecx,[ypos]
  366. push ecx
  367. mov ecx,[xpos]
  368. push ecx
  369. call Mono_Set_Cursor
  370. add esp,8
  371. ??drawloop:
  372. ; Determine the number of characters to output.
  373. mov ecx,[width]
  374. cmp [BYTE PTR esi+2],1
  375. je short ??gotlen
  376. mov ecx,[height]
  377. cmp [BYTE PTR esi+2],2
  378. je short ??gotlen
  379. mov ecx,1
  380. ??gotlen:
  381. jecxz ??donerun
  382. ??runloop:
  383. sub ebx,ebx
  384. mov bl,[BYTE PTR edi]
  385. ; mov ebx,eax
  386. sub eax,eax
  387. mov al,[BYTE PTR attrib]
  388. push eax
  389. push ebx
  390. call Mono_Put_Char
  391. add esp,8
  392. movsx eax,[BYTE PTR esi+1]
  393. ; cbw
  394. add eax,[MonoY]
  395. push eax
  396. movsx eax,[BYTE PTR esi]
  397. ; cbw
  398. add eax,[MonoX]
  399. dec eax ; Undo cursor advance.
  400. push eax
  401. call Mono_Set_Cursor ; Properly advance cursor.
  402. add esp,8
  403. loop ??runloop
  404. ??donerun:
  405. ; Advance to next control entry.
  406. add esi,3
  407. inc edi
  408. cmp [BYTE PTR esi+2],-1
  409. jne ??drawloop
  410. ; Restore cursor to original position.
  411. call Mono_Set_Cursor
  412. add esp,8
  413. ??fini:
  414. ??exit:
  415. ret
  416. ENDP Mono_Draw_Rect
  417. ;***************************************************************************
  418. ;* MONO_TEXT_PRINT -- Prints text to the mono screen at coordinates. *
  419. ;* *
  420. ;* *
  421. ;* *
  422. ;* INPUT: *
  423. ;* *
  424. ;* OUTPUT: *
  425. ;* *
  426. ;* WARNINGS: *
  427. ;* *
  428. ;* HISTORY: *
  429. ;*=========================================================================*
  430. ; void Mono_Text_Print(void *text, int x, int y, int attrib, int update);
  431. PROC _Mono_Text_Print C near
  432. USES eax,ebx,ecx,edx,edi,esi
  433. ARG text:DWORD
  434. ARG xpos:DWORD
  435. ARG ypos:DWORD
  436. ARG attrib:DWORD
  437. ARG update:DWORD
  438. cmp [MonoEnabled],0
  439. je ??exit
  440. ; mov ax,cs
  441. ; and ax,7
  442. ; or ax,SS_DATA
  443. ; mov ds,ax
  444. ; mov es,ax
  445. ; Preserve cursor coordinates for later restoration.
  446. mov eax,[MonoY]
  447. push eax
  448. mov eax,[MonoX]
  449. push eax
  450. cmp [text],NULL
  451. je ??fini
  452. mov eax,[ypos]
  453. push eax
  454. mov eax,[xpos]
  455. push eax
  456. call Mono_Set_Cursor
  457. add esp,8
  458. mov esi,[text]
  459. ??charloop:
  460. xor eax,eax
  461. mov al,[BYTE PTR esi] ; Fetch character to output.
  462. inc esi
  463. ; Stop processing on a NULL character.
  464. or eax,eax
  465. je short ??fini
  466. ; Special processing for a '\r' characters.
  467. cmp eax,CR
  468. je short ??cr
  469. ; Output character to monochrome monitor.
  470. ??normal:
  471. ; xor ah,ah
  472. mov ebx,eax
  473. mov eax,[attrib]
  474. push eax
  475. push ebx
  476. call Mono_Put_Char
  477. add esp,8
  478. ; Perform adjustments if wrapping past right margin.
  479. cmp [WORD PTR MonoX],CPL
  480. jb short ??nowrap
  481. inc [ypos]
  482. mov eax,[ypos]
  483. push eax
  484. ; sub eax,eax
  485. push 0
  486. call Mono_Set_Cursor
  487. add esp,8
  488. jmp short ??nowrap
  489. ; Move to start of next line.
  490. ??cr:
  491. inc [ypos]
  492. mov eax,[ypos]
  493. push eax
  494. mov eax,[xpos]
  495. push eax
  496. call Mono_Set_Cursor
  497. add esp,8
  498. ; Scroll the monochrome screen if necessary.
  499. ??nowrap:
  500. cmp [MonoY],LPS
  501. jb short ??noscroll
  502. push 1
  503. call Mono_Scroll
  504. add esp,4
  505. dec [ypos]
  506. ??noscroll:
  507. jmp short ??charloop
  508. ??fini:
  509. cmp [update],0
  510. jne short ??noupdate
  511. call Mono_Set_Cursor
  512. ??noupdate:
  513. add esp,8
  514. ??exit:
  515. ret
  516. ENDP _Mono_Text_Print
  517. ;=====================================================================
  518. PROC Mono_Text_Print C near
  519. USES eax
  520. ARG text:DWORD
  521. ARG xpos:DWORD
  522. ARG ypos:DWORD
  523. ARG attrib:DWORD
  524. cmp [MonoEnabled],0
  525. je ??exit
  526. ; sub eax,eax
  527. push 0
  528. mov eax,[attrib]
  529. push eax
  530. mov eax,[ypos]
  531. push eax
  532. mov eax,[xpos]
  533. push eax
  534. mov eax,[text]
  535. push eax
  536. call _Mono_Text_Print
  537. add esp,20
  538. ??exit:
  539. ret
  540. ENDP Mono_Text_Print
  541. ;***************************************************************************
  542. ;* MONO_PRINT -- Prints text to the mono screen at current pos. *
  543. ;* *
  544. ;* *
  545. ;* *
  546. ;* INPUT: *
  547. ;* *
  548. ;* OUTPUT: *
  549. ;* *
  550. ;* WARNINGS: *
  551. ;* *
  552. ;* HISTORY: *
  553. ;*=========================================================================*
  554. ; void Mono_Print(void *text);
  555. PROC Mono_Print C near
  556. USES eax
  557. ARG text:DWORD
  558. cmp [MonoEnabled],0
  559. je ??exit
  560. ; mov ax,cs
  561. ; and ax,7
  562. ; or ax,SS_DATA
  563. ; mov ds,ax
  564. ; mov es,ax
  565. ; mov eax,1
  566. push 1
  567. ; mov eax,2
  568. push 2
  569. mov eax,[MonoY]
  570. push eax
  571. mov eax,[MonoX]
  572. push eax
  573. mov eax,[text]
  574. push eax
  575. call _Mono_Text_Print
  576. add esp,20
  577. ??exit:
  578. ret
  579. ENDP Mono_Print
  580. ;***************************************************************************
  581. ;* Mono_View_Page -- page in a mono screen *
  582. ;* *
  583. ;* Displays the specified page in displayable mono memory area. *
  584. ;* *
  585. ;* INPUT: WORD page = which page of memory we will use for storage *
  586. ;* *
  587. ;* OUTPUT: old_page *
  588. ;* *
  589. ;* WARNINGS: none. *
  590. ;* *
  591. ;* HISTORY: *
  592. ;*=========================================================================*
  593. ; int cdecl Mono_View_Page(int page);
  594. PROC Mono_View_Page C near
  595. USES eax,ebx,ecx,edx,edi,esi
  596. ARG page:DWORD
  597. LOCAL oldpage:DWORD
  598. cmp [MonoEnabled],0
  599. je ??exit
  600. cld
  601. ; mov ax,cs
  602. ; and ax,7
  603. ; or ax,SS_DATA
  604. ; mov ds,ax
  605. ; mov es,ax
  606. ; Prepare the original page number for return to caller.
  607. mov ebx,[PageMap]
  608. mov [oldpage],ebx
  609. ; If the desired page is already displayed, then don't do anything.
  610. mov eax,[page]
  611. cmp eax,ebx
  612. je short ??fini
  613. ; Verify that page specified is legal.
  614. cmp eax,7
  615. ja short ??fini
  616. ; Find where the logical page to display is actually located.
  617. mov ecx,8
  618. mov edi,OFFSET PageMap
  619. repne scasd
  620. neg ecx
  621. add ecx,7 ; ECX = where desired page is located.
  622. ; Swap the page ID bytes in the PageMap array.
  623. sub edi,4
  624. mov ebx,[PageMap]
  625. mov eax,[edi]
  626. mov [edi],ebx
  627. mov [PageMap],eax
  628. ; Set DS and ES to point to each page.
  629. ; mov eax,[MonoScreen]
  630. ; mov ds,ax
  631. mov esi , [ MonoScreen ]
  632. ; shl ecx,8
  633. shl ecx , 12
  634. ; add ecx,edi ; NO Addition to selectors!
  635. lea edi , [ esi + ecx ]
  636. ; mov edi,ecx
  637. ; xor esi,esi
  638. ; Exchange the two pages.
  639. mov ecx,1000H/4
  640. ??looper:
  641. mov edx,[edi]
  642. mov ebx,[esi]
  643. mov [edi],ebx
  644. mov [esi],edx
  645. add esi,4
  646. add edi,4
  647. loop ??looper
  648. ; Return with the original page number.
  649. ??fini:
  650. ??exit:
  651. mov eax,[oldpage]
  652. ret
  653. ENDP Mono_View_Page
  654. END
  655.