Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

716 lines
19 KiB

  1. page ,132
  2. ;-----------------------------Module-Header-----------------------------;
  3. ; Module Name: MVGAXX.ASM
  4. ;
  5. ; This module contains functions for dealing with the following VGA
  6. ; 256 color (modex) modes.
  7. ;
  8. ; 320x200x8
  9. ; 320x400x8
  10. ; 320x240x8
  11. ;
  12. ; Created: 03-20-90
  13. ; Author: Todd Laney [ToddLa]
  14. ;
  15. ; 15-Dec-96 jeffno Made ScreenOffset and ScreenDisplay public so modex.c's
  16. ; new mode-set code can get at them. Also added cdwScreenWidthInDWORDS
  17. ; to enable PixBlt to operate correctly with 360x modes.
  18. ;
  19. ; Copyright (c) 1984-1995 Microsoft Corporation
  20. ;
  21. ;-----------------------------------------------------------------------;
  22. ?PLM = 1
  23. ?WIN = 0
  24. .386
  25. .xlist
  26. include cmacros.inc
  27. include mvgaxx.inc
  28. .list
  29. externA __A000h
  30. ; size for one 320x240x8 page (in mode X)
  31. ;-------------
  32. ; This is no longer accurate for x350 etc modex...
  33. ; turn it into a WORD and make it public so modex.c can
  34. ; set it properly.
  35. ;ScreenPageSize equ ((80 * 240 + 255) and (not 255))
  36. sBegin Data
  37. ScreenSel dw __A000h
  38. ;-------------------------------- Public Data ----------------------------------------
  39. ;
  40. ; The following three WORDS (ScreenOffset, ScreenDisplay and cdwScreenWidthInDWORDS
  41. ; and ScreenPageSize) MUST remain in sync with the extern declarations in modex.c
  42. ;
  43. _ScreenOffset label word
  44. ScreenOffset dw 0
  45. _ScreenDisplay label word
  46. ScreenDisplay dw 0
  47. _cdwScreenWidthInDWORDS label word
  48. cdwScreenWidthInDWORDS dw 0
  49. _cbScreenPageSize label word
  50. cbScreenPageSize dw ((80 * 240 + 255) and (not 255))
  51. ;expose these so modex.c can set 'em
  52. public _ScreenOffset
  53. public _ScreenDisplay
  54. public _cdwScreenWidthInDWORDS
  55. public _cbScreenPageSize
  56. ;
  57. ;
  58. ;-------------------------------------------------------------------------------------
  59. sEnd Data
  60. ifndef SEGNAME
  61. SEGNAME equ <MODEX_TEXT>
  62. endif
  63. createSeg %SEGNAME, CodeSeg, word, public, CODE
  64. sBegin CodeSeg
  65. assumes cs,CodeSeg
  66. assumes ds,Data
  67. assumes es,nothing
  68. ; Manually perform "push" dword register instruction to remove warning
  69. PUSHD macro reg
  70. db 66h
  71. push reg
  72. endm
  73. ; Manually perform "pop" dword register instruction to remove warning
  74. POPD macro reg
  75. db 66h
  76. pop reg
  77. endm
  78. ;---------------------------Public-Routine------------------------------;
  79. ; FlipPage
  80. ;
  81. ; display the current draw page and select another draw page
  82. ;
  83. ; Entry:
  84. ;
  85. ; Returns:
  86. ; none
  87. ; Error Returns:
  88. ; None
  89. ; Registers Preserved:
  90. ; BP,DS,SI,DI
  91. ; Registers Destroyed:
  92. ; AX,BX,CX,DX,FLAGS
  93. ; Calls:
  94. ; none
  95. ; History:
  96. ; Wed 04-Jan-1990 13:45:58 -by- Todd Laney [ToddLa]
  97. ; Created.
  98. ;-----------------------------------------------------------------------;
  99. assumes ds,Data
  100. assumes es,nothing
  101. cProc FlipPage, <NEAR, PUBLIC>, <>
  102. cBegin
  103. ; we only program the high byte of the offset.
  104. ; so the page size must be a multiple of 256
  105. ; *** This compile-time assert can't be used anymore since cbScreenPageSize
  106. ; *** is now a static word. There are corresponding asserts in modex.c
  107. ; *** at the top of SetVGAForModeX().
  108. ;errnz <cbScreenPageSize and 255>
  109. mov ax,ScreenOffset
  110. mov ScreenDisplay,ax
  111. mov al,0Ch
  112. mov dx,CRT_INDEX
  113. out dx,ax
  114. ; NOTE. This routine will actually do triple buffering if a page is less
  115. ; than 64k/3. We might want to revisit this if we allow apps to specify a
  116. ; dirty subrect to be copied on a flip: if they don't know the difference
  117. ; double and triple-buffered they'll get all out of sync.
  118. mov ax,cbScreenPageSize
  119. add ScreenOffset,ax
  120. neg ax
  121. cmp ScreenOffset,ax
  122. jbe FlipPage13XExit
  123. mov ScreenOffset,0
  124. FlipPage13XExit:
  125. cEnd
  126. ;---------------------------Public-Routine------------------------------;
  127. ; SetPalette
  128. ;
  129. ; setup the palette
  130. ;
  131. ; Entry:
  132. ; start - first palette index to set
  133. ; count - count of palette index's
  134. ; pPal - points to array of RGBQUADs containg colors
  135. ;
  136. ; Returns:
  137. ; None
  138. ; Error Returns:
  139. ; None
  140. ; Registers Preserved:
  141. ; BP,DS,SI,DI
  142. ; Registers Destroyed:
  143. ; AX,BX,CX,DX,FLAGS
  144. ; Calls:
  145. ; setramdac
  146. ; History:
  147. ;
  148. ; Wed 04-Jan-1990 13:45:58 -by- Todd Laney [ToddLa]
  149. ; Created.
  150. ;-----------------------------------------------------------------------;
  151. assumes ds,nothing
  152. assumes es,nothing
  153. cProc SetPalette, <NEAR, PUBLIC>, <ds,si,di>
  154. parmW start
  155. parmW count
  156. parmD pPal
  157. localV pal, %(3 * 256)
  158. cBegin
  159. lds si,pPal
  160. mov bx,start ; get start pal index
  161. mov cx,count ; get count
  162. mov ax,bx
  163. add ax,cx
  164. sub ax,256 ; see if the count goes beyond the end
  165. jle @f ; No, valid range
  166. sub cx,ax ; Yes, clip it
  167. mov count,cx
  168. @@:
  169. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -;
  170. ; convert the palette from a array of RGBQUADs (B,G,R,X) to a array of
  171. ; VGA RGBs (R>>2,G>>2,B>>2)
  172. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -;
  173. lea di,pal ; ES:DI --> pal array on stack
  174. mov ax,ss
  175. mov es,ax
  176. convert_pal_loop:
  177. lodsw ; al=blue, ah=green
  178. mov dx,ax ; dl=blue, dh=green
  179. lodsw ; al=red
  180. shr al,2 ; map from 0-255 into 0-63
  181. shr dl,2
  182. shr dh,2
  183. xchg al,dl
  184. stosb ; write red
  185. xchg dl,dh ; switch blue,green
  186. mov ax,dx
  187. stosw ; write green,blue
  188. loop convert_pal_loop
  189. lea si,pal ; DS:SI --> converted RGBs
  190. mov ax,ss
  191. mov ds,ax
  192. mov cx,count ; re-load count
  193. call setramdac ; set the physical palette
  194. cEnd
  195. ;---------------------------------------------------------------------------
  196. ; setramdac - initialize the ramdac to the values stored in
  197. ; a color table composed of double words
  198. ;
  199. ; entry:
  200. ; bx - index to 1st palette entry
  201. ; cx - count of indices to program
  202. ; ds:si -> array of RGBs
  203. ;
  204. ; exit:
  205. ; palette has been loaded
  206. ;
  207. ; Registers destroyed:
  208. ; al,cx,dx,si
  209. ;
  210. ;---------------------------------------------------------------------------
  211. assumes ds,nothing
  212. assumes es,nothing
  213. public setramdac
  214. setramdac proc near
  215. mov ax,bx
  216. mov dx,3c8h ;Color palette write mode index reg.
  217. out dx,al
  218. mov dx,3c9h ;Color palette data reg.
  219. mov bx,cx ;CX *= 3
  220. add cx,cx ;
  221. add cx,bx ;
  222. if 0
  223. rep outsb ;Set the palette all at once!
  224. else
  225. @@: lodsb
  226. out dx,al
  227. pause
  228. loop @b
  229. endif
  230. ret
  231. setramdac endp
  232. ;---------------------------Public-Routine------------------------------;
  233. ; PixBlt
  234. ;
  235. ; copy a bitmap to the screen
  236. ;
  237. ; Entry:
  238. ; x - (x,y) pos of lower left of rect
  239. ; y
  240. ; xExt - width and height of rect
  241. ; yExt
  242. ; pBits - pointer to bits
  243. ; BitsOffset - pointer offset to start at.
  244. ; WidthBytes - width of a bitmap scan
  245. ;
  246. ; IMPORTANT: SEE WIDTH RESTRICTIONS AS DOCUMENTED WITHIN ROUTINE
  247. ; Note reference to cdwScreenWidthInDWORDS.
  248. ;
  249. ; Returns:
  250. ; none
  251. ; Error Returns:
  252. ; None
  253. ; Registers Preserved:
  254. ; BP,DS,SI,DI
  255. ; Registers Destroyed:
  256. ; AX,BX,CX,DX,FLAGS
  257. ; History:
  258. ;
  259. ; Wed 04-Jan-1990 13:45:58 -by- Todd Laney [ToddLa]
  260. ; Created.
  261. ; 15-Dec-96 jeffno Allowed pitch other than 320, extended inner loop
  262. ; to handle multiples of 320 with remainder 8 pixels
  263. ; (for 360x modes)
  264. ;-----------------------------------------------------------------------;
  265. assumes ds,Data
  266. assumes es,nothing
  267. cProc PixBlt, <NEAR, PUBLIC>, <ds>
  268. ParmW xExt ;14
  269. ParmW yExt ;12
  270. ParmD pBits ;8 10
  271. ParmD BitsOffset ;4 6
  272. ParmW WidthBytes ;2
  273. ;0
  274. localW next_dst_scan
  275. localD next_src_scan
  276. cBegin
  277. .386
  278. PUSHD si ; push esi
  279. PUSHD di ; push edi
  280. xor esi,esi
  281. xor edi,edi
  282. xor ebx,ebx
  283. ; this routine only handles images in multiles of 32 pixels
  284. ; and they must start 4 pixel aligned
  285. ; But JeffNo added an extra loop to extend to either a multiple
  286. ; of 32 (320x) or a multiple of 32 plus 8 extra pixels (360x).
  287. ; An assert has been added in modex.c to ensure one of these cases.
  288. ; and xExt,not 31
  289. ;; and x,not 3
  290. mov es,ScreenSel
  291. mov ax,cdwScreenWidthInDWORDS
  292. mov next_dst_scan,ax
  293. mov ax,WidthBytes
  294. sub ax,4
  295. movsx eax,ax
  296. mov next_src_scan,eax
  297. mov di,ScreenOffset ; es:di -> top-left screen
  298. lds si,pBits
  299. add esi,BitsOffset
  300. assumes ds,nothing
  301. mov al,SC_MAP_MASK
  302. mov dx,SC_INDEX
  303. out dx,al
  304. align 4
  305. PixBltXLoop:
  306. ;-----------------------------------------------------------------;
  307. ; ax - free
  308. ; bx - index into dest es:[edi+ebx] index into source [esi+ebx*4]
  309. ; cx - loop count
  310. ; dl - mask
  311. ; dh - free
  312. ; si - source pointer (does not change)
  313. ; di - dest pointer (does not change)
  314. mov cx,xExt
  315. shr cx,2
  316. and cx,0fff8h ; a left over would give an extra loop at 360x
  317. mov dl,11h ; dh = mask
  318. align 4
  319. PixBltXPhaseLoop:
  320. mov bx,dx ; set the mask
  321. mov al,dl
  322. mov dx,SC_INDEX+1
  323. out dx,al
  324. mov dx,bx
  325. xor bx,bx ; start at zero
  326. align 4
  327. PixBltXPixelLoop:
  328. mov al,[esi+ebx*4]
  329. mov ah,[esi+ebx*4+4]
  330. mov es:[di+bx],ax
  331. mov al,[esi+ebx*4+8]
  332. mov ah,[esi+ebx*4+12]
  333. mov es:[di+bx+2],ax
  334. mov al,[esi+ebx*4+16]
  335. mov ah,[esi+ebx*4+20]
  336. mov es:[di+bx+4],ax
  337. mov al,[esi+ebx*4+24]
  338. mov ah,[esi+ebx*4+28]
  339. mov es:[di+bx+6],ax
  340. add bx,8
  341. cmp bx,cx
  342. jl short PixBltXPixelLoop
  343. PixBltXNext:
  344. inc esi
  345. shl dl,1
  346. jnc short PixBltXPhaseLoop
  347. ;-----------------------------------------------------------------;
  348. ; extra stuff to tack on the extra 2 chains to go from 352 to 360
  349. ; Note this little chunk relies on the xExt being a multiple of
  350. ; 8 pixels. If xExt is 320, we'll skip this part, and if it's
  351. ; 360, we'll do it
  352. ;
  353. test xExt,08h
  354. je short NoExtras ;branch taken implies width is 320, else 360
  355. mov dx,SC_INDEX+1
  356. mov al,011h ;the plane bits
  357. out dx,al ;select plane.
  358. mov bx,xExt ; point to the last 8 columns
  359. sub bx,8
  360. shr bx,2
  361. mov cl,[esi+ebx*4-4] ; -4 because esi is 4 greater than start of row
  362. mov ch,[esi+ebx*4]
  363. mov es:[di+bx],cx
  364. shl al,1
  365. out dx,al ;select plane.
  366. mov cl,[esi+ebx*4-3]
  367. mov ch,[esi+ebx*4+1]
  368. mov es:[di+bx],cx
  369. shl al,1
  370. out dx,al ;select plane.
  371. mov cl,[esi+ebx*4-2]
  372. mov ch,[esi+ebx*4+2]
  373. mov es:[di+bx],cx
  374. shl al,1
  375. out dx,al ;select plane.
  376. mov cl,[esi+ebx*4-1]
  377. mov ch,[esi+ebx*4+3]
  378. mov es:[di+bx],cx
  379. NoExtras:
  380. ;-----------------------------------------------------------------;
  381. add di,next_dst_scan ;no changes to these to support 360x, since this
  382. add esi,next_src_scan ;assume looped over multiple of 320, and the extra
  383. ;loop didn't change di and esi.
  384. dec yExt
  385. jnz PixBltXLoop ;not a short by just 3 bytes!
  386. PixBltXExit:
  387. POPD di ; pop edi
  388. POPD si ; pop esi
  389. cEnd
  390. ;---------------------------Private-Routine------------------------------;
  391. ; SetMode320x200x8
  392. ;
  393. ; VGA 320x200x8 graphics mode is entered (plain ol' MODE 13h)
  394. ;
  395. ; Entry:
  396. ;
  397. ; Returns:
  398. ; 360x200x8 graphics mode is entered
  399. ; Error Returns:
  400. ; None
  401. ; Registers Preserved:
  402. ; BP,DS,SI,DI
  403. ; Registers Destroyed:
  404. ; AX,BX,CX,DX,FLAGS
  405. ; Calls:
  406. ; INT 10h
  407. ; History:
  408. ;
  409. ; Wed 04-Jan-1990 13:45:58 -by- Todd Laney [ToddLa]
  410. ; Created.
  411. ;-----------------------------------------------------------------------;
  412. assumes ds,Data
  413. assumes es,nothing
  414. cProc SetMode320x200x8, <NEAR, PUBLIC>, <ds,si,di>
  415. cBegin
  416. mov ScreenOffset,0 ; make sure this is zero
  417. mov ScreenDisplay,0 ; make sure this is zero too.
  418. mov ax,13h ; set display mode 320x200x8
  419. int 10h
  420. mov dx,SC_INDEX ; alter sequencer registers
  421. mov ax,0604h
  422. out dx,ax ;disable chain4 mode
  423. mov dx,CRT_INDEX
  424. mov ax,0E317h
  425. out dx, ax
  426. mov ax, 014h
  427. out dx, ax
  428. cEnd
  429. ;---------------------------Private-Macro--------------------------------;
  430. ; SLAM port, regs
  431. ;
  432. ; Sets a range of VGA registers
  433. ;
  434. ; Entry:
  435. ; port port index register
  436. ; regs table of register values
  437. ;
  438. ; History:
  439. ; Wed 04-Jan-1990 13:45:58 -by- Todd Laney [ToddLa]
  440. ; Created.
  441. ;-----------------------------------------------------------------------;
  442. SLAM macro port, regs
  443. local slam_loop
  444. local slam_exit
  445. mov cx,(&regs&_end - regs) / 2
  446. mov dx,port
  447. mov si,offset regs
  448. jcxz slam_exit
  449. slam_loop:
  450. lodsw
  451. out dx,ax
  452. pause
  453. loop slam_loop
  454. slam_exit:
  455. endm
  456. ;---------------------------Private-Routine------------------------------;
  457. ; SetMode320x400x8
  458. ;
  459. ; VGA 320x400x8 graphics mode is entered
  460. ;
  461. ; Entry:
  462. ;
  463. ; Returns:
  464. ; 320x400x8 graphics mode is entered
  465. ; Error Returns:
  466. ; None
  467. ; Registers Preserved:
  468. ; BP,DS,SI,DI
  469. ; Registers Destroyed:
  470. ; AX,BX,CX,DX,FLAGS
  471. ; Calls:
  472. ; INT 10h
  473. ; History:
  474. ;
  475. ; Wed 04-Jan-1990 13:45:58 -by- Todd Laney [ToddLa]
  476. ; Created.
  477. ;-----------------------------------------------------------------------;
  478. assumes ds,Data
  479. assumes es,nothing
  480. seq_320x400:
  481. ;dw 00801h ; Dot Clock * 2
  482. dw 00604h ; Disable chain 4
  483. seq_320x400_end:
  484. crt_320x400:
  485. dw 04009h ; cell height
  486. dw 00014h ; turn off dword mode
  487. dw 0e317h ; turn on byte mode
  488. crt_320x400_end:
  489. assumes ds,Data
  490. assumes es,nothing
  491. cProc SetMode320x400x8, <NEAR, PUBLIC>, <ds,si,di>
  492. cBegin
  493. mov ScreenOffset,0 ; make sure this is zero
  494. mov ScreenDisplay,0 ; make sure this is zero too.
  495. mov ax,12h
  496. int 10h ; have BIOS clear memory
  497. mov ax,13h ; set display mode 320x200x8
  498. int 10h
  499. mov ax,cs ; get segment for data
  500. mov ds,ax
  501. ;
  502. ; Set the CRT regs
  503. ;
  504. SLAM CRT_INDEX, crt_320x400
  505. ;
  506. ; Set the SEQ regs
  507. ;
  508. SLAM SC_INDEX, seq_320x400
  509. cEnd
  510. ;---------------------------Private-Routine------------------------------;
  511. ; SetMode320x240x8
  512. ;
  513. ; VGA 320x240x8 graphics mode is entered
  514. ;
  515. ; Entry:
  516. ;
  517. ; Returns:
  518. ; 320x240x8 graphics mode is entered
  519. ; Error Returns:
  520. ; None
  521. ; Registers Preserved:
  522. ; BP,DS,SI,DI
  523. ; Registers Destroyed:
  524. ; AX,BX,CX,DX,FLAGS
  525. ; Calls:
  526. ; INT 10h
  527. ; History:
  528. ;
  529. ; Wed 04-Jan-1990 13:45:58 -by- Todd Laney [ToddLa]
  530. ; Created.
  531. ;-----------------------------------------------------------------------;
  532. assumes ds,Data
  533. assumes es,nothing
  534. seq_320x240:
  535. dw 00604h ; Disable chain 4
  536. seq_320x240_end:
  537. crt_320x240:
  538. ; dw 00611h ; un-protect cr0-cr7
  539. dw 00d06h ;vertical total
  540. dw 03e07h ;overflow (bit 8 of vertical counts)
  541. dw 04109h ;cell height (2 to double-scan)
  542. dw 0ea10h ;v sync start
  543. dw 0ac11h ;v sync end and protect cr0-cr7
  544. dw 0df12h ;vertical displayed
  545. dw 00014h ;turn off dword mode
  546. dw 0e715h ;v blank start
  547. dw 00616h ;v blank end
  548. dw 0e317h ;turn on byte mode
  549. crt_320x240_end:
  550. cProc SetMode320x240x8, <NEAR, PUBLIC>, <ds,si,di>
  551. cBegin
  552. mov ScreenOffset,0 ; make sure this is zero
  553. mov ScreenDisplay,0 ; make sure this is zero too.
  554. mov ax,13h ; set display mode 320x200x8
  555. int 10h
  556. mov ax,cs ; get segment for data
  557. mov ds,ax
  558. assumes ds,Code
  559. mov dx,CRT_INDEX ;reprogram the CRT Controller
  560. mov al,11h ;VSync End reg contains register write
  561. out dx,al ; protect bit
  562. inc dx ;CRT Controller Data register
  563. in al,dx ;get current VSync End register setting
  564. and al,7fh ;remove write protect on various
  565. out dx,al ; CRTC registers
  566. dec dx ;CRT Controller Index
  567. ;
  568. ; Set the CRT regs
  569. ;
  570. SLAM CRT_INDEX, crt_320x240
  571. mov dx,SC_INDEX ; alter sequencer registers
  572. mov ax,0604h
  573. out dx,ax ;disable chain4 mode
  574. ;
  575. ; Select a 25 mHz crystal
  576. ;
  577. cli
  578. ; mov dx,SC_INDEX ; alter sequencer registers
  579. mov ax,0100h ; synchronous reset
  580. out dx,ax ; asserted
  581. pause
  582. mov dx,MISC_OUTPUT ; misc output
  583. mov al,0e3h ; use 25 mHz dot clock
  584. out dx,al ; select it
  585. pause
  586. mov dx,SC_INDEX ; sequencer again
  587. mov ax,0300h ; restart sequencer
  588. out dx,ax ; running again
  589. pause
  590. sti
  591. ;
  592. ; now clear the memory.
  593. ;
  594. mov ax,DataBASE
  595. mov ds,ax
  596. assumes ds,Data
  597. mov ax,ScreenSel
  598. mov es,ax
  599. xor di,di
  600. mov ax,SC_MAP_MASK + 0F00h
  601. mov dx,SC_INDEX
  602. out dx,ax
  603. xor ax,ax
  604. mov cx,8000h
  605. rep stosw
  606. cEnd
  607. sEnd CodeSeg
  608. end