MONO.ASM 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871
  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. ;*
  20. ;* 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
  21. ;*
  22. ;*---------------------------------------------------------------------------
  23. ;*
  24. ;* FILE
  25. ;* mono.asm
  26. ;*
  27. ;* DESCRIPTION
  28. ;* Mono screen print and output routines. (32-Bit protected mode)
  29. ;*
  30. ;* PROGRAMMER
  31. ;* Denzil E. Long, Jr.
  32. ;*
  33. ;* DATE
  34. ;* Febuary 8, 1995
  35. ;*
  36. ;*---------------------------------------------------------------------------
  37. ;*
  38. ;* PUBLIC
  39. ;* Mono_Enable - Enable mono output.
  40. ;* Mono_Disable - Disable mono output.
  41. ;* Mono_X - Get mono cursors X position.
  42. ;* Mono_Y - Get mono cursors Y position.
  43. ;* Mono_Set_Cursor - Set the mono cursor to specified coordinates.
  44. ;* Mono_Clear_Screen - Clear the mono screen.
  45. ;* Mono_Scroll - Scroll the mono screen up.
  46. ;* Mono_Put_Char - Ouput a character to the mono screen.
  47. ;* Mono_Draw_Rect - Draw a box on the mono screen.
  48. ;* Mono_Text_Print - Print a string to the mono screen at a specified
  49. ;* position.
  50. ;* Mono_Print - Print a string to the mono screen.
  51. ;* Mono_View_Page - View a mono page.
  52. ;*
  53. ;****************************************************************************
  54. IDEAL
  55. P386
  56. MODEL USE32 FLAT
  57. LOCALS ??
  58. DATASEG
  59. MonoEnabled DD 1
  60. MonoX DD 0
  61. MonoY DD 0
  62. MonoOff DD 0
  63. CharData DB 0DAh,0C4h,0BFh,0B3h,0D9h,0C4h,0C0h,0B3h ; Single line
  64. DB 0D5h,0CDh,0B8h,0B3h,0BEh,0CDh,0D4h,0B3h ; Double horz.
  65. DB 0D6h,0C4h,0B7h,0BAh,0BDh,0C4h,0D3h,0BAh ; Double vert.
  66. DB 0C9h,0CDh,0BBh,0BAh,0BCh,0CDh,0C8h,0BAh ; Double line.
  67. ; x,y,dist
  68. BoxData DB 1,0,0 ; Upper left corner.
  69. DB 1,0,1 ; Top edge.
  70. DB 0,1,0 ; Upper right corner.
  71. DB 0,1,2 ; Right edge.
  72. DB -1,0,0 ; Bottom right corner.
  73. DB -1,0,1 ; Bottom edge.
  74. DB 0,-1,0 ; Bottom left corner.
  75. DB 0,-1,2 ; Left edge.
  76. DB 0,0,-1 ; End of list.
  77. PageMap DD 0,1,2,3,4,5,6,7
  78. CODESEG
  79. ;****************************************************************************
  80. ;*
  81. ;* NAME
  82. ;* Mono_Enable - Enable mono output.
  83. ;*
  84. ;* SYNOPSIS
  85. ;* Mono_Enable()
  86. ;*
  87. ;* void Mono_Enable(void);
  88. ;*
  89. ;* FUNCTION
  90. ;* Turn on the MonoEnabled flag.
  91. ;*
  92. ;* INPUTS
  93. ;* NONE
  94. ;*
  95. ;* RESULT
  96. ;* NONE
  97. ;*
  98. ;****************************************************************************
  99. GLOBAL C Mono_Enable:NEAR
  100. PROC Mono_Enable C NEAR
  101. mov [MonoEnabled],1
  102. ret
  103. ENDP Mono_Enable
  104. ;****************************************************************************
  105. ;*
  106. ;* NAME
  107. ;* Mono_Disable - Disable mono output.
  108. ;*
  109. ;* SYNOPSIS
  110. ;* Mono_Disable()
  111. ;*
  112. ;* void Mono_Disable(void);
  113. ;*
  114. ;* FUNCTION
  115. ;* Turn off the MonoEnabled flag.
  116. ;*
  117. ;* INPUTS
  118. ;* NONE
  119. ;*
  120. ;* RESULT
  121. ;* NONE
  122. ;*
  123. ;****************************************************************************
  124. GLOBAL C Mono_Disable:NEAR
  125. PROC Mono_Disable C NEAR
  126. mov [MonoEnabled],0
  127. ret
  128. ENDP Mono_Disable
  129. ;****************************************************************************
  130. ;*
  131. ;* NAME
  132. ;* Mono_X - Get mono cursors X position.
  133. ;*
  134. ;* SYNOPSIS
  135. ;* X = Mono_X()
  136. ;*
  137. ;* long Mono_X(void);
  138. ;*
  139. ;* FUNCTION
  140. ;* Return the X position of the mono screen cursor.
  141. ;*
  142. ;* INPUTS
  143. ;* NONE
  144. ;*
  145. ;* RESULT
  146. ;* X - X coordinate position.
  147. ;*
  148. ;****************************************************************************
  149. GLOBAL C Mono_X:NEAR
  150. PROC Mono_X C NEAR
  151. mov eax,[MonoX]
  152. ret
  153. ENDP Mono_X
  154. ;****************************************************************************
  155. ;*
  156. ;* NAME
  157. ;* Mono_Y - Get mono cursors Y position.
  158. ;*
  159. ;* SYNOPSIS
  160. ;* Y = Mono_Y()
  161. ;*
  162. ;* long Mono_Y(void);
  163. ;*
  164. ;* FUNCTION
  165. ;* Return the Y position of the mono screen cursor.
  166. ;*
  167. ;* INPUTS
  168. ;* NONE
  169. ;*
  170. ;* RESULT
  171. ;* Y - Y coordinate position.
  172. ;*
  173. ;****************************************************************************
  174. GLOBAL C Mono_Y:NEAR
  175. PROC Mono_Y C NEAR
  176. mov eax,[MonoY]
  177. ret
  178. ENDP Mono_Y
  179. ;****************************************************************************
  180. ;*
  181. ;* NAME
  182. ;* Mono_Set_Cursor - Set the mono cursor to specified coordinates.
  183. ;*
  184. ;* SYNOPSIS
  185. ;* Mono_Set_Cursor(X, Y)
  186. ;*
  187. ;* void Mono_Set_Cursor(long, long);
  188. ;*
  189. ;* FUNCTION
  190. ;*
  191. ;* INPUTS
  192. ;* X - X coordinate position.
  193. ;* Y - Y coordinate position.
  194. ;*
  195. ;* RESULT
  196. ;* NONE
  197. ;*
  198. ;****************************************************************************
  199. GLOBAL C Mono_Set_Cursor:NEAR
  200. PROC Mono_Set_Cursor C NEAR USES eax ebx edx
  201. ARG xpos:DWORD
  202. ARG ypos:DWORD
  203. cmp [MonoEnabled],0
  204. je short ??fini
  205. mov eax,[ypos]
  206. mov ah,80
  207. imul ah
  208. add eax,[xpos]
  209. mov ebx,eax
  210. ; Update cursor position.
  211. mov dx,03B4h
  212. mov al,0Eh ;High byte register set.
  213. out dx,al
  214. inc dx
  215. mov al,bh
  216. out dx,al ;Set high byte.
  217. dec dx
  218. mov al,0Fh ;Low byte register set.
  219. out dx,al
  220. inc dx
  221. mov al,bl
  222. out dx,al ;Set low byte.
  223. ; Update the globals.
  224. add ebx,ebx
  225. mov [MonoOff],ebx
  226. mov eax,[xpos]
  227. mov [MonoX],eax
  228. mov eax,[ypos]
  229. mov [MonoY],eax
  230. ??fini:
  231. ret
  232. ENDP Mono_Set_Cursor
  233. ;****************************************************************************
  234. ;*
  235. ;* NAME
  236. ;* Mono_Clear_Screen - Clear the mono screen.
  237. ;*
  238. ;* SYNOPSIS
  239. ;* Mono_Clear_Screen()
  240. ;*
  241. ;* void Mono_Clear_Screen(void);
  242. ;*
  243. ;* FUNCTION
  244. ;* Clear the mono screen and set the mono cursor to the upperleft corner
  245. ;* of the screen.
  246. ;*
  247. ;* INPUTS
  248. ;* NONE
  249. ;*
  250. ;* RESULT
  251. ;* NONE
  252. ;*
  253. ;****************************************************************************
  254. GLOBAL C Mono_Clear_Screen:NEAR
  255. PROC Mono_Clear_Screen C NEAR USES es eax ecx edi
  256. ; Exit if mono disabled
  257. cmp [MonoEnabled],0
  258. je short ??fini
  259. ; Clear the mono screen
  260. IF PHARLAP_TNT
  261. mov ax,034h
  262. mov es,ax ;Set ES selector to first MB
  263. ENDIF
  264. mov edi,0B0000h ;EDI = Mono screen address
  265. xor eax,eax ;Set char & attributes to 0
  266. mov ecx,8000h/4 ;Number of longwords to clear
  267. rep stosd ;Clear the mono screen.
  268. call Mono_Set_Cursor C,eax,eax
  269. ??fini:
  270. ret
  271. ENDP Mono_Clear_Screen
  272. ;****************************************************************************
  273. ;*
  274. ;* NAME
  275. ;* Mono_Scroll - Scroll the mono screen up.
  276. ;*
  277. ;* SYNOPSIS
  278. ;* Mono_Scroll(Lines)
  279. ;*
  280. ;* void Mono_Scroll(long);
  281. ;*
  282. ;* FUNCTION
  283. ;* Move the contents of the mono screen up the specified number of lines
  284. ;* while clearing out the bottom lines.
  285. ;*
  286. ;* INPUTS
  287. ;* Lines - Number of lines to scroll the screen up.
  288. ;*
  289. ;* RESULT
  290. ;* NONE
  291. ;*
  292. ;****************************************************************************
  293. GLOBAL C Mono_Scroll:NEAR
  294. PROC Mono_Scroll C NEAR USES es eax ebx ecx esi edi
  295. ARG lines:DWORD
  296. ; Exit if mono disabled
  297. cmp [MonoEnabled],0
  298. je short ??fini
  299. ; Exit if lines to scroll is 0.
  300. mov eax,[lines]
  301. or eax,eax
  302. je short ??fini
  303. ; Move the screen data up the specified lines
  304. mov ebx,eax
  305. ??looper:
  306. IF PHARLAP_TNT
  307. mov ax,034h
  308. mov es,ax ;Set ES selector to first MB
  309. ENDIF
  310. push ds ;Save DS selector
  311. mov ds,ax ;Set DS selector to first MB
  312. mov ecx,((80*24)/2) ;Number of DWORDs to move
  313. mov esi,0B00A0h
  314. mov edi,0B0000h
  315. rep movsd
  316. pop ds ;Restore DS selector
  317. dec [MonoY]
  318. sub [MonoOff],(80*2)
  319. xor eax,eax
  320. mov ecx,(80/2)
  321. rep stosd
  322. dec ebx
  323. jne ??looper
  324. ??fini:
  325. ret
  326. ENDP Mono_Scroll
  327. ;****************************************************************************
  328. ;*
  329. ;* NAME
  330. ;* Mono_Put_Char - Ouput a character to the mono screen.
  331. ;*
  332. ;* SYNOPSIS
  333. ;* Mono_Put_Char(Character, Attributes)
  334. ;*
  335. ;* void Mono_Put_Char(long, long);
  336. ;*
  337. ;* FUNCTION
  338. ;*
  339. ;* INPUTS
  340. ;* Character - ASCII character to output.
  341. ;* Attributes - Display attributes
  342. ;*
  343. ;* RESULT
  344. ;* NONE
  345. ;*
  346. ;****************************************************************************
  347. GLOBAL C Mono_Put_Char:NEAR
  348. PROC Mono_Put_Char C NEAR USES es eax edi
  349. ARG character:DWORD
  350. ARG attrib:DWORD
  351. ; Exit if mono disabled
  352. cmp [MonoEnabled],0
  353. je short ??fini
  354. ; Output character to the mono screen
  355. cld
  356. IF PHARLAP_TNT
  357. mov ax,034h
  358. mov es,ax ;Set ES selector to first MB
  359. ENDIF
  360. mov edi,0B0000h ;EDI = mono screen
  361. add edi,[MonoOff] ;Add cursor offset
  362. mov eax,[character]
  363. mov ah,[BYTE PTR attrib]
  364. stosw
  365. ; Update cursor position.
  366. inc [MonoX] ; X position moves.
  367. call Mono_Set_Cursor C,[MonoX],[MonoY]
  368. ??fini:
  369. ret
  370. ENDP Mono_Put_Char
  371. ;****************************************************************************
  372. ;*
  373. ;* NAME
  374. ;* Mono_Draw_Rect - Draw a box on the mono screen.
  375. ;*
  376. ;* SYNOPSIS
  377. ;* Mono_Draw_Rect(X, Y, Width, Height, Attributes, Thickness)
  378. ;*
  379. ;* void Mono_Draw_Rect();
  380. ;*
  381. ;* FUNCTION
  382. ;* Draw a rectangle text box on the mono screen.
  383. ;*
  384. ;* INPUTS
  385. ;* X - X coordinate position of upperleft corner.
  386. ;* Y - Y coordinate position of upperleft corner.
  387. ;* Width - Desired width.
  388. ;* Height - Desired height.
  389. ;* Attributes - Display attributes.
  390. ;* Thickness - Line thickness.
  391. ;*
  392. ;* RESULT
  393. ;* NONE
  394. ;*
  395. ;****************************************************************************
  396. GLOBAL C Mono_Draw_Rect:NEAR
  397. PROC Mono_Draw_Rect C NEAR
  398. ARG xpos:DWORD
  399. ARG ypos:DWORD
  400. ARG width:DWORD
  401. ARG height:DWORD
  402. ARG attrib:DWORD
  403. ARG thick:DWORD
  404. ; Exit if mono disabled
  405. pushad
  406. cmp [MonoEnabled],0
  407. je ??fini
  408. ; Select the character table for the desired line thickness
  409. mov edi,OFFSET CharData
  410. mov cl,3
  411. mov eax,[thick]
  412. and eax,011b
  413. shl eax,cl
  414. add edi,eax
  415. ; Prep width and height.
  416. cmp [width],2
  417. jb ??fini
  418. cmp [height],2
  419. jb ??fini
  420. sub [width],2
  421. sub [height],2
  422. ; Set cursor position to upperleft corner of box
  423. push [MonoY]
  424. push [MonoX] ;Save current cursor position
  425. call Mono_Set_Cursor C,[xpos],[ypos]
  426. ; Draw the rectangle
  427. mov esi,OFFSET BoxData
  428. ; Determine the number of characters to output
  429. ??drawloop:
  430. mov ecx,[width]
  431. cmp [BYTE PTR esi+2],1
  432. je short ??gotlen
  433. mov ecx,[height]
  434. cmp [BYTE PTR esi+2],2
  435. je short ??gotlen
  436. mov ecx,1
  437. ??gotlen:
  438. jecxz ??donerun
  439. ??runloop:
  440. xor eax,eax
  441. mov al,[BYTE PTR edi]
  442. call Mono_Put_Char C,eax,[attrib] ;Output the character.
  443. mov al,[BYTE PTR esi+1]
  444. cbw
  445. cwde
  446. add eax,[MonoY]
  447. push eax
  448. mov al,[BYTE PTR esi]
  449. cbw
  450. cwde
  451. add eax,[MonoX]
  452. dec eax ; Undo cursor advance.
  453. push eax
  454. call Mono_Set_Cursor ; Properly advance cursor.
  455. add sp,8
  456. loop ??runloop
  457. ; Advance to next control entry.
  458. ??donerun:
  459. add esi,3
  460. inc edi
  461. cmp [BYTE PTR esi+2],-1
  462. jne ??drawloop
  463. ; Restore cursor to original position.
  464. call Mono_Set_Cursor
  465. add sp,8
  466. ??fini:
  467. popad
  468. ret
  469. ENDP Mono_Draw_Rect
  470. ;****************************************************************************
  471. ;*
  472. ;* NAME
  473. ;* Mono_Text_Print - Print a string to the mono screen at a specified
  474. ;* position.
  475. ;*
  476. ;* SYNOPSIS
  477. ;* Mono_Text_Print(String, X, Y, Attributes, Update)
  478. ;*
  479. ;* void Mono_Text_Print(char *, long, long, long, long);
  480. ;*
  481. ;* FUNCTION
  482. ;* Print a NULL terminated string to the mono screen at the specified
  483. ;* cooridinates and attributes.
  484. ;*
  485. ;* INPUTS
  486. ;* String - Pointer to NULL terminated string.
  487. ;* X - X coordinate position.
  488. ;* Y - Y coordinate position.
  489. ;* Attributes - Display attributes
  490. ;* Update - Update cursor position flag.
  491. ;*
  492. ;* RESULT
  493. ;* NONE
  494. ;*
  495. ;****************************************************************************
  496. GLOBAL C _Mono_Text_Print:NEAR
  497. PROC _Mono_Text_Print C NEAR USES eax esi
  498. ARG text:NEAR PTR
  499. ARG xpos:DWORD
  500. ARG ypos:DWORD
  501. ARG attrib:DWORD
  502. ARG update:DWORD
  503. ; Save the current cursor position.
  504. push [MonoY]
  505. push [MonoX]
  506. cmp [text],0 ;Exit if the string is NULL
  507. je short ??fini
  508. call Mono_Set_Cursor C,[xpos],[ypos]
  509. ; Print string to the mono screen
  510. mov esi,[text] ;Text pointer
  511. ??charloop:
  512. mov eax,[esi]
  513. inc esi
  514. or al,al ;Stop on a NULL
  515. je short ??fini
  516. cmp al,13 ;Special processing for '\r'
  517. je short ??cr
  518. ; Output character to mono screen
  519. ??normal:
  520. xor ah,ah
  521. call Mono_Put_Char C,eax,[attrib]
  522. ; Perform adjustments if wrapping past right margin.
  523. cmp [MonoX],80
  524. jb short ??nowrap
  525. inc [ypos]
  526. call Mono_Set_Cursor C,0,[ypos]
  527. jmp short ??nowrap
  528. ; Move to start of next line.
  529. ??cr:
  530. inc [ypos]
  531. call Mono_Set_Cursor C,[xpos],[ypos]
  532. ; Scroll the monochrome screen if necessary.
  533. ??nowrap:
  534. cmp [MonoY],25
  535. jb short ??noscroll
  536. call Mono_Scroll C,1
  537. dec [ypos]
  538. ??noscroll:
  539. jmp short ??charloop
  540. ??fini:
  541. cmp [update],0
  542. jne short ??noupdate
  543. call Mono_Set_Cursor
  544. ??noupdate:
  545. pop eax
  546. pop eax
  547. ret
  548. ENDP _Mono_Text_Print
  549. ;****************************************************************************
  550. ;*
  551. ;* NAME
  552. ;* Mono_Text_Print - Print a string to the mono screen. (ASM call)
  553. ;*
  554. ;* SYNOPSIS
  555. ;* Mono_Text_Print(String, X, Y, Attributes)
  556. ;*
  557. ;* void Mono_Text_Print(char *, long, long, long);
  558. ;*
  559. ;* FUNCTION
  560. ;* Print a NULL terminated string to the mono screen at the specified
  561. ;* cooridinates and attributes.
  562. ;*
  563. ;* INPUTS
  564. ;* String - Pointer to NULL terminated string.
  565. ;* X - X coordinate position.
  566. ;* Y - Y coordinate position.
  567. ;* Attributes - Display attributes
  568. ;*
  569. ;* RESULT
  570. ;* NONE
  571. ;*
  572. ;* SEE ALSO
  573. ;* _Mono_Text_Print
  574. ;*
  575. ;****************************************************************************
  576. GLOBAL C Mono_Text_Print:NEAR
  577. PROC Mono_Text_Print C NEAR USES
  578. ARG text:NEAR PTR
  579. ARG xpos:DWORD
  580. ARG ypos:DWORD
  581. ARG attrib:DWORD
  582. ; Exit if mono disabled
  583. cmp [MonoEnabled],0
  584. je short ??fini
  585. call _Mono_Text_Print C,[text],[xpos],[ypos],[attrib],0
  586. ??fini:
  587. ret
  588. ENDP Mono_Text_Print
  589. ;****************************************************************************
  590. ;*
  591. ;* NAME
  592. ;* Mono_Print - Print a string to the mono screen.
  593. ;*
  594. ;* SYNOPSIS
  595. ;* Mono_Print(String)
  596. ;*
  597. ;* void Mono_Print(char *);
  598. ;*
  599. ;* FUNCTION
  600. ;* Print a string to the mono screen at the current cursor position and
  601. ;* update the cursor position.
  602. ;*
  603. ;* INPUTS
  604. ;* String - Pointer to NULL terminated string.
  605. ;*
  606. ;* RESULT
  607. ;* NONE
  608. ;*
  609. ;****************************************************************************
  610. GLOBAL C Mono_Print:NEAR
  611. PROC Mono_Print C NEAR
  612. ARG text:NEAR PTR
  613. ; Exit if mono disabled
  614. cmp [MonoEnabled],0
  615. je short ??fini
  616. call _Mono_Text_Print C,[text],[MonoX],[MonoY],2,1
  617. ??fini:
  618. ret
  619. ENDP Mono_Print
  620. ;****************************************************************************
  621. ;*
  622. ;* NAME
  623. ;* Mono_View_Page - View a mono page.
  624. ;*
  625. ;* SYNOPSIS
  626. ;* Oldpage = Mono_View_Page(Page)
  627. ;*
  628. ;* long Mono_View_Page(long);
  629. ;*
  630. ;* FUNCTION
  631. ;* Displays the specified page in displayable mono memory.
  632. ;*
  633. ;* INPUTS
  634. ;* Page - Page to view.
  635. ;*
  636. ;* RESULT
  637. ;* Oldpage - Previous page.
  638. ;*
  639. ;****************************************************************************
  640. GLOBAL C Mono_View_Page:NEAR
  641. PROC Mono_View_Page C NEAR USES ds es eax ebx ecx edi esi
  642. ARG page:DWORD
  643. LOCAL oldpage:DWORD
  644. ; Prepare the original page number for return to caller.
  645. cld
  646. mov ebx,[PageMap]
  647. mov [oldpage],ebx
  648. ; Exit of mono disabled
  649. cmp [MonoEnabled],0
  650. je short ??fini
  651. ; If the desired page is already displayed, then don't do anything.
  652. mov eax,[page]
  653. cmp eax,ebx
  654. je short ??fini
  655. ; Verify that page specified is legal.
  656. cmp eax,7
  657. ja short ??fini
  658. ; Find where the logical page to display is actually located.
  659. mov ecx,8
  660. push ds
  661. pop es
  662. lea edi,[PageMap]
  663. repne scasw
  664. neg ecx
  665. add ecx,7 ; CX = where desired page is located.
  666. ; Swap the page ID bytes in the PageMap array.
  667. sub edi,4
  668. mov ebx,[PageMap]
  669. mov eax,[edi]
  670. mov [edi],ebx
  671. mov [PageMap],eax
  672. shl ecx,8
  673. add ecx,eax
  674. mov esi,ecx
  675. IF PHARLAP_TNT
  676. mov ax,034h
  677. mov ds,ax
  678. ENDIF
  679. mov edi,0B0000h
  680. ; Exchange the two pages.
  681. mov ecx,1000H/4
  682. ??looper:
  683. mov edx,[edi]
  684. mov ebx,[esi]
  685. mov [edi],ebx
  686. mov [esi],edx
  687. add esi,4
  688. add edi,4
  689. loop ??looper
  690. ; Return with the original page number.
  691. ??fini:
  692. mov eax,[oldpage]
  693. ret
  694. ENDP Mono_View_Page
  695. END