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

操作系统开发

开发平台:

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. ifndef KANJI
  250. mov bx,OFF_lpwDataCsd ;* Data in data segment
  251. cmp [bx].fBlinkEnable,0
  252. je @F ;trash ax,dx
  253. mov [bx].fBlinkEnable,0 ;disable Blink
  254. cCall DiddleBlinkbit
  255. jmp short RestoreBlink
  256. @@:
  257. mov [bx].fBlinkEnable,1 ;enable Blink
  258. cCall EnableBlinkbit
  259. RestoreBlink:
  260. endif ; !KANJI
  261. mov bx,OFF_lpwDataCsd ;* Data in data segment
  262. test [bx].fvmCurAdap, fvmVGA  ;VGA ?
  263. jz EgaFRs_SetScanLines_done
  264. mov al,2 ;default 400 lines
  265. cmp [di].ayMacVids,43      ; 43 line mode
  266. jne useDefaultLine
  267. dec al ;set 350 scan line
  268. useDefaultLine:
  269. mov ah,12h ;set vertical scan line
  270. mov bl,30h
  271. int 10h ;takes effect on next mode set
  272. EgaFRs_SetScanLines_done:
  273. cCall SetVideoMode
  274. or ax,ax ;mode set ?
  275. jz EgaFRS_Common
  276. cmp [di].ayPointsVids,8 ;8x8 font ?
  277. jne EgaFRS_Common
  278. mov ax,1112h
  279. mov bh,8
  280. xor bl,bl
  281. int 10h
  282. jmp EgaFRS_Common
  283. EgaFRS_HardGraphics:
  284. cCall ClearRegen
  285. cCall SetVideoMode
  286. cmp [di].ayPointsVids, 8
  287. jne EgaFRs_NoLoad8
  288. mov ax,1123h
  289. xor bh,bh
  290. mov bl,[di].modeVids
  291. sub bl,0dh
  292. mov dl,cs:[GraphicsModeRows+bx]
  293. xor bl,bl
  294. int 10h
  295. EgaFRs_NoLoad8:
  296. EgaFRs_Common:
  297. mov al,[di].pageVids
  298. mov ah,5
  299. int 10h ;* SetPage
  300. mov dx,di
  301. xor ax,ax
  302. mov es,ax
  303. lea si,[di].rgwCursorPosVids
  304. mov di,BIOS_cursor_posn
  305. mov cx,8
  306. rep movsw
  307. mov di,dx
  308. mov bl,[di].pageVids
  309. xor bh,bh
  310. shl bx,1
  311. mov dx,[di+bx].rgwCursorPosVids ;* get cursor pos for this page
  312. shr bx,1
  313. mov bh,bl
  314. mov ah,2
  315. int 10h ;* SetCursorPos
  316. mov cx,[di].vparmCursorVids
  317. mov ah,1
  318. int 10h ;* SetCursor
  319. cmp [di].modeVids,40H ;Don't EgaRestore palette for
  320. je @F ; Olivetti
  321. mov bx,OFF_lpwDataCsd ;* Data in data segment
  322. test [bx].fvmCurAdap, fvmEGA or fvmVGA or fvm64KEGA or fvmEGAM or fvmMCGA
  323. jz @F
  324. cCall EgaRestorePalette
  325. @@:
  326. public restoreCGAPal ;UNDONE - remove
  327. restoreCGAPal: ;UNDONE - remove
  328. push bx
  329. mov bl, [di].bCGAPalVids
  330. or bl,bl
  331. js @F ;* skip if negative
  332. mov bh,1
  333. mov ah,0BH
  334. int 10H ;* set color palette
  335. @@:
  336. mov bl, [di].bCGABgVids
  337. or bl,bl
  338. js @F ;* skip if negative
  339. xor bh,bh
  340. mov ah,0BH
  341. int 10H ;* set background color
  342. @@:
  343. pop bx
  344. test [bx].fvmCurAdap, fvmCGA  ;CGA ?
  345. jz @F
  346. xor ax,ax
  347. mov es,ax
  348. mov al, [di].ayOverScanVids
  349. mov byte ptr es:[466H],al
  350. mov dx, 3d9H
  351. out dx, al
  352. @@:
  353. mov ax,sp ;* success
  354. cEnd FRestoreVidsCsd
  355. ;********** EgaRestorePalette ********
  356. ;*
  357. ;*
  358. cProc EgaRestorePalette,<NEAR,PUBLIC>,<SI,DI,ES>
  359. cBegin  EgaRestorePalette
  360. mov bx,OFF_lpwDataCsd ;* Data in data segment
  361. mov ax,ds
  362. mov es,ax
  363. test [bx].fvmCurAdap, fvmMCGA or fvmVGA  ;PS2 ?
  364. jz @F
  365. lea dx, [di].rgbPS2PaletteVids
  366. mov ax, 1012H ; write block of Palette regs
  367. xor bx,bx ;    start at reg 0
  368. mov cx, 256 ;    read 256 regs
  369. int 10H
  370. @@:
  371. mov bx,OFF_lpwDataCsd ;* Data in data segment
  372. test [bx].fvmCurAdap, fvmEGA or fvmVGA or fvm64KEGA or fvmEGAM
  373. jz @F
  374. cmp cs:[lpbBIOSINT10_Offset],0 ;save check
  375. je @F
  376. mov ax,1002h
  377. lea dx, [di].rgbEGAPaletteVids ;es:[dx] -> buffer
  378. int 10h
  379. @@:
  380. cEnd EgaRestorePalette
  381. ;***********************
  382. cProc EnableBlinkBit, <NEAR, ATOMIC, PUBLIC>, <DS>
  383. cBegin EnableBlinkBit
  384. ;* * Diddle blink bit via BIOS call (or diddle CGA bit)
  385. mov bx,OFF_lpwDataCsd ;* Data in data segment
  386. test [bx].fvmCurAdap, fvmCGA or fvmMDA
  387. jz EBB_NotCGA
  388. xor ax,ax
  389. mov ds,ax
  390. mov dx,ds:[BIOS_addr_6845]
  391. add dx,PORT_mode
  392. ;* * set the mode set flag
  393. or byte ptr ds:[BIOS_crt_mode_set],20H
  394. mov al,ds:[BIOS_crt_mode_set]
  395. out dx,al ;* send to port
  396. ;* * EGA etc has a BIOS call for this
  397. EBB_NotCGA:
  398. mov ax,1003H ;* set intensify/blink
  399. mov bl,1 ;* enable blink
  400. int 10h
  401. cEnd EnableBlinkBit
  402. ;********** SetVideoMode **********
  403. ;* entry: al = video mode
  404. ;* * Set specified video mode
  405. ;* exit: trash ax,cx,es
  406. ;* ax = 0 same mode,-1 mode set
  407. cProc SetVideoMode,<NEAR>,<es>
  408. cBegin SetVideoMode
  409. mov ah,0Fh
  410. int 10h ;* GetMode
  411. and al,7fh
  412. cmp al,[di].modeVids
  413. jne SVM_SetMode      ;reset
  414. ;same mode, check rows
  415. mov bx,OFF_lpwDataCsd ;* Data in data segment
  416. test ss:[bx].fvmCurAdap, fvmCGA ;CGA only support 25 rows
  417. jnz mode_already_set
  418. push bp
  419. mov ax,1130h ; get info
  420. xor bx,bx
  421. xor cx,cx
  422. int 10h
  423. pop bp
  424. inc dl ; dl = scan lines
  425. cmp dl,[di].ayMacVids ; rows
  426. jne SVM_SetMode
  427. jmp mode_already_set
  428. SVM_SetMode:
  429. mov al,[di].modeVids
  430. or al,[di].fClearRegenVids
  431. mov bx,OFF_lpwDataCsd ;* Data in data segment
  432. test ss:[bx].fvmCurAdap, fvmEGA or fvmVGA or fvm64KEGA or fvmMCGA or fvmEGAM
  433. jz TrashRegen ;CGA doesn't support the function below
  434. cmp al, 40H ;Olivetti doesn't support it either.
  435. je TrashRegen
  436. or al,80h ;* don't clear RGEN
  437. TrashRegen:
  438. xor ah,ah
  439. push ax ;save mode
  440. int 10h ;* set mode
  441. pop ax ;restore
  442. ;* * Delay so that we won't start writting to the display before it has
  443. ;* * settled down.
  444. mov cx,500
  445. delay_me:
  446. loop delay_me
  447. ;
  448. ; When the olivetti is in mode 40H the value at BIOS_info is a pointer to
  449. ; the character set (NOT flags as it is in EGA modes)
  450. ; So let's not trash the pointer by clearing the "don't clear regen" bit.
  451. ;
  452. cmp al, 40H
  453. je @F
  454. test ss:[bx].fvmCurAdap, fvmEGA or fvmVGA or fvm64KEGA or fvmMCGA or fvmEGAM
  455. jz @F
  456. ;* Clear the "don't clear regen" bit in the BIOS image
  457. xor ax,ax
  458. mov es,ax
  459. and byte ptr es:[BIOS_info],7fH ;487H
  460. mov ax,40h
  461. mov es,ax
  462. mov al,[di].ayMacVids ;
  463. dec al ; rows - 1
  464. mov byte ptr es:[0084H],al ;* update BIOS rows
  465. @@:
  466. ;
  467. ; The following is provided only to overcome a bug in the EGA BIOS
  468. ; routines which support the graphics "compatibility mode" (BIOS 4)
  469. ; so that the two calls related to PALETTE (INT10 AH = 0BH and
  470. ; INT10H AH = 10H) work correctly.  If we use the first call once
  471. ; when user invokes SCREEN 1 to set the background color, then the
  472. ; BIOS will subsequently reference the correct (low-intensity)
  473. ; color values for the 4 palette attributes whenever the call using
  474. ; INT10H, AH = 0BH is used to toggle the palette, and whenever the
  475. ; call INT10H, AH = 10H is used to set an individual palette regis-
  476. ; ter.  In the absence of this initialization, the high-intensity
  477. ; color values for both palettes are referenced.
  478. ;
  479. test ss:[bx].fvmCurAdap, fvmEGA or fvmVGA or fvm64KEGA or fvmEGAM
  480. jz SkipKludge
  481. mov al, [di].modeVids
  482. cmp al,4
  483. je @F
  484. cmp al,5
  485. jne SkipKludge
  486. @@:
  487. push bx
  488. xor bx,bx
  489. mov ah, 0BH
  490. int 10H ;set background color
  491. pop bx
  492. SkipKludge:
  493. mov ax,-1 ;mode set
  494. jmp short @F
  495. mode_already_set:
  496. xor ax,ax ;same mode
  497. @@:
  498. cEnd SetVideoMode
  499. ;********** SaveVidDataCsd ********
  500. ;* entry: pvidsSaveData = near pointer to VIDS structure
  501. ;* lpwBuffer = buffer to save data
  502. ;* * save screen data into buffer
  503. ;* exit: n/a
  504. cProc SaveVidDataCsd, <FAR, PUBLIC, ATOMIC>, <DS, SI, DI>
  505.     parmDP pvidsSaveData
  506.     parmD  lpwBuffer
  507. cBegin SaveVidDataCsd
  508. mov di,pvidsSaveData
  509. mov si,di
  510. mov dl,[di].modeVids
  511. mov cx,0B800h
  512. cmp dl,7
  513. jb @F
  514. cmp dl,8
  515. ja @F
  516. mov cx,0B000h ;video segment for mono mode
  517. @@:
  518. mov ax,[di].cwSwapVids
  519. les di,lpwBuffer ;es:[di] -> buffer
  520. cmp dl,40h ;Olivetti ?
  521. je @F
  522. cmp dl,8
  523. ja save_graphics_text
  524. @@: ;Text modes or mode 6
  525. cCall SaveRegen
  526. mov di,si
  527. cCall  ClearRegen
  528. jmp SaveVidsDataExit
  529. save_graphics_text:
  530. mov bx,OFF_lpwDataCsd ;* Data in data segment
  531. mov ax, 0a000H ; Address of bit planes
  532. mov ds, ax ;ds:[si] -> video buffer
  533. test ss:[bx].fvmCurAdap, fvmMCGA
  534. jz EgaSS_NotMCGA
  535. mov si, 8000H
  536. mov cx, 2*1024
  537. EgaSS_MCGA1:
  538. xor ax,ax
  539. xchg ax, [si]
  540. inc si
  541. inc si
  542. stosw
  543. loop EgaSS_MCGA1
  544. jmp short EgaSS_SaveBitPlane2
  545. EgaSS_NotMCGA:
  546. mov cl, 0     ;bit plane 0
  547. mov bx,pvidsSaveData
  548. mov ax, ss:[bx].cwSwapVids
  549. cCall SaveBitPlane
  550. mov cl, 1 ;bit plane 1
  551. mov bx,pvidsSaveData
  552. mov ax, ss:[bx].cwSwapVids
  553. cCall SaveBitPlane
  554. EgaSS_SaveBitPlane2:
  555. mov cl, 2 ;bit plane 2
  556. mov ax, 4*1024
  557. cCall SaveBitPlane
  558. ;
  559. ; The 8k bytes starting at 16k only gets trashed on 64k Ega cards
  560. ;
  561. mov bx,OFF_lpwDataCsd ;* Data in data segment
  562. test ss:[bx].fvmCurAdap, fvm64KEGA
  563. jz EgaSs_64plus
  564. mov cl, 2
  565. mov ax, 4*1024
  566. mov si, 16*1024
  567. cCall SaveBitPlane2
  568. EgaSs_64plus:
  569. push ss ; Restore ds
  570. pop ds
  571. mov bx,OFF_lpwDataCsd ;* Data in data segment
  572. test [bx].fvmCurAdap, fvmMCGA
  573. jnz EgaSS_NotMCGA2
  574. mov di,pvidsSaveData
  575. cCall ClearBitPlanes
  576. EgaSS_NotMCGA2:
  577. SaveVidsDataExit:
  578. cEnd SaveVidsDataCsd
  579. ;***
  580. ;
  581. ;  SaveRegen - Saves the video regen buffer to global memory
  582. ;
  583. ;  Inputs: [ax] - Number of words to save
  584. ; [di] - Points to a VideoState buffer where handle to
  585. ;        global memory used to save the regen buffer is
  586. ;        store (along with the size of the saved buffer)
  587. ; [es] - Segment of video regen buffer
  588. ;
  589. ;
  590. ;  Outputs: none.
  591. ;
  592. ;  Uses: es, si
  593. ;
  594. ;****
  595. cProc SaveRegen,<NEAR>,<DI,SI>
  596. cBegin SaveRegen
  597. push ds
  598. mov ds,cx
  599. mov cx,ax
  600. xor si,si
  601. ; cCall VideoOff ; (CGA) Only affects ax and dx
  602. rep movsw
  603. pop ds
  604. ; cCall VideoOn
  605. NoRegenSave:
  606. cEnd SaveRegen
  607. cProc VideoOff,<NEAR,PUBLIC>,<ES> ;trash ax,dx
  608. cBegin VideoOff
  609. mov dx,CGA_6845_STATUS
  610. WaitVerticalRetrace:
  611. in al,dx 
  612. test al,08H
  613. jz WaitVerticalRetrace
  614. xor ax,ax
  615. mov es,ax 
  616. mov ax,es:[0465H] ; Get Current CRT mode
  617. and ax, NOT 0008H ; turn off video signal bit
  618. mov dx,CGA_6845_MODE
  619. out dx,al 
  620. cEnd VideoOff
  621. cProc VideoOn,<NEAR,PUBLIC>,<ES> ;trash ax,dx
  622. cBegin VideoOn
  623. xor ax,ax
  624. mov es,ax 
  625. mov ax,es:[0465H]  ; Get Current CRT mode
  626. or ax,0008H ; Turn on video signal bit
  627. mov dx,CGA_6845_MODE
  628. out dx,al 
  629. cEnd VideoOn
  630. ;***
  631. ;
  632. ;  ClearRegen - Clears the part of the regen buffer used by TWIN.
  633. ;
  634. ;  Inputs: [di] - Points to a VideoState buffer containing the
  635. ;        video state to be restored.
  636. ; [videoseg] - Segment of video regen buffer
  637. ;
  638. ;  Outputs: The global memory used to save the regen buffer is freed.
  639. ; i.e. don't call RestoreRegen again with the save video state.
  640. ;
  641. ;  Uses: es,di
  642. ;
  643. ;****
  644. cProc ClearRegen,<NEAR>,<di,es>
  645. cBegin ClearRegen
  646. mov ax, 0720H ; Assume text mode (clear to spaces)
  647. mov cx, 0B800h ; EGA
  648. mov bl, [di].modeVids
  649. cmp bl, 3
  650. jbe CR_1
  651. cmp bl,7
  652. jb @F
  653. cmp bl,8
  654. ja @F
  655. mov cx,0B000h
  656. jmp short CR_1
  657. @@:
  658. xor ax,ax ; Clear to Null for graphics modes.
  659. CR_1:
  660. mov es, cx ; Clear the part of the regen buffer
  661. mov cx, [di].cwSwapVids ; Save for later
  662. xor di,di ; that we used.
  663. rep stosw
  664. cEnd ClearRegen
  665. ;***
  666. ;
  667. ;  RestoreRegen - Restores the video regen buffer from pVideoState
  668. ;
  669. ;  Inputs: [di] - Points to a VideoState buffer containing the
  670. ;        video state to be restored.
  671. ; [videoseg] - Segment of video regen buffer
  672. ; cx = video segment
  673. ;
  674. ;  Outputs: NZ - if restore ok
  675. ; Z - if not restored
  676. ;
  677. ;               The global memory used to save the regen buffer is freed.
  678. ; i.e. don't call RestoreRegen again with the save video state.
  679. ;
  680. ;  Uses: es, si
  681. ;
  682. ;****
  683. cProc RestoreRegen,<NEAR>,<di>
  684. cBegin RestoreRegen
  685. mov es,cx
  686. mov cx,ax
  687. xor di,di
  688. rep movsw
  689. cEnd RestoreRegen
  690. ; SaveBitPlane - Saves a given number of words from a given bit plane.
  691. ;
  692. ; INPUT:
  693. ;    ax - Number of words to save
  694. ;    cl - Number of bit plane
  695. ;    ds - is the segment address of the bit plane.
  696. ;    es:di - where to save.
  697. ;              
  698. ; OUTPUT:
  699. ;    ES:DI - Points 1 word past the last saved word
  700. ;
  701. ; USES:
  702. ;    SI
  703. ;
  704. cProc SaveBitPlane,<NEAR>
  705. cBegin SaveBitPlane
  706. xor si,si
  707. LabelNP <SaveBitPlane2>
  708. push ax ; Save count of words
  709. cCall MapBitPlane
  710. pop cx ; Restore
  711. rep movsw
  712. cEnd SaveBitPlane
  713. ;
  714. ; RestoreBitPlane - Restores a given number of words to a given bit plane.
  715. ;
  716. ; INPUT:
  717. ;    ax - Number of words to restore
  718. ;    cl - Number of bit plane
  719. ;    es - is the segment address of the bit plane.
  720. ;    ds:si - where to restore from.
  721. ;              
  722. ; OUTPUT:
  723. ;    ds:si - Points 1 word past the last restored word
  724. ;
  725. ; USES:
  726. ;    DI
  727. ;
  728. cProc RestoreBitPlane,<NEAR>
  729. cBegin RestoreBitPlane
  730. xor di,di
  731. LabelNP <RestoreBitPlane2>
  732. push ax ; Save count of words
  733. cCall MapBitPlane
  734. pop cx ; Restore
  735. rep movsw
  736. cEnd RestoreBitPlane
  737. ;
  738. ; MapBitPlane - Maps the specified bit plane in for read/write
  739. ;
  740. ; INPUT:
  741. ;    CL - the bit plane.
  742. ;
  743. cProc MapBitPlane,<NEAR>
  744. cBegin MapBitPlane
  745. mov al, 2 ; Set Map Mask register
  746. mov ah, 1
  747. shl ah, cl
  748. cCall SetEgaSequencer ; Only trashes DX,AX
  749. mov al, 4 ; Read Map Select
  750. mov ah,cl
  751. mov dx, 3ceH ; Graphics Controler Address Port
  752. cCall OutWord
  753. cEnd MapBitPlane
  754. cProc ClearBitPlanes,<NEAR>,<DI,SI>
  755. cBegin ClearBitPlanes
  756. mov si,di ; ds:si -> saved video state
  757. mov ax, 0a000H
  758. mov es,ax
  759. mov cl, 0 ; Map in bit plane 0
  760. cCall MapBitPlane
  761. xor di,di
  762. mov cx, [si].cwSwapVids
  763. xor ax,ax
  764. rep stosw
  765. mov cl, 1 ; Map in bit plane 1
  766. cCall MapBitPlane
  767. xor di,di
  768. mov cx, [si].cwSwapVids
  769. xor ax,ax
  770. rep stosw
  771. mov cl, 2 ; Map in bit plane 2
  772. cCall MapBitPlane
  773. xor di,di
  774. mov cx, 8*1024/2
  775. xor ax,ax
  776. rep stosw
  777. push ss
  778. pop ds ; Restore ds
  779. cEnd ClearBitPlanes
  780. ; SetEgaSequencer - Sends data to the Ega sequencer
  781. ;
  782. ; INPUT:
  783. ;    AL - Sequencer register number
  784. ;         00 Reset
  785. ;         01 Clocking Mode
  786. ;         02 Map Mask
  787. ;         03 Character Map Select
  788. ;         04 Memory Mode
  789. ;    AH - Data for the register
  790. ;
  791. cProc SetEgaSequencer,<NEAR>
  792. cBegin SetEgaSequencer
  793. mov dx, 3c4H ; Ega Sequencer Address Port
  794. cCall OutWord
  795. cEnd SetEgaSequencer
  796. ;
  797. ; This is just an `out dx,ax' kludge to ensure that it works on
  798. ; AT&T 6300
  799. ;
  800. cProc OutWord,<NEAR>
  801. cBegin OutWord
  802. out dx, al
  803. jmp short OUTWORD_1 ; I/O delay
  804. OUTWORD_1:
  805. inc dx
  806. mov al,ah
  807. out dx, al
  808. cEnd OutWord
  809. ;********** RestoreVidDataCsd ********
  810. ;* entry: pvidsRestoreData = near pointer to VIDS structure
  811. ;* lpwBuffer = buffer to save data (NULL => just clear screen)
  812. ;* * restore screen data from buffer
  813. ;* exit: n/a
  814. cProc RestoreVidDataCsd, <FAR, PUBLIC, ATOMIC>, <DS, SI, DI>
  815.     parmDP pvidsRestoreData
  816.     parmD  lpwBuffer
  817. cBegin RestoreVidDataCsd
  818. mov di,pvidsRestoreData
  819. mov al, [di].modeVids
  820. cmp al, 3
  821. jb EgaRS_Text
  822. cmp al, 7
  823. je EgaRS_Text
  824. jb EgaRS_SimpleGraphics
  825. cmp al,8
  826. je EgaRs_Text
  827. cmp al,40h ;Olivetti ?
  828. je EgaRS_SimpleGraphics
  829. jmp short EgaRs_HardGraphics
  830. EgaRS_SimpleGraphics: ;mode 6
  831. push ax
  832. cCall ClearRegen
  833. pop ax
  834. EgaRS_Text: ; mode 2,3 and 7,8
  835. mov cx,0B800h
  836. cmp al, 7
  837. jb @F
  838. cmp al,8
  839. ja @F
  840. mov cx,0B000h
  841. @@:
  842. mov ax,[di].cwSwapVids
  843. lds si,lpwBuffer
  844. cCall RestoreRegen
  845. jmp RestoreVidsCsd_exit
  846. EgaRS_HardGraphics:
  847. cCall ClearRegen
  848. mov ax, 0a000H ; Address of bit planes
  849. mov es, ax
  850. lds si,lpwBuffer ;ds:[si] -> buffer
  851. mov bx,OFF_lpwDataCsd ;* Data in data segment
  852. test ss:[bx].fvmCurAdap, fvmMCGA
  853. jz EgaRs_NotMCGA
  854. mov di, 8000H
  855. mov cx, 2*1024
  856. rep movsw
  857. jmp short EgaRs_RestoreBitPlane2
  858. EgaRs_NotMCGA:
  859. mov cl, 0
  860. mov di,pvidsRestoreData
  861. mov ax, ss:[di].cwSwapVids
  862. cCall RestoreBitPlane
  863. mov cl, 1
  864. mov di,pvidsRestoreData
  865. mov ax, ss:[di].cwSwapVids
  866. cCall RestoreBitPlane
  867. EgaRs_RestoreBitPlane2:
  868. mov cl, 2
  869. mov ax, 4*1024
  870. cCall RestoreBitPlane
  871. ;
  872. ; The 8k bytes starting at 16k only gets trashed on 64k Ega cards
  873. ;
  874. mov bx,OFF_lpwDataCsd ;* Data in data segment
  875. test ss:[bx].fvmCurAdap, fvm64KEGA
  876. jz EgaRs_64plus
  877. mov cl, 2
  878. mov ax, 4*1024
  879. mov di, 16*1024
  880. cCall RestoreBitPlane2
  881. EgaRs_64Plus:
  882. mov ax,ss ; Restore ds
  883. mov ds,ax
  884. ;
  885. ; Set Map Mask register back to what BASIC expects
  886. ;
  887. mov ax, 0f02H ; Set map mask to 0fH
  888. cCall SetEgaSequencer
  889. jmp RestoreVidsCsd_exit
  890. EgaRs_HardNoRegen:
  891. cCall ClearBitPlanes
  892. RestoreVidsCsd_exit:
  893. cEnd RestoreVidDataCsd
  894. ;
  895. ; INT10Handler
  896. ;    The BIOS INT10 (Video Sevices) is hooked to mirror the palette
  897. ;    registers (so they can be restored).
  898. ;
  899. RegPtr cs_bx, cs, bx
  900. RegPtr es_bx, es, bx
  901. ;********** EnableVidsMonitorCsd ********
  902. ;* entry: fMonitorOn => monitor should be on
  903. ;* * enable/disable INT 10 monitor
  904. ;* exit: n/a
  905. cProc EnableVidsMonitorCsd, <FAR, PUBLIC, ATOMIC>,<di>
  906.     parmW  fMonitorOn
  907. cBegin EnableVidsMonitorCsd
  908. mov di,OFF_lpwDataCsd ;* Data in data segment
  909. cmp fMonitorOn,0
  910. je Unhook
  911. ; Hook int10 trap
  912. test ss:[di].fvmCurAdap, fvmEGA or fvmVGA or fvmMCGA
  913. jz @F
  914. mov [ColourPaletteYellow], 010100B  ;brown
  915. @@:
  916. mov dx,drvOffset ColourPalette    ; Default Enhanced colour
  917. test ss:[di].fvmCurAdap, fvmEGAM
  918. jz @F
  919. mov dx,drvOffset MonoPalette    ; Default Monochrome palette
  920. @@:
  921. push cs
  922. pop ds ;now ds:dx points to source
  923. cCall CopyPalette ; Initialise the user palette
  924. push ss
  925. pop ds ;restore ds
  926. mov ax, 10H
  927. mov bx, drvOffset INT10Handler
  928. cCall HookVector,<ax, cs_bx>
  929. mov cs:[lpbBIOSINT10_Offset], ax
  930. mov cs:[lpbBIOSINT10_Segment], dx
  931. jmp EVM_Exit
  932. Unhook:
  933. ; Unhook int10 trap
  934. les bx, cs:[BIOSINT10]
  935. mov ax, 10H
  936. cCall HookVector,<ax,es_bx>
  937. xor ax,ax       ; clear handler
  938. mov cs:[lpbBIOSINT10_Offset], ax
  939. mov cs:[lpbBIOSINT10_Segment], ax
  940. EVM_Exit:
  941. cEnd EnableVidsMonitorCsd
  942. ;***
  943. ;
  944. ;  HookVector(vecNum, vector)
  945. ;
  946. ;  Sets an interrupt vector and returns the old interrupt vector
  947. ;
  948. ;  Inputs: vecNum - Which vector to set
  949. ; vector - address of the new vector
  950. ;
  951. ;  Outputs: DX:AX == old interrupt vector
  952. ;
  953. ;****
  954. cProc HookVector,<NEAR,PUBLIC>,<DS>
  955. parmB vecNum
  956. parmD vector
  957. cBegin HookVector
  958. mov ah, 35H
  959. mov al, [vecNum]
  960. int 21H ; Get old vector
  961. push bx ; save for return
  962. push es ; save for return
  963. mov ah, 25H
  964. mov al, [vecNum]
  965. lds dx, [vector]
  966. int 21H ; Set new vector
  967. pop dx ; return the old vector
  968. pop ax ; return the old vector
  969. cEnd HookVector
  970. ;-------------------------------------------------------------------;
  971. INT10Handler:
  972. or ah,ah
  973. jz INT10SetMode
  974. cmp ah, 10h ;set palette regs ?
  975. je INT10SetPalette
  976. cmp ah, 0Bh
  977. je INT10SetCGABgPal
  978. INT10_Chain:
  979. jmp cs:[BIOSINT10]
  980. INT10SetMode:
  981. mov cs:[bCGABg],-1 ; bCGABg is now invalid.
  982. mov cs:[bCGAPal],-1 ; bCGAPal is now invalid.
  983. jmp short INT10_Chain
  984. public INT10SetCGABgPal ;UNDONE - Remove.
  985. INT10SetCGABgPal:
  986. or bh,bh ;Set Background colour?
  987. jnz @F ;brif no.
  988. ;* * assume BH == 1 for setting palette (if not CGA who cares anyway)
  989. mov cs:[bCGABg],bl
  990. jmp short INT10_Chain
  991. @@:
  992. mov cs:[bCGAPal],bl ;Must be setting CGA Palette
  993. jmp short INT10_Chain
  994. INT10SetPalette:
  995. push ax ; Save the regs we use
  996. or al,al
  997. jz INT10_SetIndividualPaletteReg ;ax = 1000h
  998. dec al
  999. jz INT10_SetOverscanReg ;     1001h
  1000. dec al
  1001. jz INT10_SetAllPaletteRegs ;     1002h
  1002. INT10_Exit:
  1003. pop ax
  1004. jmp short INT10_Chain
  1005. ;
  1006. ; INT10_SetIndividualPaletteReg
  1007. ;    Sets the specified palette register
  1008. ;
  1009. ; BL - Is the register number (0-15)
  1010. ; BH - Is the value
  1011. ;
  1012. INT10_SetIndividualPaletteReg:
  1013. push bx
  1014. xchg al, bh ; BH <-- 0, AL <-- value
  1015. mov cs:[EgaPaletteMirror+bx], al
  1016. pop bx
  1017. jmp short INT10_SetPaletteCommon
  1018. ;
  1019. ; INT10_SetOverscanReg
  1020. ;    Sets the overscan register
  1021. ;
  1022. ; BH - Is the value.
  1023. ;
  1024. INT10_SetOverscanReg:
  1025. mov cs:[OverScanMirror], bh
  1026. jmp short INT10_Exit
  1027. ;
  1028. ; INT10_SetAllPaletteRegs
  1029. ;    Sets all the palette registers and the overscan register.
  1030. ;
  1031. ; ES:DX - points to table of values for the 16 palette registers and
  1032. ;         the overscan register
  1033. ;
  1034. INT10_SetAllPaletteRegs:
  1035. push ds
  1036. push es
  1037. pop ds ; now ds:dx points to source
  1038. call CopyPalette
  1039. pop ds
  1040. mov cs:[bCGAPal],-1 ; bCGAPal is now invalid.
  1041. INT10_SetPaletteCommon:
  1042. mov cs:[bCGABg],-1 ; bCGABg is now invalid.
  1043. jmp short INT10_Exit
  1044. ;
  1045. ; Copy DS:DX to CS:EgaPaletteMirror
  1046. ;
  1047. cProc CopyPalette,<NEAR>,<SI,DI,CX,ES>
  1048. cBegin CopyPalette
  1049. push cs
  1050. pop es
  1051. mov si, dx
  1052. mov di, DrvOffset EgaPaletteMirror
  1053. mov cx, 17
  1054. rep movsb
  1055. cEnd CopyPalette
  1056. ifndef KANJI
  1057. ;***** UNDONE - HACK HACK HACK HACK HACK HACK HACK HACK HACK HACK
  1058. ;***** UNDONE This piece of code is called directly by QB 4.5
  1059. ;***** UNDONE It must not be called by QBJ
  1060. ;***** UNDONE Remove this as soon as QB 4.5 ships.
  1061. cProc SetBlinkBit,<FAR,PUBLIC>
  1062. parmB fOn
  1063. cBegin
  1064. cmp [fOn],0
  1065. je @F
  1066. cCall EnableBlinkBit
  1067. jmp short SBB_Exit
  1068. @@:
  1069. cCall DiddleBlinkBit
  1070. SBB_Exit:
  1071. cEnd
  1072. endif ; !KANJI