XMODE.ASM 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748
  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. ;* xmode.asm
  26. ;*
  27. ;* DESCRIPTION
  28. ;* Xmode graphics display routines. (32-Bit protected mode)
  29. ;*
  30. ;* PROGRAMMER
  31. ;* Bill Randolph
  32. ;* Denzil E. Long, Jr.
  33. ;*
  34. ;* DATE
  35. ;* Febuary 3, 1995
  36. ;*
  37. ;*---------------------------------------------------------------------------
  38. ;*
  39. ;* PUBLIC
  40. ;* SetXMode - Set the specified Xmode video mode.
  41. ;* ClearXMode - Clear the XMode VRAM.
  42. ;* ShowXPage - Set a specific page for XMode display.
  43. ;* Xmode_BufferCopy_320x200 - Copy 320x200 buffer to Xmode VRAM.
  44. ;* Xmode_Blit - Bit blit a block to the XMode display.
  45. ;*
  46. ;****************************************************************************
  47. IDEAL
  48. P386
  49. MODEL USE32 FLAT
  50. LOCALS ??
  51. INCLUDE "vga.i"
  52. INCLUDE "video.i"
  53. CODESEG
  54. ;****************************************************************************
  55. ;*
  56. ;* NAME
  57. ;* SetXMode - Set the specified Xmode video mode.
  58. ;*
  59. ;* SYNOPSIS
  60. ;* Error = SetXMode(Mode)
  61. ;*
  62. ;* long SetXMode(long);
  63. ;*
  64. ;* FUNCTION
  65. ;* This routines set the current display adapter to the specified Xmode.
  66. ;* Portions of this routine were take from Dr. Dobb's, written in C, and
  67. ;* portions were taken from Dominic's 320x200 code.
  68. ;*
  69. ;* INPUTS
  70. ;* Mode - Xmode mode to set display to.
  71. ;*
  72. ;* RESULT
  73. ;* Error - 0 if successful, or -1 if error.
  74. ;*
  75. ;****************************************************************************
  76. GLOBAL C SetXMode:NEAR
  77. PROC SetXMode C NEAR USES edx
  78. ARG mode:DWORD
  79. ??Set320x200:
  80. cmp [mode],XMODE_320X200 ;320x200?
  81. jne ??Set320x240
  82. IF 0
  83. mov eax,MCGA
  84. int 10h
  85. ; Memory Mode:
  86. ; bit3 (chain) = 0 (planes are accessed via Map Mask)
  87. ; bit2 (odd/even) = 1 (use sequential addressing mode)
  88. INPORT R_SEQUENCER,SEQ_MEMORY_MODE
  89. and al,not 08h ;Turn off chain 4
  90. or al,04h ;Turn off odd/even
  91. out dx,al
  92. INPORT R_GRAPHICS_CONTROLLER,GC_MODE
  93. and al,not 10h ;Turn off odd/even
  94. out dx,al
  95. INPORT R_GRAPHICS_CONTROLLER,GC_MISC
  96. and al,not 02h ;Turn off chain
  97. out dx,al
  98. OUTPORT R_SEQUENCER,SEQ_MAP_MASK,0Fh
  99. INPORT R_CRT_CONTROLLER, CRT_MAX_SCANLINE
  100. and al,not 1fh ;Clear low 5 bits
  101. or al,1 ;Mode = 0 => 400 lines
  102. out dx,al ;Mode =1 => 200
  103. INPORT R_CRT_CONTROLLER,CRT_UNDERLINE
  104. and al,not 40h ;Turn off doubleword
  105. out dx,al
  106. INPORT R_CRT_CONTROLLER,CRT_MODE_CONTROL
  107. or al,40h ;Turn on byte mode bit,
  108. out dx,al ; so mem scanned linearly
  109. ENDIF
  110. ; The following section of code is from Roger Stevens' XMode
  111. ; example code; it's the same as 320x400, except the value sent
  112. ; to CRT_MAX_SCANLINE is 41, not 40.
  113. mov eax,MCGA
  114. int 10h
  115. OUTPORT R_SEQUENCER,SEQ_MEMORY_MODE,06h
  116. INPORT R_CRT_CONTROLLER,CRT_VERTRET_END
  117. and al,07Fh
  118. out dx,al
  119. OUTPORT R_CRT_CONTROLLER,CRT_MAX_SCANLINE,41h
  120. OUTPORT R_CRT_CONTROLLER,CRT_UNDERLINE,00h
  121. OUTPORT R_CRT_CONTROLLER,CRT_MODE_CONTROL,0E3h
  122. mov eax,0
  123. jmp ??Done
  124. ??Set320x240:
  125. cmp [mode],XMODE_320X240 ;320x240?
  126. jne ??Set320x400
  127. ; Start by setting MCGA to let the BIOS program the registers;
  128. ; then, reprogram the registers that need it.
  129. mov eax,MCGA
  130. int 10h
  131. ; Memory Mode:
  132. ; bit3 (chain) = 0 (planes are accessed via Map Mask)
  133. ; bit2 (odd/even) = 1 (use sequential addressing mode)
  134. ; bit1 (extended mem) = 1 (>64K video RAM)
  135. ; bit0 (alpha/graph) = 0 (graphics mode)
  136. OUTPORT R_SEQUENCER,SEQ_MEMORY_MODE,06h
  137. ; Issue a Sequencer Reset
  138. OUTPORT R_SEQUENCER,SEQ_RESET,01h
  139. ; Misc Output: (set to 1100 0011)
  140. ; Bit 7: VSync polarity (1=negative)
  141. ; Bit 6: HSync polarity (1=negative)
  142. ; Bit 5: page bit for odd/even (0=low 64K)
  143. ; Bit 4: Video drivers (0=enable)
  144. ; Bit 3,2: clock select (0=25-MHz clock)
  145. ; Bit 1: VRAM access (1 = enable CPU to access)
  146. ; Bit 0: I/O Address (1=color emulation)
  147. mov edx,R_MISC_OUTPUT
  148. mov al,0C3h
  149. out dx,al
  150. ; Clear Sequencer Reset
  151. OUTPORT R_SEQUENCER,SEQ_RESET,03h
  152. ; Read Vertical Retrace End, and with 07f to clear high bit
  153. ; (clearing bit 7 enables writing to registers 0-7)
  154. INPORT R_CRT_CONTROLLER,CRT_VERTRET_END
  155. and al,07Fh
  156. out dx,al
  157. ; Program the CRT Controller to display 480 scanlines, but to
  158. ; double each scanline so only 240 are displayed:
  159. OUTPORT R_CRT_CONTROLLER,CRT_UNDERLINE,00h
  160. OUTPORT R_CRT_CONTROLLER,CRT_MODE_CONTROL,0E3h
  161. OUTPORT R_CRT_CONTROLLER,CRT_VERT_TOTAL,0Dh
  162. OUTPORT R_CRT_CONTROLLER,CRT_OVERFLOW,03Eh
  163. OUTPORT R_CRT_CONTROLLER,CRT_VERTRET_START,0EAh
  164. OUTPORT R_CRT_CONTROLLER,CRT_VERTRET_END,0ACh
  165. OUTPORT R_CRT_CONTROLLER,CRT_VERTDISP_END,0DFh
  166. OUTPORT R_CRT_CONTROLLER,CRT_START_VB,0E7h
  167. OUTPORT R_CRT_CONTROLLER,CRT_END_VB,06h
  168. OUTPORT R_CRT_CONTROLLER,CRT_MAX_SCANLINE,041h
  169. xor eax,eax
  170. jmp ??Done
  171. ??Set320x400:
  172. cmp [mode],XMODE_320X400 ;320x400
  173. jne ??Set320x480
  174. mov eax,MCGA
  175. int 10h
  176. OUTPORT R_SEQUENCER,04h,06h
  177. INPORT R_CRT_CONTROLLER,011h
  178. and al,07Fh
  179. out dx,al
  180. OUTPORT R_CRT_CONTROLLER,09h,40h
  181. OUTPORT R_CRT_CONTROLLER,014h,00h
  182. OUTPORT R_CRT_CONTROLLER,017h,0E3h
  183. xor eax,eax
  184. jmp ??Done
  185. ??Set320x480:
  186. cmp [mode],XMODE_320X480 ;320x480?
  187. jne ??Set360x400
  188. mov eax,MCGA
  189. int 10h
  190. mov edx,R_SEQUENCER
  191. mov eax,0604h
  192. out dx,ax
  193. mov eax,0100h
  194. out dx,ax
  195. mov edx,R_MISC_OUTPUT
  196. mov al,0C3h
  197. out dx,al
  198. mov edx,R_SEQUENCER
  199. mov eax,0300h
  200. out dx,ax
  201. mov edx,R_CRT_CONTROLLER
  202. mov al,011h
  203. out dx,al
  204. mov edx,03D5h
  205. in al,dx
  206. and al,07Fh
  207. out dx,al
  208. mov edx,R_CRT_CONTROLLER
  209. mov eax,04009h
  210. out dx,ax
  211. mov eax,00014h
  212. out dx,ax
  213. mov eax,0E317h
  214. out dx,ax
  215. mov eax,00D06h
  216. out dx,ax
  217. mov eax,03E07h
  218. out dx,ax
  219. mov eax,0EA10h
  220. out dx,ax
  221. mov eax,0AC11h
  222. out dx,ax
  223. mov eax,0DF12h
  224. out dx,ax
  225. mov eax,0E715h
  226. out dx,ax
  227. mov eax,00616h
  228. out dx,ax
  229. mov eax,04009h
  230. out dx,ax
  231. xor eax,eax
  232. jmp ??Done
  233. ??Set360x400:
  234. cmp [mode],XMODE_360X400 ;360x400
  235. jne ??Set360x480
  236. mov eax,MCGA
  237. int 10h
  238. mov edx,R_SEQUENCER
  239. mov eax,0604h
  240. out dx,ax
  241. mov eax,0100h
  242. out dx,ax
  243. mov edx,R_MISC_OUTPUT
  244. mov al,067h
  245. out dx,al
  246. mov edx,R_SEQUENCER
  247. mov eax,0300h
  248. out dx,ax
  249. mov edx,R_CRT_CONTROLLER
  250. mov al,011h
  251. out dx,al
  252. mov edx,03D5h
  253. in al,dx
  254. and al,07Fh
  255. out dx,al
  256. mov edx,R_CRT_CONTROLLER
  257. mov eax,06B00h
  258. out dx,ax
  259. mov eax,05901h
  260. out dx,ax
  261. mov eax,05A02h
  262. out dx,ax
  263. mov eax,08E03h
  264. out dx,ax
  265. mov eax,05E04h
  266. out dx,ax
  267. mov eax,08A05h
  268. out dx,ax
  269. mov eax,04009
  270. out dx,ax
  271. mov eax,00014h
  272. out dx,ax
  273. mov eax,0E317h
  274. out dx,ax
  275. mov eax,02D13h
  276. out dx,ax
  277. xor eax,eax
  278. jmp ??Done
  279. ??Set360x480:
  280. cmp [mode],XMODE_360X480 ;360x480?
  281. jne ??Unknown_mode
  282. mov eax,MCGA
  283. int 10h
  284. mov edx,R_SEQUENCER
  285. mov eax,0604h
  286. out dx,ax
  287. mov eax,0100h
  288. out dx,ax
  289. mov edx,R_MISC_OUTPUT
  290. mov al,0E7h
  291. out dx,al
  292. mov edx,R_SEQUENCER
  293. mov eax,0300h
  294. out dx,ax
  295. mov edx,R_CRT_CONTROLLER
  296. mov al,011h
  297. out dx,al
  298. mov edx,03D5h
  299. in al,dx
  300. and al,07Fh
  301. out dx,al
  302. mov edx,R_CRT_CONTROLLER
  303. mov eax,06B00h
  304. out dx,ax
  305. mov eax,05901h
  306. out dx,ax
  307. mov eax,05A02h
  308. out dx,ax
  309. mov eax,08E03h
  310. out dx,ax
  311. mov eax,05E04h
  312. out dx,ax
  313. mov eax,08A05h
  314. out dx,ax
  315. mov eax,04009h
  316. out dx,ax
  317. mov eax,00014h
  318. out dx,ax
  319. mov eax,0E317h
  320. out dx,ax
  321. mov eax,00D06h
  322. out dx,ax
  323. mov eax,03E07h
  324. out dx,ax
  325. mov eax,0EA10h
  326. out dx,ax
  327. mov eax,0AC11h
  328. out dx,ax
  329. mov eax,0DF12h
  330. out dx,ax
  331. mov eax,0E715h
  332. out dx,ax
  333. mov eax,00616h
  334. out dx,ax
  335. mov eax,02D13h
  336. out dx,ax
  337. xor eax,eax
  338. jmp ??Done
  339. ??Unknown_mode:
  340. mov eax,0FFFFFFFFh ;Unknown mode
  341. ??Done:
  342. ret
  343. ENDP SetXMode
  344. ;****************************************************************************
  345. ;*
  346. ;* NAME
  347. ;* ClearXMode - Clear the XMode VRAM.
  348. ;*
  349. ;* SYNOPSIS
  350. ;* ClearXMode()
  351. ;*
  352. ;* void ClearXMode(void);
  353. ;*
  354. ;* FUNCTION
  355. ;*
  356. ;* INPUTS
  357. ;* NONE
  358. ;*
  359. ;* RESULT
  360. ;* NONE
  361. ;*
  362. ;****************************************************************************
  363. GLOBAL C ClearXMode:NEAR
  364. PROC ClearXMode C NEAR USES eax ecx edi es
  365. IF PHARLAP_TNT
  366. mov eax,01Ch
  367. mov es,ax ;Set ES selector to VRAM
  368. mov edi,0
  369. ELSE
  370. mov edi,0A0000h
  371. ENDIF
  372. SET_PLANE 0Fh
  373. mov ecx,((320*240*2)/4/4)
  374. xor eax,eax
  375. rep stosd
  376. ret
  377. ENDP ClearXMode
  378. ;****************************************************************************
  379. ;*
  380. ;* NAME
  381. ;* ShowXPage - Set a specific page for XMode display.
  382. ;*
  383. ;* SYNOPSIS
  384. ;* ShowXPage(Offset)
  385. ;*
  386. ;* void ShowXPage();
  387. ;*
  388. ;* FUNCTION
  389. ;* Show the page at the specified offset in the bitmap. Page-flip takes
  390. ;* effect on the next active scan cycle.
  391. ;*
  392. ;* INPUTS
  393. ;* Offset - Offset to set page to.
  394. ;*
  395. ;* RESULT
  396. ;* NONE
  397. ;*
  398. ;****************************************************************************
  399. GLOBAL C ShowXPage:NEAR
  400. PROC ShowXPage C NEAR USES eax ebx ecx edx
  401. ARG StartOffset:DWORD
  402. mov edx,R_CRT_CONTROLLER
  403. mov bl,CRT_STARTADDR_LOW
  404. mov bh,[byte ptr StartOffset]
  405. mov cl,CRT_STARTADDR_HIGH
  406. mov ch,[byte ptr StartOffset+1]
  407. mov eax,ebx
  408. out dx,ax
  409. mov eax,ecx
  410. out dx,ax
  411. ret
  412. ENDP ShowXPage
  413. ;****************************************************************************
  414. ;*
  415. ;* NAME
  416. ;* Xmode_BufferCopy_320x200 - Copy 320x200 buffer to Xmode VRAM.
  417. ;*
  418. ;* SYNOPSIS
  419. ;* Xmode_BufferCopy_320x200(Buffer, Screen)
  420. ;*
  421. ;* void Xmode_BufferCopy_320x200(char *, char *);
  422. ;*
  423. ;* FUNCTION
  424. ;* BitBlt copy to VRAM.
  425. ;*
  426. ;* INPUTS
  427. ;* Buffer - Pointer to buffer to copy to XMode VRAM.
  428. ;* Screen - XMode VRAM screen address to copy buffer to.
  429. ;*
  430. ;* RESULT
  431. ;* NONE
  432. ;*
  433. ;****************************************************************************
  434. GLOBAL C Xmode_BufferCopy_320x200:NEAR
  435. PROC Xmode_BufferCopy_320x200 C NEAR USES eax ecx edx edi esi es
  436. ARG buffer:NEAR PTR
  437. ARG screen:NEAR PTR
  438. LOCAL save_esi:DWORD
  439. LOCAL save_edi:DWORD
  440. ;----------------------------------------------------------------------------
  441. ; Initialize
  442. ;----------------------------------------------------------------------------
  443. IF PHARLAP_TNT
  444. mov eax,01Ch ;Set ES selector to VRAM.
  445. mov es,ax
  446. ENDIF
  447. mov esi,[buffer] ;Set pointers
  448. mov edi,[screen]
  449. mov [save_esi],esi
  450. mov [save_edi],edi
  451. ;----------------------------------------------------------------------------
  452. ; Copy plane 1
  453. ;----------------------------------------------------------------------------
  454. SET_PLANE XPLANE_1
  455. mov ecx,4000
  456. x_loop_1:
  457. mov al,[esi + 8] ;Get pixel
  458. mov ah,[esi + 12] ;Get pixel
  459. ror eax,16
  460. mov al,[esi] ;Get pixel
  461. mov ah,[esi + 4] ;Get pixel
  462. mov [es:edi],eax ;Write plane 1 pixels to VRAM
  463. add esi,16 ;Next source pixel position
  464. add edi,4 ;Next VRAM position
  465. dec ecx
  466. jnz short x_loop_1
  467. ;----------------------------------------------------------------------------
  468. ; Copy plane 2
  469. ;----------------------------------------------------------------------------
  470. mov esi,[save_esi] ;Restore pointers
  471. mov edi,[save_edi]
  472. inc esi ;Adjust source pointer to plane 2
  473. SET_PLANE XPLANE_2
  474. mov ecx,4000
  475. x_loop_2:
  476. mov al,[esi + 8] ;Get pixel
  477. mov ah,[esi + 12] ;Get pixel
  478. ror eax,16
  479. mov al,[esi] ;Get pixel
  480. mov ah,[esi + 4] ;Get pixel
  481. mov [es:edi],eax ;Write plane 2 pixels to VRAM
  482. add esi,16 ;Next source pixel position
  483. add edi,4 ;Next VRAM position
  484. dec ecx
  485. jnz short x_loop_2
  486. ;----------------------------------------------------------------------------
  487. ; Copy plane 3
  488. ;----------------------------------------------------------------------------
  489. mov esi,[save_esi] ;Restore pointers
  490. mov edi,[save_edi]
  491. add esi,2 ;Adjust source pointer to plane 3
  492. SET_PLANE XPLANE_3
  493. mov ecx,4000
  494. x_loop_3:
  495. mov al,[esi + 8] ;Get pixel
  496. mov ah,[esi + 12] ;Get pixel
  497. ror eax,16
  498. mov al,[esi] ;Get pixel
  499. mov ah,[esi + 4] ;Get pixel
  500. mov [es:edi],eax ;Write plane 3 pixels to VRAM
  501. add esi,16 ;Next source pixel position
  502. add edi,4 ;Next VRAM position
  503. dec ecx
  504. jnz short x_loop_3
  505. ;----------------------------------------------------------------------------
  506. ; Copy plane 4
  507. ;----------------------------------------------------------------------------
  508. mov esi,[save_esi] ;Restore pointers
  509. mov edi,[save_edi]
  510. add esi,3 ;Adjust source pointer to plane 4
  511. SET_PLANE XPLANE_4
  512. mov ecx,4000
  513. x_loop_4:
  514. mov al,[esi + 8] ;Get pixel
  515. mov ah,[esi + 12] ;Get pixel
  516. ror eax,16
  517. mov al,[esi] ;Get pixel
  518. mov ah,[esi + 4] ;Get pixel
  519. mov [es:edi],eax ;Write plane 4 pixels to VRAM
  520. add esi,16 ;Next source pixel position
  521. add edi,4 ;Next screen position
  522. dec ecx
  523. jnz short x_loop_4
  524. ret
  525. ENDP Xmode_BufferCopy_320x200
  526. ;****************************************************************************
  527. ;*
  528. ;* NAME
  529. ;* Xmode_Blit - Bit blit a block to the XMode display.
  530. ;*
  531. ;* SYNOPSIS
  532. ;* XMode_Blit(Buffer, Screen, Width, Height)
  533. ;*
  534. ;* void XMode_Blit(char *, char *, long, long);
  535. ;*
  536. ;* FUNCTION
  537. ;*
  538. ;* INPUTS
  539. ;* Buffer - Pointer buffer to blit to screen.
  540. ;* Screen - Screen address to blit buffer to.
  541. ;* Width - Width of buffer.
  542. ;* Height - Height of buffer.
  543. ;*
  544. ;* RESULT
  545. ;* NONE
  546. ;*
  547. ;* WARNINGS
  548. ;* Assumes the screen to be 320 pixels wide and the source buffer width
  549. ;* to be divisible by 16.
  550. ;*
  551. ;****************************************************************************
  552. GLOBAL C Xmode_Blit:NEAR
  553. PROC Xmode_Blit C NEAR USES ecx edx esi edi es
  554. ARG buffer:NEAR PTR
  555. ARG screen:NEAR PTR
  556. ARG imgwidth:DWORD
  557. ARG imgheight:DWORD
  558. LOCAL rowcount:DWORD
  559. LOCAL xplane:DWORD
  560. LOCAL edi_startval:DWORD
  561. LOCAL esi_startval:DWORD
  562. LOCAL xadd:DWORD
  563. ;----------------------------------------------------------------------------
  564. ; Initialize
  565. ;----------------------------------------------------------------------------
  566. IF PHARLAP_TNT
  567. mov eax,01Ch ;Set ES selector to VRAM
  568. mov es,ax
  569. ENDIF
  570. mov esi,[buffer]
  571. mov edi,[screen]
  572. mov [esi_startval],esi
  573. mov [edi_startval],edi
  574. mov edx,320 ;Compute modulo
  575. sub edx,[imgwidth]
  576. shr edx,2
  577. mov [xadd],edx
  578. ;----------------------------------------------------------------------------
  579. ; Transfer the data on plane at a time.
  580. ;----------------------------------------------------------------------------
  581. mov [xplane],1
  582. ??Do_plane:
  583. SET_PLANE [xplane] ;Set plane to transfer to
  584. mov eax,[imgheight]
  585. mov [rowcount],eax
  586. mov edx,[xadd]
  587. ??Do_row:
  588. mov ecx,[imgwidth] ;Length of row to copy in DWORDS
  589. shr ecx,4
  590. ; Transfer a row of pixels
  591. ??Not_done:
  592. mov al,[esi + 8] ;Get pixel
  593. mov ah,[esi + 12] ;Get pixel
  594. ror eax,16
  595. mov al,[esi] ;Get pixel
  596. mov ah,[esi + 4] ;Get pixel
  597. mov [es:edi],eax ;Write pixels to VRAM plane
  598. add esi,16 ;Next source position
  599. add edi,4 ;Next VRAM position
  600. dec ecx
  601. jnz ??Not_done
  602. add edi,edx ;Next VRAM row
  603. dec [rowcount] ;Decrement the row count
  604. jnz ??Do_row
  605. ; Go to next X-Plane
  606. inc [esi_startval]
  607. mov eax,[esi_startval]
  608. mov esi,eax
  609. mov eax,[edi_startval]
  610. mov edi,eax
  611. shl [xplane],1
  612. cmp [xplane],16
  613. jnz ??Do_plane
  614. ret
  615. ENDP Xmode_Blit
  616. END