saveega.new
上传用户:xiaoan1112
上传日期:2013-04-11
资源大小:19621k
文件大小:28k
源码类别:

操作系统开发

开发平台:

Visual C++

  1. ;*
  2. ;* CW : Character Windows
  3. ;*
  4. ;* ega.asm : DOS3 TWIN compatible screen driver
  5. ;*
  6. ;*****************************************************************************
  7. ;* * Special screen save
  8. NonStandard CbSizeVidsCsd
  9. NonStandard FSaveVidsCsd
  10. NonStandard FRestoreVidsCsd
  11. NonStandard SetVideoMode
  12. NonStandard SaveVidDataCsd
  13. NonStandard RestoreVidDataCsd
  14. NonStandard EnableVidsMonitorCsd
  15. ;********** CbSizeVidsCsd **********
  16. ;* * CSD entry point (see documentation for interface)
  17. cProc CbSizeVidsCsd, <FAR, PUBLIC, ATOMIC>
  18. cBegin CbSizeVidsCsd
  19. mov ax,SIZE EGA_VIDS
  20. mov bx,OFF_lpwDataCsd ;* Data in data segment
  21. test [bx].fvmCurAdap, fvmEGA or fvmVGA or fvm64KEGA or fvmEGAM or fvmMCGA
  22. jnz notCGAVids
  23. sub ax,24 ;for EGA palette settings
  24. jmp short CbSizeExit
  25. notCGAVids:
  26. test [bx].fvmCurAdap, fvmMCGA or fvmVGA
  27. jz CbSizeExit
  28. add ax,255*3 ;for PS2 palette settings
  29. CbSizeExit:
  30. inc ax ;get even cb
  31. and ax,0FFFEh      
  32. cEnd CbSizeVidsCsd
  33. ;********** FSaveVidsCsd ********
  34. ;* entry: pvidsSave = near pointer to VIDS structure
  35. ;* pinst = near pointer to INST for new mode
  36. ;* * fill *pvidsSave with state of current screen mode (not screen data)
  37. ;* exit: AX != 0 if ok, == 0 if error
  38. cProc FSaveVidsCsd, <FAR, PUBLIC, ATOMIC>, <si, di>
  39.     parmDP pvidsSave
  40.     parmDP pinst
  41. cBegin FSaveVidsCsd
  42. mov di,pvidsSave
  43. mov ah,0Fh
  44. int 10h ;* GetMode and page
  45. and  al,07Fh ; clear msb
  46. mov [di].modeVids,al
  47. mov [di].pageVids,bh
  48. mov [di].fClearRegenVids,00H
  49.       
  50. mov ax,SIZE EGA_VIDS - cbVidsMin ;default EGA
  51. mov bx,OFF_lpwDataCsd ;* Data in data segment
  52. test [bx].fvmCurAdap, fvmEGA or fvmVGA or fvm64KEGA or fvmEGAM or fvmMCGA
  53. jnz notFSCGA
  54. sub ax,24 ;EGA palette regs
  55. jmp short notFSPS2
  56. notFSCGA:
  57. test [bx].fvmCurAdap, fvmMCGA or fvmVGA
  58. jz notFSPS2
  59. add ax,255*3 ;DAC color regs
  60. notFSPS2:
  61. inc ax ;get even cb
  62. and ax,0FFFEh      
  63. shr ax,1
  64. mov [di].cwExtraVids,ax
  65. mov ah,3
  66. int 10h ;* GetCursorPos
  67. mov [di].vparmCursorVids,cx
  68. mov ax,ds
  69. mov es,ax
  70. mov dx,di
  71. lea di,[di].rgwCursorPosVids ;* save cursor positions here
  72. push ds
  73. xor ax,ax
  74. mov ds,ax
  75. mov si,BIOS_cursor_posn ;* 8 Cursor positions in BIOS
  76. mov cx,8
  77. rep movsw
  78. pop ds
  79. mov di,dx ; restore di
  80. public saveCGAPal ;UNDONE - remove these two lines
  81. saveCGAPal: ;UNDONE
  82. ;
  83. ; Assumes bCGABg is immediately before bCGAPal
  84. ; and bCGABgVids is immediately before bCGAPalVids
  85. ;
  86. .errnz (bCGABgVids+1) - bCGAPalVids
  87. .errnz (bCGABg+1) - bCGAPal
  88. mov ax, word ptr cs:[bCGABg]
  89. mov word ptr [di].bCGABgVids, ax
  90. mov dl, [di].modeVids
  91. cmp dl,40H ;Olivetti
  92. jz @F
  93. test [bx].fvmCurAdap, fvmCGA
  94. jz skipCGA
  95. @@:
  96. ;* for CGA only
  97. xor ax,ax
  98. mov es,ax
  99. mov al, byte ptr es:[466H]
  100. mov [di].ayOverScanVids, al
  101. mov ax, 80*25 ; Maybe we can get by just saving what we use (4k b).
  102. cmp dl, 2
  103. je save_not_graphics
  104. cmp dl, 3
  105. je save_not_graphics
  106. mov ax, 8*1024 ; Must mode switch (4,5,6) so must save all of regen(16k b)
  107. cmp dl, 40H ; Is this an Olivetti graphics screen mode?
  108. jne @F
  109. add ax, ax ; Yes, there is twice as much memory to save
  110. @@:
  111. save_graphics:
  112. and [di].fvidsVids,not fvidsChAttr ;graphics modes 
  113. save_not_graphics: ;* ax = # of words to swap
  114. mov [di].cwSwapVids,ax
  115. jmp EgaSS_Exit
  116. skipCGA:
  117. test [bx].fvmCurAdap, fvmEGA or fvmVGA or fvm64KEGA or fvmEGAM or fvmMCGA
  118. jz @F
  119. cCall EgaSavePalette ;save palette regs
  120. @@:
  121. push bp
  122. mov ax,1130h ; get info
  123. xor bx,bx
  124. xor cx,cx
  125. int 10h
  126. pop bp
  127. inc dl ; dl = scan lines
  128. mov [di].ayMacVids,dl ; rows
  129. mov [di].ayPointsVids,cl ; cl = number of lines in char
  130. cmp [di].modeVids,4 ;check simple graphics
  131. jb notmode4to6
  132. cmp [di].modeVids,6
  133. ja notmode4to6
  134. mov ax,8*1024 ; Must mode switch (4,5,6) so must save all of regen(16k b)
  135. mov [di].cwSwapVids,ax
  136. and [di].fvidsVids,not fvidsChAttr ;graphics modes 
  137. jmp EgaSS_Exit
  138. notmode4to6:
  139. mov ax,80 ;default 80 columns
  140. mov si,pinst
  141. cmp dl,[si].ayMacInst ;rows
  142. ja AboveNewAy
  143. mov dl,[si].ayMacInst ;assume going into text mode
  144. AboveNewAy:
  145. mul dl ;columns * rows
  146. mov cl,[di].modeVids
  147. cmp cl, 08H
  148. ja EgaSS_Hard
  149. cmp cl, 07H
  150. jb NotHerc
  151. ; We are in mode 7 or 8 so we might have a Hercules card.
  152. push ax ;Save cwSwap
  153. mov ah,0efH
  154. mov dl, -1
  155. int 10H
  156. pop ax ;restore cwSwap
  157. inc dl
  158. jz NotHerc ;DL not changed by INT 10 unless herc.
  159. mov ax,8*1024 ;Must save 8k words for herc
  160. ;We would only have to save 4K words
  161. ;If it weren't for Compaq's stupid
  162. ;BIOS which always clears 16K bytes
  163. ;when switching into mode 7.
  164. mov [di].fClearRegenVids,80H
  165. NotHerc:
  166. mov [di].cwSwapVids,ax
  167. mov [di].fvidsVids,fvidsChAttr ;Text modes 
  168. jmp EgaSS_Exit
  169. ; *** Graphics Text ***
  170. ; Ok, we are in one of the difficult graphics modes.
  171. ; We must save cLines*80 words from bit plane 0 and the same from bit plane 1
  172. ; and we must save 4k words from bit plane 2 (because the character
  173. ; generator gets loaded into this area when we switch to alpha mode).
  174. EgaSS_Hard:
  175. mov [di].cwSwapVids,ax
  176. and [di].fvidsVids,not fvidsChAttr ;graphics modes 
  177. mov ax, 2*1024 ; MCGA uses 2k words
  178. mov bx,OFF_lpwDataCsd ;* Data in data segment
  179. test [bx].fvmCurAdap, fvmMCGA
  180. jnz EgaSS_Alloc
  181. mov ax,[di].cwSwapVids ; ax == cLines*cColumns words
  182. shl ax,1 ; for bit plane 0 and 1
  183. EgaSS_Alloc:
  184. add ax, 4*1024 ; Save 4k words of bit plane 2
  185. test [bx].fvmCurAdap, fvm64KEGA
  186. jz EgaSS_Exit
  187. ; More memory gets trashed by the BIOS doing a mode reset on a 64k Ega.
  188. ; Note: On a 64k Ega, the 4k words starting at 16k of bit plane 2 also get
  189. ;       trashed by the BIOS for some reason (so we gotta save that too).
  190. add ax,4*1024
  191. EgaSS_Exit:
  192. mov [di].cwVidDataVids,ax
  193. mov ax,sp ;* success
  194. cEnd FSaveVidsCsd
  195. ;********** EgaSavePalette ********
  196. ;*
  197. ;* entry: ds:[di] => Vids
  198. cProc EgaSavePalette,<NEAR,PUBLIC>,<SI,DI,ES>
  199. cBegin EgaSavePalette
  200. mov bx,OFF_lpwDataCsd ;* Data in data segment
  201. mov ax,ds
  202. mov es,ax
  203. test [bx].fvmCurAdap, fvmMCGA or fvmVGA  ;PS2 ?
  204. jz @F
  205. lea dx, [di].rgbPS2PaletteVids
  206. mov ax, 1017H ; Read block of Palette regs
  207. xor bx,bx ;    start at reg 0
  208. mov cx, 256 ;    read 256 regs
  209. int 10H
  210. @@:
  211. mov bx,OFF_lpwDataCsd ;* Data in data segment
  212. test [bx].fvmCurAdap, fvmEGA or fvmVGA or fvm64KEGA or fvmEGAM
  213. jz @F
  214. push ds
  215. pop es
  216. lea di, [di].rgbEgaPaletteVids ;es:[di] -> buffer
  217. push cs
  218. pop ds
  219. mov si, DrvOffset EGAPaletteMirror
  220. mov cx,17 ;16 palette + overscan regs
  221. rep movsb
  222. push ss
  223. pop ds ;restore ds
  224. @@:
  225. cEnd EgaSavePalette
  226. ;********** FRestoreVidsCsd ********
  227. ;* entry: pvidsRestore = near pointer to VIDS structure
  228. ;* * restore video state with data in *pvidsRestore (not screen data)
  229. ;* exit: AX != 0 if ok, == 0 if error
  230. cProc FRestoreVidsCsd, <FAR, PUBLIC, ATOMIC>, <si, di>
  231.     parmDP pvidsRestore
  232. cBegin FRestoreVidsCsd
  233. mov di,pvidsRestore
  234. mov al, [di].modeVids
  235. cmp al, 2
  236. je EgaFRS_Text
  237. cmp al, 3
  238. je EgaFRS_Text
  239. cmp al, 40H ;[==] Olivetti
  240. je EgaFRS_SimpleGraphics ;[==]
  241. cmp al, 8
  242. ja EgaFRs_HardGraphics
  243. cmp al, 7
  244. jae EgaFRS_Text
  245. EgaFRS_SimpleGraphics: ;mode 4,5 & 6
  246. cCall SetVideoMode
  247. jmp EgaFRS_Common
  248. EgaFRS_Text: ; mode 2,3 and 7
  249. mov bx,OFF_lpwDataCsd ;* Data in data segment
  250. cmp [bx].fBlinkEnable,0
  251. je @F ;trash ax,dx
  252. mov [bx].fBlinkEnable,0 ;disable Blink
  253. cCall DiddleBlinkbit
  254. jmp short RestoreBlink
  255. @@:
  256. mov [bx].fBlinkEnable,1 ;enable Blink
  257. cCall EnableBlinkbit
  258. RestoreBlink:
  259. mov bx,OFF_lpwDataCsd ;* Data in data segment
  260. test [bx].fvmCurAdap, fvmVGA  ;VGA ?
  261. jz EgaFRs_SetScanLines_done
  262. mov al,2 ;default 400 lines
  263. cmp [di].ayMacVids,43      ; 43 line mode
  264. jne useDefaultLine
  265. dec al ;set 350 scan line
  266. useDefaultLine:
  267. mov ah,12h ;set vertical scan line
  268. mov bl,30h
  269. int 10h ;takes effect on next mode set
  270. EgaFRs_SetScanLines_done:
  271. cCall SetVideoMode
  272. or ax,ax ;mode set ?
  273. jz EgaFRS_Common
  274. cmp [di].ayPointsVids,8 ;8x8 font ?
  275. jne EgaFRS_Common
  276. mov ax,1112h
  277. mov bh,8
  278. xor bl,bl
  279. int 10h
  280. jmp EgaFRS_Common
  281. EgaFRS_HardGraphics:
  282. cCall ClearRegen
  283. cCall SetVideoMode
  284. cmp [di].ayPointsVids, 8
  285. jne EgaFRs_NoLoad8
  286. mov ax,1123h
  287. xor bh,bh
  288. mov bl,[di].modeVids
  289. sub bl,0dh
  290. mov dl,cs:[GraphicsModeRows+bx]
  291. xor bl,bl
  292. int 10h
  293. EgaFRs_NoLoad8:
  294. EgaFRs_Common:
  295. mov al,[di].pageVids
  296. mov ah,5
  297. int 10h ;* SetPage
  298. mov dx,di
  299. xor ax,ax
  300. mov es,ax
  301. lea si,[di].rgwCursorPosVids
  302. mov di,BIOS_cursor_posn
  303. mov cx,8
  304. rep movsw
  305. mov di,dx
  306. mov bl,[di].pageVids
  307. xor bh,bh
  308. shl bx,1
  309. mov dx,[di+bx].rgwCursorPosVids ;* get cursor pos for this page
  310. shr bx,1
  311. mov bh,bl
  312. mov ah,2
  313. int 10h ;* SetCursorPos
  314. mov cx,[di].vparmCursorVids
  315. mov ah,1
  316. int 10h ;* SetCursor
  317. cmp [di].modeVids,40H ;Don't EgaRestore palette for
  318. je @F ; Olivetti
  319. mov bx,OFF_lpwDataCsd ;* Data in data segment
  320. test [bx].fvmCurAdap, fvmEGA or fvmVGA or fvm64KEGA or fvmEGAM or fvmMCGA
  321. jz @F
  322. cCall EgaRestorePalette
  323. @@:
  324. public restoreCGAPal ;UNDONE - remove
  325. restoreCGAPal: ;UNDONE - remove
  326. push bx
  327. mov bl, [di].bCGAPalVids
  328. or bl,bl
  329. js @F ;* skip if negative
  330. mov bh,1
  331. mov ah,0BH
  332. int 10H ;* set color palette
  333. @@:
  334. mov bl, [di].bCGABgVids
  335. or bl,bl
  336. js @F ;* skip if negative
  337. xor bh,bh
  338. mov ah,0BH
  339. int 10H ;* set background color
  340. @@:
  341. pop bx
  342. test [bx].fvmCurAdap, fvmCGA  ;CGA ?
  343. jz @F
  344. xor ax,ax
  345. mov es,ax
  346. mov al, [di].ayOverScanVids
  347. mov byte ptr es:[466H],al
  348. mov dx, 3d9H
  349. out dx, al
  350. @@:
  351. mov ax,sp ;* success
  352. cEnd FRestoreVidsCsd
  353. ;********** EgaRestorePalette ********
  354. ;*
  355. ;*
  356. cProc EgaRestorePalette,<NEAR,PUBLIC>,<SI,DI,ES>
  357. cBegin  EgaRestorePalette
  358. mov bx,OFF_lpwDataCsd ;* Data in data segment
  359. mov ax,ds
  360. mov es,ax
  361. test [bx].fvmCurAdap, fvmMCGA or fvmVGA  ;PS2 ?
  362. jz @F
  363. lea dx, [di].rgbPS2PaletteVids
  364. mov ax, 1012H ; write block of Palette regs
  365. xor bx,bx ;    start at reg 0
  366. mov cx, 256 ;    read 256 regs
  367. int 10H
  368. @@:
  369. mov bx,OFF_lpwDataCsd ;* Data in data segment
  370. test [bx].fvmCurAdap, fvmEGA or fvmVGA or fvm64KEGA or fvmEGAM
  371. jz @F
  372. cmp cs:[lpbBIOSINT10_Offset],0 ;save check
  373. je @F
  374. mov ax,1002h
  375. lea dx, [di].rgbEGAPaletteVids ;es:[dx] -> buffer
  376. int 10h
  377. @@:
  378. cEnd EgaRestorePalette
  379. ;***********************
  380. cProc EnableBlinkBit, <NEAR, ATOMIC, PUBLIC>, <DS>
  381. cBegin EnableBlinkBit
  382. ;* * Diddle blink bit via BIOS call (or diddle CGA bit)
  383. mov bx,OFF_lpwDataCsd ;* Data in data segment
  384. test [bx].fvmCurAdap, fvmCGA or fvmMDA
  385. jz EBB_NotCGA
  386. xor ax,ax
  387. mov ds,ax
  388. mov dx,ds:[BIOS_addr_6845]
  389. add dx,PORT_mode
  390. ;* * set the mode set flag
  391. or byte ptr ds:[BIOS_crt_mode_set],20H
  392. mov al,ds:[BIOS_crt_mode_set]
  393. out dx,al ;* send to port
  394. ;* * EGA etc has a BIOS call for this
  395. EBB_NotCGA:
  396. mov ax,1003H ;* set intensify/blink
  397. mov bx,1 ;* enable blink
  398. int 10h
  399. cEnd EnableBlinkBit
  400. ;********** SetVideoMode **********
  401. ;* entry: al = video mode
  402. ;* * Set specified video mode
  403. ;* exit: trash ax,cx,es
  404. ;* ax = 0 same mode,-1 mode set
  405. cProc SetVideoMode,<NEAR>,<es>
  406. cBegin SetVideoMode
  407. mov ah,0Fh
  408. int 10h ;* GetMode
  409. and al,7fh
  410. cmp al,[di].modeVids
  411. jne SVM_SetMode      ;reset
  412. ;same mode, check rows
  413. mov bx,OFF_lpwDataCsd ;* Data in data segment
  414. test ss:[bx].fvmCurAdap, fvmCGA ;CGA only support 25 rows
  415. jnz @F ; jnz mode_already_set
  416. push bp
  417. mov ax,1130h ; get info
  418. xor bx,bx
  419. xor cx,cx
  420. int 10h
  421. pop bp
  422. inc dx ; dl = scan lines
  423. cmp dl,[di].ayMacVids ; rows
  424. jne SVM_SetMode
  425. @@:
  426. jmp mode_already_set
  427. SVM_SetMode:
  428. mov al,[di].modeVids
  429. or al,[di].fClearRegenVids
  430. mov bx,OFF_lpwDataCsd ;* Data in data segment
  431. test ss:[bx].fvmCurAdap, fvmEGA or fvmVGA or fvm64KEGA or fvmMCGA or fvmEGAM
  432. jz TrashRegen ;CGA doesn't support the function below
  433. cmp al, 40H ;Olivetti doesn't support it either.
  434. je TrashRegen
  435. or al,80h ;* don't clear RGEN
  436. ; The following section is to make switching between color and monochrome
  437. ; modes work on all VGA's.  On Olivetti VGA's and PS/2 VGA's this works
  438. ; automatically, but on IBM AT-card VGA's and other CLONES, a hack is
  439. ; needed to make it work.  If it's a VGA, we change the equipment flags
  440. ; to match the mode we're going into (mono or color).  We also have to
  441. ; call INT 10, function 12, sub-function 33 to turn gray-scale summing on
  442. ; or off if a color display is attached.
  443. test ss:[bx].fvmCurAdap, fvmVGA ;[1]
  444. je TrashRegen ;[1]
  445. push ax ; save mode
  446. xor cx,cx ;
  447. mov es,cx ;
  448. mov ah,es:[410h] ; get equipment flags
  449. or ah,30h ;
  450. and al,07h ; check for mode 7 or f
  451. sub al,07h ; mono mode?
  452. jz @F ; brif -- go set equipment flags
  453. mov al,1 ; turn off summing if color monitor
  454. and ah,0EFh ; set equipment flags for Color80
  455. @@: ;
  456. mov es:[410h],ah ; uddate equipment flags
  457. cmp ss:[bx].fvmCurDisp, fvmMD ; monochrome analog monitor?
  458. je @F ; brif so -- leave summing on
  459. push bx ; save OFF_lpwDataCsd
  460. mov bl,33h ;
  461. mov ah,12h ; turn gray-scale summing on/off
  462. int 10h ;
  463. pop bx ; restore bx = OFF_lpwDataCsd
  464. @@: ;
  465. pop ax ; restore al = mode
  466. TrashRegen:
  467. xor ah,ah
  468. push ax ;save mode
  469. int 10h ;* set mode
  470. pop ax ;restore
  471. ;* * Delay so that we won't start writting to the display before it has
  472. ;* * settled down.
  473. mov cx,500
  474. delay_me:
  475. loop delay_me
  476. ;
  477. ; When the olivetti is in mode 40H the value at BIOS_info is a pointer to
  478. ; the character set (NOT flags as it is in EGA modes)
  479. ; So let's not trash the pointer by clearing the "don't clear regen" bit.
  480. ;
  481. cmp al, 40H
  482. je @F
  483. test ss:[bx].fvmCurAdap, fvmEGA or fvmVGA or fvm64KEGA or fvmMCGA or fvmEGAM
  484. jz @F
  485. ;* Clear the "don't clear regen" bit in the BIOS image
  486. xor ax,ax
  487. mov es,ax
  488. and byte ptr es:[BIOS_info],7fH ;487H
  489. mov al,[di].ayMacVids ;
  490. dec ax ; rows - 1
  491. mov byte ptr es:[0484H],al ; * update BIOS rows
  492. @@:
  493. ;
  494. ; The following is provided only to overcome a bug in the EGA BIOS
  495. ; routines which support the graphics "compatibility mode" (BIOS 4)
  496. ; so that the two calls related to PALETTE (INT10 AH = 0BH and
  497. ; INT10H AH = 10H) work correctly.  If we use the first call once
  498. ; when user invokes SCREEN 1 to set the background color, then the
  499. ; BIOS will subsequently reference the correct (low-intensity)
  500. ; color values for the 4 palette attributes whenever the call using
  501. ; INT10H, AH = 0BH is used to toggle the palette, and whenever the
  502. ; call INT10H, AH = 10H is used to set an individual palette regis-
  503. ; ter.  In the absence of this initialization, the high-intensity
  504. ; color values for both palettes are referenced.
  505. ;
  506. test ss:[bx].fvmCurAdap, fvmEGA or fvmVGA or fvm64KEGA or fvmEGAM
  507. jz SkipKludge
  508. mov al, [di].modeVids
  509. cmp al,4
  510. je @F
  511. cmp al,5
  512. jne SkipKludge
  513. @@:
  514. push bx
  515. xor bx,bx
  516. mov ah, 0BH
  517. int 10H ;set background color
  518. pop bx
  519. SkipKludge:
  520. mov ax,-1 ;mode set
  521. jmp short @F
  522. mode_already_set:
  523. xor ax,ax ;same mode
  524. @@:
  525. cEnd SetVideoMode
  526. ;********** SaveVidDataCsd ********
  527. ;* entry: pvidsSaveData = near pointer to VIDS structure
  528. ;* lpwBuffer = buffer to save data
  529. ;* * save screen data into buffer
  530. ;* exit: n/a
  531. cProc SaveVidDataCsd, <FAR, PUBLIC, ATOMIC>, <DS, SI, DI>
  532.     parmDP pvidsSaveData
  533.     parmD  lpwBuffer
  534. cBegin SaveVidDataCsd
  535. mov di,pvidsSaveData
  536. mov si,di
  537. mov dl,[di].modeVids
  538. mov cx,0B800h
  539. cmp dl,7
  540. jb @F
  541. cmp dl,8
  542. ja @F
  543. mov cx,0B000h ;video segment for mono mode
  544. @@:
  545. mov ax,[di].cwSwapVids
  546. les di,lpwBuffer ;es:[di] -> buffer
  547. cmp dl,40h ;Olivetti ?
  548. je @F
  549. cmp dl,8
  550. ja save_graphics_text
  551. @@: ;Text modes or mode 6
  552. cCall SaveRegen
  553. mov di,si
  554. cCall  ClearRegen
  555. jmp SaveVidsDataExit
  556. save_graphics_text:
  557. mov bx,OFF_lpwDataCsd ;* Data in data segment
  558. mov ax, 0a000H ; Address of bit planes
  559. mov ds, ax ;ds:[si] -> video buffer
  560. test ss:[bx].fvmCurAdap, fvmMCGA
  561. jz EgaSS_NotMCGA
  562. mov si, 8000H
  563. mov cx, 2*1024
  564. EgaSS_MCGA1:
  565. xor ax,ax
  566. xchg ax, [si]
  567. inc si
  568. inc si
  569. stosw
  570. loop EgaSS_MCGA1
  571. jmp short EgaSS_SaveBitPlane2
  572. EgaSS_NotMCGA:
  573. mov cl, 0     ;bit plane 0
  574. mov bx,pvidsSaveData
  575. mov ax, ss:[bx].cwSwapVids
  576. cCall SaveBitPlane
  577. mov cl, 1 ;bit plane 1
  578. mov bx,pvidsSaveData
  579. mov ax, ss:[bx].cwSwapVids
  580. cCall SaveBitPlane
  581. EgaSS_SaveBitPlane2:
  582. mov cl, 2 ;bit plane 2
  583. mov ax, 4*1024
  584. cCall SaveBitPlane
  585. ;
  586. ; The 8k bytes starting at 16k only gets trashed on 64k Ega cards
  587. ;
  588. mov bx,OFF_lpwDataCsd ;* Data in data segment
  589. test ss:[bx].fvmCurAdap, fvm64KEGA
  590. jz EgaSs_64plus
  591. mov cl, 2
  592. mov ax, 4*1024
  593. mov si, 16*1024
  594. cCall SaveBitPlane2
  595. EgaSs_64plus:
  596. push ss ; Restore ds
  597. pop ds
  598. mov bx,OFF_lpwDataCsd ;* Data in data segment
  599. test [bx].fvmCurAdap, fvmMCGA
  600. jnz EgaSS_NotMCGA2
  601. mov di,pvidsSaveData
  602. cCall ClearBitPlanes
  603. EgaSS_NotMCGA2:
  604. SaveVidsDataExit:
  605. cEnd SaveVidsDataCsd
  606. ;***
  607. ;
  608. ;  SaveRegen - Saves the video regen buffer to global memory
  609. ;
  610. ;  Inputs: [ax] - Number of words to save
  611. ; [di] - Points to a VideoState buffer where handle to
  612. ;        global memory used to save the regen buffer is
  613. ;        store (along with the size of the saved buffer)
  614. ; [es] - Segment of video regen buffer
  615. ;
  616. ;
  617. ;  Outputs: none.
  618. ;
  619. ;  Uses: es, si
  620. ;
  621. ;****
  622. cProc SaveRegen,<NEAR>,<DI,SI>
  623. cBegin SaveRegen
  624. push ds
  625. mov ds,cx
  626. mov cx,ax
  627. xor si,si
  628. ; cCall VideoOff ; (CGA) Only affects ax and dx
  629. rep movsw
  630. pop ds
  631. ; cCall VideoOn
  632. NoRegenSave:
  633. cEnd SaveRegen
  634. cProc VideoOff,<NEAR,PUBLIC>,<ES> ;trash ax,dx
  635. cBegin VideoOff
  636. mov dx,CGA_6845_STATUS
  637. WaitVerticalRetrace:
  638. in al,dx 
  639. test al,08H
  640. jz WaitVerticalRetrace
  641. xor ax,ax
  642. mov es,ax 
  643. mov ax,es:[0465H] ; Get Current CRT mode
  644. and ax, NOT 0008H ; turn off video signal bit
  645. mov dx,CGA_6845_MODE
  646. out dx,al 
  647. cEnd VideoOff
  648. cProc VideoOn,<NEAR,PUBLIC>,<ES> ;trash ax,dx
  649. cBegin VideoOn
  650. xor ax,ax
  651. mov es,ax 
  652. mov ax,es:[0465H]  ; Get Current CRT mode
  653. or ax,0008H ; Turn on video signal bit
  654. mov dx,CGA_6845_MODE
  655. out dx,al 
  656. cEnd VideoOn
  657. ;***
  658. ;
  659. ;  ClearRegen - Clears the part of the regen buffer used by TWIN.
  660. ;
  661. ;  Inputs: [di] - Points to a VideoState buffer containing the
  662. ;        video state to be restored.
  663. ; [videoseg] - Segment of video regen buffer
  664. ;
  665. ;  Outputs: The global memory used to save the regen buffer is freed.
  666. ; i.e. don't call RestoreRegen again with the save video state.
  667. ;
  668. ;  Uses: es,di
  669. ;
  670. ;****
  671. cProc ClearRegen,<NEAR>,<di,es>
  672. cBegin ClearRegen
  673. mov ax, 0720H ; Assume text mode (clear to spaces)
  674. mov cx, 0B800h ; EGA
  675. mov bl, [di].modeVids
  676. cmp bl, 3
  677. jbe CR_1
  678. cmp bl,7
  679. jb @F
  680. cmp bl,8
  681. ja @F
  682. mov cx,0B000h
  683. jmp short CR_1
  684. @@:
  685. xor ax,ax ; Clear to Null for graphics modes.
  686. CR_1:
  687. mov es, cx ; Clear the part of the regen buffer
  688. mov cx, [di].cwSwapVids ; Save for later
  689. xor di,di ; that we used.
  690. rep stosw
  691. cEnd ClearRegen
  692. ;***
  693. ;
  694. ;  RestoreRegen - Restores the video regen buffer from pVideoState
  695. ;
  696. ;  Inputs: [di] - Points to a VideoState buffer containing the
  697. ;        video state to be restored.
  698. ; [videoseg] - Segment of video regen buffer
  699. ; cx = video segment
  700. ;
  701. ;  Outputs: NZ - if restore ok
  702. ; Z - if not restored
  703. ;
  704. ;               The global memory used to save the regen buffer is freed.
  705. ; i.e. don't call RestoreRegen again with the save video state.
  706. ;
  707. ;  Uses: es, si
  708. ;
  709. ;****
  710. cProc RestoreRegen,<NEAR>,<di>
  711. cBegin RestoreRegen
  712. mov es,cx
  713. mov cx,ax
  714. xor di,di
  715. rep movsw
  716. cEnd RestoreRegen
  717. ; SaveBitPlane - Saves a given number of words from a given bit plane.
  718. ;
  719. ; INPUT:
  720. ;    ax - Number of words to save
  721. ;    cl - Number of bit plane
  722. ;    ds - is the segment address of the bit plane.
  723. ;    es:di - where to save.
  724. ;              
  725. ; OUTPUT:
  726. ;    ES:DI - Points 1 word past the last saved word
  727. ;
  728. ; USES:
  729. ;    SI
  730. ;
  731. cProc SaveBitPlane,<NEAR>
  732. cBegin SaveBitPlane
  733. xor si,si
  734. LabelNP <SaveBitPlane2>
  735. push ax ; Save count of words
  736. cCall MapBitPlane
  737. pop cx ; Restore
  738. rep movsw
  739. cEnd SaveBitPlane
  740. ;
  741. ; RestoreBitPlane - Restores a given number of words to a given bit plane.
  742. ;
  743. ; INPUT:
  744. ;    ax - Number of words to restore
  745. ;    cl - Number of bit plane
  746. ;    es - is the segment address of the bit plane.
  747. ;    ds:si - where to restore from.
  748. ;              
  749. ; OUTPUT:
  750. ;    ds:si - Points 1 word past the last restored word
  751. ;
  752. ; USES:
  753. ;    DI
  754. ;
  755. cProc RestoreBitPlane,<NEAR>
  756. cBegin RestoreBitPlane
  757. xor di,di
  758. LabelNP <RestoreBitPlane2>
  759. push ax ; Save count of words
  760. cCall MapBitPlane
  761. pop cx ; Restore
  762. rep movsw
  763. cEnd RestoreBitPlane
  764. ;
  765. ; MapBitPlane - Maps the specified bit plane in for read/write
  766. ;
  767. ; INPUT:
  768. ;    CL - the bit plane.
  769. ;
  770. cProc MapBitPlane,<NEAR>
  771. cBegin MapBitPlane
  772. mov al, 2 ; Set Map Mask register
  773. mov ah, 1
  774. shl ah, cl
  775. cCall SetEgaSequencer ; Only trashes DX,AX
  776. mov al, 4 ; Read Map Select
  777. mov ah,cl
  778. mov dx, 3ceH ; Graphics Controler Address Port
  779. cCall OutWord
  780. cEnd MapBitPlane
  781. cProc ClearBitPlanes,<NEAR>,<DI,SI>
  782. cBegin ClearBitPlanes
  783. mov si,di ; ds:si -> saved video state
  784. mov ax, 0a000H
  785. mov es,ax
  786. mov cl, 0 ; Map in bit plane 0
  787. cCall MapBitPlane
  788. xor di,di
  789. mov cx, [si].cwSwapVids
  790. xor ax,ax
  791. rep stosw
  792. mov cl, 1 ; Map in bit plane 1
  793. cCall MapBitPlane
  794. xor di,di
  795. mov cx, [si].cwSwapVids
  796. xor ax,ax
  797. rep stosw
  798. mov cl, 2 ; Map in bit plane 2
  799. cCall MapBitPlane
  800. xor di,di
  801. mov cx, 8*1024/2
  802. xor ax,ax
  803. rep stosw
  804. push ss
  805. pop ds ; Restore ds
  806. cEnd ClearBitPlanes
  807. ; SetEgaSequencer - Sends data to the Ega sequencer
  808. ;
  809. ; INPUT:
  810. ;    AL - Sequencer register number
  811. ;         00 Reset
  812. ;         01 Clocking Mode
  813. ;         02 Map Mask
  814. ;         03 Character Map Select
  815. ;         04 Memory Mode
  816. ;    AH - Data for the register
  817. ;
  818. cProc SetEgaSequencer,<NEAR>
  819. cBegin SetEgaSequencer
  820. mov dx, 3c4H ; Ega Sequencer Address Port
  821. cCall OutWord
  822. cEnd SetEgaSequencer
  823. ;
  824. ; This is just an `out dx,ax' kludge to ensure that it works on
  825. ; AT&T 6300
  826. ;
  827. cProc OutWord,<NEAR>
  828. cBegin OutWord
  829. out dx, al
  830. jmp short OUTWORD_1 ; I/O delay
  831. OUTWORD_1:
  832. inc dx
  833. mov al,ah
  834. out dx, al
  835. cEnd OutWord
  836. ;********** RestoreVidDataCsd ********
  837. ;* entry: pvidsRestoreData = near pointer to VIDS structure
  838. ;* lpwBuffer = buffer to save data (NULL => just clear screen)
  839. ;* * restore screen data from buffer
  840. ;* exit: n/a
  841. cProc RestoreVidDataCsd, <FAR, PUBLIC, ATOMIC>, <DS, SI, DI>
  842.     parmDP pvidsRestoreData
  843.     parmD  lpwBuffer
  844. cBegin RestoreVidDataCsd
  845. mov di,pvidsRestoreData
  846. mov al, [di].modeVids
  847. cmp al, 3
  848. jb EgaRS_Text
  849. cmp al, 7
  850. je EgaRS_Text
  851. jb EgaRS_SimpleGraphics
  852. cmp al,8
  853. je EgaRs_Text
  854. cmp al,40h ;Olivetti ?
  855. je EgaRS_SimpleGraphics
  856. jmp short EgaRs_HardGraphics
  857. EgaRS_SimpleGraphics: ;mode 6
  858. push ax
  859. cCall ClearRegen
  860. pop ax
  861. EgaRS_Text: ; mode 2,3 and 7,8
  862. mov cx,0B800h
  863. cmp al, 7
  864. jb @F
  865. cmp al,8
  866. ja @F
  867. mov cx,0B000h
  868. @@:
  869. mov ax,[di].cwSwapVids
  870. lds si,lpwBuffer
  871. cCall RestoreRegen
  872. jmp RestoreVidsCsd_exit
  873. EgaRS_HardGraphics:
  874. cCall ClearRegen
  875. mov ax, 0a000H ; Address of bit planes
  876. mov es, ax
  877. lds si,lpwBuffer ;ds:[si] -> buffer
  878. mov bx,OFF_lpwDataCsd ;* Data in data segment
  879. test ss:[bx].fvmCurAdap, fvmMCGA
  880. jz EgaRs_NotMCGA
  881. mov di, 8000H
  882. mov cx, 2*1024
  883. rep movsw
  884. jmp short EgaRs_RestoreBitPlane2
  885. EgaRs_NotMCGA:
  886. mov cl, 0
  887. mov di,pvidsRestoreData
  888. mov ax, ss:[di].cwSwapVids
  889. cCall RestoreBitPlane
  890. mov cl, 1
  891. mov di,pvidsRestoreData
  892. mov ax, ss:[di].cwSwapVids
  893. cCall RestoreBitPlane
  894. EgaRs_RestoreBitPlane2:
  895. mov cl, 2
  896. mov ax, 4*1024
  897. cCall RestoreBitPlane
  898. ;
  899. ; The 8k bytes starting at 16k only gets trashed on 64k Ega cards
  900. ;
  901. mov bx,OFF_lpwDataCsd ;* Data in data segment
  902. test ss:[bx].fvmCurAdap, fvm64KEGA
  903. jz EgaRs_64plus
  904. mov cl, 2
  905. mov ax, 4*1024
  906. mov di, 16*1024
  907. cCall RestoreBitPlane2
  908. EgaRs_64Plus:
  909. mov ax,ss ; Restore ds
  910. mov ds,ax
  911. ;
  912. ; Set Map Mask register back to what BASIC expects
  913. ;
  914. mov ax, 0f02H ; Set map mask to 0fH
  915. cCall SetEgaSequencer
  916. jmp RestoreVidsCsd_exit
  917. EgaRs_HardNoRegen:
  918. cCall ClearBitPlanes
  919. RestoreVidsCsd_exit:
  920. cEnd RestoreVidDataCsd
  921. ;
  922. ; INT10Handler
  923. ;    The BIOS INT10 (Video Sevices) is hooked to mirror the palette
  924. ;    registers (so they can be restored).
  925. ;
  926. RegPtr cs_bx, cs, bx
  927. RegPtr es_bx, es, bx
  928. ;********** EnableVidsMonitorCsd ********
  929. ;* entry: fMonitorOn => monitor should be on
  930. ;* * enable/disable INT 10 monitor
  931. ;* exit: n/a
  932. cProc EnableVidsMonitorCsd, <FAR, PUBLIC, ATOMIC>,<di>
  933.     parmW  fMonitorOn
  934. cBegin EnableVidsMonitorCsd
  935. mov di,OFF_lpwDataCsd ;* Data in data segment
  936. cmp fMonitorOn,0
  937. je Unhook
  938. ; Hook int10 trap
  939. test ss:[di].fvmCurAdap, fvmEGA or fvmVGA or fvmMCGA
  940. jz @F
  941. mov [ColourPaletteYellow], 010100B  ;brown
  942. @@:
  943. mov dx,drvOffset ColourPalette    ; Default Enhanced colour
  944. test ss:[di].fvmCurAdap, fvmEGAM
  945. jz @F
  946. mov dx,drvOffset MonoPalette    ; Default Monochrome palette
  947. @@:
  948. push cs
  949. pop ds ;now ds:dx points to source
  950. cCall CopyPalette ; Initialise the user palette
  951. push ss
  952. pop ds ;restore ds
  953. mov ax, 10H
  954. mov bx, drvOffset INT10Handler
  955. cCall HookVector,<ax, cs_bx>
  956. mov cs:[lpbBIOSINT10_Offset], ax
  957. mov cs:[lpbBIOSINT10_Segment], dx
  958. jmp EVM_Exit
  959. Unhook:
  960. ; Unhook int10 trap
  961. les bx, cs:[BIOSINT10]
  962. mov ax, 10H
  963. cCall HookVector,<ax,es_bx>
  964. xor ax,ax       ; clear handler
  965. mov cs:[lpbBIOSINT10_Offset], ax
  966. mov cs:[lpbBIOSINT10_Segment], ax
  967. EVM_Exit:
  968. cEnd EnableVidsMonitorCsd
  969. ;***
  970. ;
  971. ;  HookVector(vecNum, vector)
  972. ;
  973. ;  Sets an interrupt vector and returns the old interrupt vector
  974. ;
  975. ;  Inputs: vecNum - Which vector to set
  976. ; vector - address of the new vector
  977. ;
  978. ;  Outputs: DX:AX == old interrupt vector
  979. ;
  980. ;****
  981. cProc HookVector,<NEAR,PUBLIC>,<DS>
  982. parmB vecNum
  983. parmD vector
  984. cBegin HookVector
  985. mov ah, 35H
  986. mov al, [vecNum]
  987. int 21H ; Get old vector
  988. push bx ; save for return
  989. push es ; save for return
  990. mov ah, 25H
  991. mov al, [vecNum]
  992. lds dx, [vector]
  993. int 21H ; Set new vector
  994. pop dx ; return the old vector
  995. pop ax ; return the old vector
  996. cEnd HookVector
  997. ;-------------------------------------------------------------------;
  998. INT10Handler:
  999. or ah,ah
  1000. jz INT10SetMode
  1001. cmp ah, 10h ;set palette regs ?
  1002. je INT10SetPalette
  1003. cmp ah, 0Bh
  1004. je INT10SetCGABgPal
  1005. INT10_Chain:
  1006. jmp cs:[BIOSINT10]
  1007. INT10SetMode:
  1008. mov cs:[bCGABg],-1 ; bCGABg is now invalid.
  1009. mov cs:[bCGAPal],-1 ; bCGAPal is now invalid.
  1010. jmp short INT10_Chain
  1011. public INT10SetCGABgPal ;UNDONE - Remove.
  1012. INT10SetCGABgPal:
  1013. or bh,bh ;Set Background colour?
  1014. jnz @F ;brif no.
  1015. ;* * assume BH == 1 for setting palette (if not CGA who cares anyway)
  1016. mov cs:[bCGABg],bl
  1017. jmp short INT10_Chain
  1018. @@:
  1019. mov cs:[bCGAPal],bl ;Must be setting CGA Palette
  1020. jmp short INT10_Chain
  1021. INT10SetPalette:
  1022. push ax ; Save the regs we use
  1023. or al,al
  1024. jz INT10_SetIndividualPaletteReg ;ax = 1000h
  1025. dec al
  1026. jz INT10_SetOverscanReg ;     1001h
  1027. dec al
  1028. jz INT10_SetAllPaletteRegs ;     1002h
  1029. INT10_Exit:
  1030. pop ax
  1031. jmp short INT10_Chain
  1032. ;
  1033. ; INT10_SetIndividualPaletteReg
  1034. ;    Sets the specified palette register
  1035. ;
  1036. ; BL - Is the register number (0-15)
  1037. ; BH - Is the value
  1038. ;
  1039. INT10_SetIndividualPaletteReg:
  1040. push bx
  1041. xchg al, bh ; BH <-- 0, AL <-- value
  1042. mov cs:[EgaPaletteMirror+bx], al
  1043. pop bx
  1044. jmp short INT10_SetPaletteCommon
  1045. ;
  1046. ; INT10_SetOverscanReg
  1047. ;    Sets the overscan register
  1048. ;
  1049. ; BH - Is the value.
  1050. ;
  1051. INT10_SetOverscanReg:
  1052. mov cs:[OverScanMirror], bh
  1053. jmp short INT10_Exit
  1054. ;
  1055. ; INT10_SetAllPaletteRegs
  1056. ;    Sets all the palette registers and the overscan register.
  1057. ;
  1058. ; ES:DX - points to table of values for the 16 palette registers and
  1059. ;         the overscan register
  1060. ;
  1061. INT10_SetAllPaletteRegs:
  1062. push ds
  1063. push es
  1064. pop ds ; now ds:dx points to source
  1065. call CopyPalette
  1066. pop ds
  1067. mov cs:[bCGAPal],-1 ; bCGAPal is now invalid.
  1068. INT10_SetPaletteCommon:
  1069. mov cs:[bCGABg],-1 ; bCGABg is now invalid.
  1070. jmp short INT10_Exit
  1071. ;
  1072. ; Copy DS:DX to CS:EgaPaletteMirror
  1073. ;
  1074. cProc CopyPalette,<NEAR>,<SI,DI,CX,ES>
  1075. cBegin CopyPalette
  1076. push cs
  1077. pop es
  1078. mov si, dx
  1079. mov di, DrvOffset EgaPaletteMirror
  1080. mov cx, 17
  1081. rep movsb
  1082. cEnd CopyPalette
  1083. ;***** UNDONE - HACK HACK HACK HACK HACK HACK HACK HACK HACK HACK
  1084. ;***** UNDONE   This piece of code is called directly by QB 4.5
  1085. ;***** UNDONE   It must not be called by QBJ
  1086. ;***** UNDONE   Remove this as soon as QB 4.5 ships.
  1087. cProc SetBlinkBit,<FAR,PUBLIC>
  1088. parmB fOn
  1089. cBegin
  1090. cmp [fOn],0
  1091. je @F
  1092. cCall EnableBlinkBit
  1093. jmp short SBB_Exit
  1094. @@:
  1095. cCall DiddleBlinkBit
  1096. SBB_Exit:
  1097. cEnd