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

操作系统开发

开发平台:

Visual C++

  1. page 56,132
  2. name EGASYS
  3. title EGA Screen Device Driver
  4. subttl Header
  5. IFDEF OS2
  6. .286 ; Oh goody, can use 80286 instructions
  7. ELSE ; NOT OS2
  8. .8086 ; Have to support everything
  9. ENDIF ; NOT OS2
  10. ;
  11. ; I N C L U D E S
  12. ;
  13. include ega.inc
  14. ;
  15. ; C O D E
  16. ;
  17. IFDEF OS2 ; Start of OS/2 functions
  18. ;
  19. ; DoSave - Save state of EGA
  20. ;
  21. ; ENTRY
  22. ; ds = cs
  23. ;
  24. ; EXIT
  25. ; ax = 0, operation complete
  26. ;
  27. ; DESTROYS
  28. ; bx, si
  29. ;
  30. assume cs:CODE, ds:CODE, es:nothing, ss:nothing
  31. DoSave proc near
  32. mov ax,cs
  33. mov es,ax
  34. assume es:CODE
  35. mov ax,0F901h ; Select new context subfunction
  36. jmp short DoCommon
  37. DoSave endp
  38. ;
  39. ; DoRestore - Restore state of EGA
  40. ;
  41. ; ENTRY
  42. ; ds = cs
  43. ;
  44. ; EXIT
  45. ; ax = 0, operation complete
  46. ;
  47. ; DESTROYS
  48. ; bx, si, ds
  49. ;
  50. assume cs:CODE, ds:CODE, es:nothing, ss:nothing
  51. DoRestore proc near
  52. mov ax,cs
  53. mov es,ax
  54. assume es:CODE
  55. mov ax,0F902h ; Select new context subfunction
  56. DoCommon:
  57. mov bx,offset ContextCopy
  58. int 10h ; Restore from ContextCopy
  59. if2 ; Pass 2 of the assembler
  60. .errnz ($ - StatusComplete) ; Drop into StatusComplete
  61. endif ; Pass 2 of the assembler
  62. DoRestore endp
  63. ENDIF ; OS2
  64. ;
  65. ; StatusComplete - Set completion status
  66. ;
  67. ; ENTRY
  68. ; none
  69. ;
  70. ; EXIT
  71. ; ax = 0, request completed
  72. ;
  73. ; DESTROYS
  74. ; None
  75. ;
  76. assume cs:CODE, ds:nothing, es:nothing, ss:nothing
  77. StatusComplete proc near
  78. sub ax,ax ; AX = 0, complete
  79. ret
  80. StatusComplete endp
  81. ENDIF ; SYS
  82. subttl Miscellaneous Code
  83. page
  84. ;
  85. ; UpdateCRTCMap - get the latest values for certain readable CRTC regs
  86. ;
  87. ; Called by all routines that return register values to the user,
  88. ; this function updates the current CRTC shadow map with the latest
  89. ; values of the readable CRTC StartAddress (00Ch, 00Dh) and
  90. ; CursorPosition (00Eh, 00Fh).
  91. ;
  92. ; Of the numerous EGA regs that are write only, the CRTC contains a
  93. ; handful of readable regs.  Normally, for readable regs like Input
  94. ; Status 1, EGA.SYS requires the user keep track of its value.  But if
  95. ; the goal is for the user of EGA.SYS to be able to rely 100% on the
  96. ; shadow maps, we must properly update readables that we do return.
  97. ; Note that the CRTC lightpen regs do not fall into this category,
  98. ; since we shadow writes to that index, which is really the vertical
  99. ; sync start/stop regs.
  100. ;
  101. ; ENTRY
  102. ; none
  103. ; EXIT
  104. ; none
  105. ; DESTROYS
  106. ; AX, SI (if VGA)
  107. ;
  108. assume cs:CODE, ds:CODE, es:nothing, ss:nothing
  109. UpdateCRTCMap proc near
  110. push dx ; Save environment
  111. mov dx,[PortTable][0].prPortAddr
  112. mov ax,0C0Dh
  113. pushf ; Save interrupt flag state
  114. CLI ; Disable interrupts
  115. out dx,al ; Address CRTCStart high
  116. IOdelay
  117. inc dx
  118. in al,dx ; Get CRTCStart high
  119. IOdelay
  120. dec dx
  121. xchg al,ah
  122. out dx,al ; Address CRTCStart low
  123. IOdelay
  124. inc dx
  125. in al,dx ; Get CRTCStart low
  126. IOdelay
  127. mov word ptr [CRTCRegs][00Ch],ax ; Stash low:high
  128. dec dx
  129. mov ax,00E0Fh
  130. out dx,al ; Address CRTCCursor pos high
  131. IOdelay
  132. inc dx
  133. in al,dx ; Get CRTCCursor pos high
  134. IOdelay
  135. dec dx
  136. xchg al,ah
  137. out dx,al ; Address CRTCCursor pos low
  138. IOdelay
  139. inc dx
  140. in al,dx ; Get CRTCCursor pos low
  141. popf ; Restore interrupt flag state
  142. mov word ptr [CRTCRegs][00Eh],ax ; Stash low:high
  143. cmp [fVga],false ; On VGA card?
  144. je UpdateCRTCMapDone ; No - skip
  145. xor si,si ; Don't change default save maps
  146. push bx ; Save environment
  147. push cx ; Save environment
  148. call ReadVGARegs
  149. mov [fPalette],cl ; fPalette = FALSE
  150. pop cx ; Restore environment
  151. pop bx ; Restore environment
  152. UpdateCRTCMapDone:
  153. pop dx ; Restore environment
  154. ret
  155. UpdateCRTCMap endp
  156. assume cs:CODE, ds:CODE, es:nothing, ss:nothing
  157. ReadVGARegs proc near
  158. ;
  159. ; Save Miscellaneous Output Register
  160. ;
  161. MOV DX,MiscOutputRegR ; Get Miscellaneous Output Register
  162. IN AL,DX ; Get current state of the register
  163. IOdelay
  164. MOV [MiscOutReg],AL ; value
  165. or si,si ; Change default save map?
  166. jz @F ; No - skip
  167. MOV [DefMiscOutReg],AL ; Save initial
  168. ;
  169. ; Save Feature Control Register
  170. ;
  171. @@:
  172. MOV DL,FeatureCtrlReg AND 0FFH ; Get Feature Control Register
  173. IN AL,DX ; Get current state of the register
  174. MOV [FeatureReg],AL ; value
  175. or si,si ; Change default save map?
  176. jz @F ; No - skip
  177. MOV [DefFeatureReg],AL ; Save initial
  178. ;
  179. ; Save Sequencer Registers
  180. ;
  181. @@:
  182. MOV CX,NumSeqRegs ; Initialize 5H registers
  183. MOV DL,(EGA_BASE + SEQ_ADDR) AND 0FFH ; Get Sequencer Register
  184. XOR BX,BX ; Code to select reset reg
  185. pushf ; Save interrupt flag state
  186. SaveSequencerRegs:
  187. MOV AL,BL ; Get index
  188. CLI ; Disable interrupts
  189. OUT DX,AL ; Send index to the Address Register
  190. IOdelay
  191. INC DX ; Choose read only register
  192. IN AL,DX ; Get current state of the register
  193. STI ; Enable interrupts
  194. DEC DX ; Choose index register
  195. MOV [SeqRegs][BX],AL ; value
  196. or si,si ; Change default save map?
  197. jz @F ; No - skip
  198. MOV [DefSeqRegs][BX],AL ; Save initial
  199. @@:
  200. INC BX ; Move to the next index register
  201. LOOP SaveSequencerRegs ; Loop back and initialize another reg
  202. ;
  203. ; Save Graphics Controller Registers
  204. ;
  205. MOV BX,CX ; Code to select enable set/reset reg
  206. MOV CL,NumGraphicsRegs ; Initialize 9H registers
  207. MOV DL,(EGA_BASE + GRAF_CONT) AND 0FFH
  208. ; Get Graphics Control Addr Reg
  209. SaveGraphicsContRegs:
  210. MOV AL,BL ; Get index
  211. CLI ; Disable interrupts
  212. OUT DX,AL ; Send index to the Address Register
  213. IOdelay
  214. INC DX ; Choose read only register
  215. IN AL,DX ; Get current state of the register
  216. STI ; Enable interrupts
  217. DEC DX ; Choose index register
  218. MOV [GraphicsRegs][BX],AL ; value
  219. or si,si ; Change default save map?
  220. jz @F ; No - skip
  221. MOV [DefGraphicsRegs][BX],AL ; Save initial
  222. @@:
  223. INC BX ; Move to the next index register
  224. LOOP SaveGraphicsContRegs ; Loop back and initialize another reg
  225. ;
  226. ; Save Attribute Controller Registers
  227. ;
  228. MOV BX,CX ; Code to select Palette
  229. ; Register and keep video disabled
  230. MOV CL,NumAttrRegs ; Initialize 15H registers
  231. SaveAttributeContRegs:
  232. MOV DL,BYTE PTR [PortTable][5 * SIZE PortRec].PRPortAddr
  233. CLI ; Disable interrupts
  234. IN AL,DX ; Initialize flip-flop to select address
  235. MOV AL,BL ; Get index
  236. CMP AL,10H ; Past palette registers?
  237. JB PaletteCheckDone ; No - skip
  238. OR AL,PaletteAddressSource ; Code to enable video
  239. jmp short GetAttrReg
  240. ;
  241. ; We are stuck.  In order to correctly read the Palette registers
  242. ; on a VGA, the Palette address source bit (bit 5 of the Attribute
  243. ; Address Register) needs to be 0, but making this 0 will disable
  244. ; video.  Then after reading the Palette registers, we need to
  245. ; re-enable video.  But this happens so often that the screen
  246. ; flashes.  So, we can only read these registers at init time.
  247. ; Only loss of functionality is if the palette registers get
  248. ; out of sync with the shadow maps after init time.
  249. ;
  250. PaletteCheckDone:
  251. cmp [fPalette],ch ; Did user request the palette regs?
  252. jne GetAttrReg ; Yes - skip
  253. or si,si ; Init?
  254. jz NextAttrReg ; No - skip
  255. GetAttrReg:
  256. MOV DL,AttCtrlAddrReg AND 0FFH ; Get Attribute Control Address Reg
  257. OUT DX,AL ; Send index to the Address Register
  258. IOdelay
  259. INC DX ; Choose read only register
  260. IN AL,DX ; Get current state of the register
  261. MOV [AttrRegs][BX],AL ; value
  262. or si,si ; Change default save map?
  263. jz NextAttrReg ; No - skip
  264. MOV [DefAttrRegs][BX],AL ; Save initial
  265. NextAttrReg:
  266. STI ; Enable interrupts
  267. INC BX ; Move to the next index register
  268. LOOP SaveAttributeContRegs ; Loop back and initialize another reg
  269. ;
  270. ; Save CRT Controller Registers
  271. ;
  272. MOV BX,CX ; Code to select horizontal total reg
  273. MOV CL,NumCRTCRegs ; Initialize 19H registers
  274. MOV DL,BYTE PTR [PortTable][5 * SIZE PortRec].PRPortAddr
  275. CLI ; Disable interrupts
  276. IN AL,DX ; So that we get back to index again
  277. IOdelay
  278. SUB DL,6 ; Get CRT Controller Address Reg
  279. SaveCRTContRegs:
  280. CLI ; Disable interrupts
  281. MOV AL,BL ; Get index
  282. OUT DX,AL ; Send index to the Address Register
  283. IOdelay
  284. INC DX ; Choose read only register
  285. IN AL,DX ; Get current state of the register
  286. STI ; Enable interrupts
  287. DEC DX ; Choose index register
  288. MOV [CRTCRegs][BX],AL ; value
  289. or si,si ; Change default save map?
  290. jz @F ; No - skip
  291. MOV [DefCRTCRegs][BX],AL ; Save initial
  292. @@:
  293. INC BX ; Move to the next index register
  294. LOOP SaveCRTContRegs ; Loop back and initialize another reg
  295. popf ; Restore interrupt flag state
  296. ret
  297. ReadVGARegs endp
  298. page
  299. ;
  300. ; BrstDet - determine number of scan lines for raster
  301. ;
  302. ; BrstDet, similar to the IBM function by the same name, determines
  303. ; whether the current raster should be 200 or 350 scanlines based on
  304. ; the switch settings on the rear of the EGA card.  In a nutshell,
  305. ; switch settings 0011 or 1001 indicate 350 lines, otherwise 200 lines.
  306. ;
  307. ; EXIT
  308. ; cy =  200 scanlines
  309. ; nc =  350 scanlines
  310. ; DESTROYS
  311. ; None
  312. ;
  313. assume cs:CODE, ds:nothing, es:nothing, ss:nothing
  314. BrstDet  proc near
  315. push ax
  316. mov al,[biosinfo3] ; Get feature and switch info
  317. and al,00001111b ; Mask for switches
  318. cmp al,00001001b ; Most common config
  319. je @F
  320. cmp al,00000011b ; Less common
  321. je @F
  322. stc ; Else set carry
  323. @@:
  324. pop ax
  325. ret
  326. BrstDet  endp
  327. page
  328. ;
  329. ; MakeBase - find proper video params for given mode
  330. ;
  331. ; MakeBase, similar to the IBM function by the same name, will return
  332. ; a pointer to the correct table of video parameters to use when
  333. ; initializing the EGA for a given mode. The root of the list of tables
  334. ; is derived from the ParmPtr in the SavePtr table.
  335. ;
  336. ; ENTRY
  337. ; ah =  video mode
  338. ; ds =  0
  339. ; EXIT
  340. ; es:si -> base of correct parameter table
  341. ; DESTROYS
  342. ; ax, flags
  343. ;
  344. assume cs:CODE, ds:INTVEC, es:nothing, ss:nothing
  345. MakeBase proc near
  346. les si,[lpSavePtr] ; Load up SavePtr
  347. assume es:nothing
  348. les si,es:[si] ; Load up ParmPtr
  349. assume es:nothing
  350. test [Info],01100000b ; If 64K video memory,
  351. jz mb64K ;  skip special graphics tests
  352. add si,440h ; Bump to alt 640x350x1
  353. cmp ah,0Fh  ; If this is what we want,
  354. je mbX ;  we are done
  355. add si,40h ; Bump to alt 640x350x4
  356. cmp ah,10h  ; If this is what we want,
  357. je mbX ;  we are done
  358. ;
  359. ; I assume that the special VGA modes 11h, 12h, and 13h are
  360. ; contiguous and lie after the last EGA table in memory, but
  361. ; I don't know this for sure.
  362. ;
  363. add si,140h ; Bump for VGA modes 11h, 12h, 13h
  364. cmp ah,11h ; Is it a VGA mode 11h?
  365. je mbx ; Yes - skip
  366. add si,40h ; Bump for VGA mode 12h
  367. cmp ah,12h ; Is it a VGA mode 12h?
  368. je mbx ; Yes - skip
  369. add si,40h ; Bump for VGA mode 13h
  370. cmp ah,13h ; Is it a VGA mode 13h?
  371. je mbx ; Yes - skip
  372. sub si,640h ; Nope, not special graphics
  373. mb64K:
  374. cmp ah,3h  ; If not alpha,
  375. ja @F ;  skip special alpha tests
  376. call BrstDet  ; If not enhanced config,
  377. jc @F ;  no adjustment needed
  378. add si,4C0h ; Bump to enhanced alpha parms
  379. @@:
  380. xor al,al ; Now use mode as final index
  381. ifdef OS2
  382. shr ax,2
  383. else ; NOT OS2
  384. shr ax,1 ; Funky math does the job
  385. shr ax,1
  386. endif ; NOT OS2
  387. add si,ax
  388. mbX:
  389. ret ; ES:SI -> correct table
  390. MakeBase endp
  391. ;-----------------------------------------------------------------------
  392. ; HandleIODelay -- Delay for doing close together I/O for hardware
  393. ; to catch it's breath
  394. ;
  395. ; Entry: None
  396. ;
  397. ; Exit:  None
  398. ;
  399. ; Alters: None
  400. ;
  401. ; Note: This was implemented because processors (e.g. 80486) keep
  402. ; getting faster and smarter (prefetch and caching)
  403. ; and ruin our old jmp $+2 scheme, so this is a better
  404. ; (i.e. more processor independent) method.
  405. ;
  406. ;-----------------------------------------------------------------------
  407. assume cs:CODE, ds:nothing, es:nothing, ss:nothing
  408. HandleIODelay proc near
  409. push ax ; Save environment
  410. in al,43h ; Delay by reading status register
  411. in al,43h ; Delay by reading status register
  412. pop ax ; Restore environment
  413. ret
  414. HandleIODelay endp
  415. page
  416. ;
  417. ; ChangeRegs - reinitialize all shadow maps and EGA state info
  418. ;
  419. ; ENTRY
  420. ; ah =  video mode
  421. ; al =  low byte of CRTC io address
  422. ; Used in EGAChooseMonoColorDisplay macro
  423. ; EXIT
  424. ; ds =  cs
  425. ; DESTROYS
  426. ; ax, si
  427. ;
  428. assume cs:CODE, ds:INTVEC, es:nothing, ss:nothing
  429. ChangeRegs proc near
  430. push cx ; Save environment
  431. push di ; Save environment
  432. PUSH BX ; Save environment
  433. ifdef OS2
  434. mov cx,cs ; DS = Code segment
  435. mov ds,cx ; Two instructions needed
  436. assume ds:CODE
  437. EGAChooseMonoColorDisplay ; Validate CRTC address
  438. endif ; OS2
  439. CMP [fVga],FALSE ; Do we have a VGA Card?
  440. JE HandleEGA ; No - skip
  441. PUSH DX ; Save environment
  442. ifndef OS2
  443. mov cx,cs ; DS = Code segment
  444. mov ds,cx ; Two instructions needed
  445. assume ds:CODE
  446. VGAChooseMonoColorDisplay ; Validate CRTC address
  447. endif ; NOT OS2
  448. mov si,1 ; Change default save maps
  449. call ReadVGARegs
  450. POP DX ; Restore environment
  451. JMP SHORT FinishChangeRegs
  452. HandleEGA:
  453. ifdef OS2
  454. PUSH ES ; Save environment
  455. xor si,si ; DS = Segment 0
  456. mov ds,si ; Two instructions needed
  457. assume ds:INTVEC
  458. else ; NOT OS2
  459. assume ds:INTVEC
  460. PUSH ES ; Save environment
  461. EGAChooseMonoColorDisplay ; Validate CRTC address
  462. endif ; NOT OS2
  463. call MakeBase ; ES:SI -> correct table on exit
  464. assume es:nothing
  465. mov ax,es
  466. mov ds,ax ; DS = ES
  467. assume ds:nothing
  468. mov ax,cs
  469. mov es,ax ; ES = CS
  470. assume es:CODE
  471. add si,5 ; Bump past BIOS misc junk
  472. mov di,offset StartShadowMaps
  473. mov al,3 ; Always stash 3 in seq reset reg
  474. stosb
  475. mov cx,(VGAPatch - 2) / 2 ; Move data up to extra VGA reg
  476. if (VGAPatch - 2) AND 1
  477. movsb ; Odd count adjust
  478. endif ; (VGAPatch - 2) AND 1
  479. rep movsw
  480. inc di ; Bump past VGA reg
  481. mov cl,NumGraphicsRegs / 2 ; Finish up grph ctrlr regs
  482. if NumGraphicsRegs AND 1
  483. movsb ; Odd count adjust
  484. endif ; NumGraphicsRegs AND 1
  485. rep movsw
  486. sub si,(SizeShadowMaps - 2) ; Drop back to beginning
  487. stosb ; Always stash 3 in seq reset reg
  488. mov cl,(VGAPatch - 2) / 2 ; Move data up extra VGA reg
  489. if (VGAPatch - 2) AND 1
  490. movsb ; Odd count adjust
  491. endif ; (VGAPatch - 2) AND 1
  492. rep movsw
  493. inc di ; Bump past VGA reg
  494. mov cl,NumGraphicsRegs / 2 ; Finish up grph ctrlr regs
  495. if NumGraphicsRegs AND 1
  496. movsb ; Odd count adjust
  497. endif ; NumGraphicsRegs AND 1
  498. rep movsw
  499. mov ax,cs
  500. mov ds,ax
  501. assume ds:CODE  ; DS = CS
  502. mov [PortTable][3 * SIZE PortRec].prNumRegs,NumAttrRegs - 1
  503. ; Adjust size for EGA
  504. xor ax,ax ; Get a zero value
  505. mov [Gr1PosReg],al ; AX = 0, init Gr1PosRegs
  506. mov [DefGr1PosReg],al
  507. inc ax
  508. mov [Gr2PosReg],al ; AX = 1, init Gr2PosRegs
  509. mov [DefGr2PosReg],al
  510. POP ES ; Restore environment
  511. assume es:nothing
  512. FinishChangeRegs:
  513. assume ds:CODE
  514. xor ax,ax
  515. mov di,ax ; Now clear all dirty flags
  516. mov cl,NumPtrData
  517. mov bx,offset PortTable ; Start at beginning
  518. @@:
  519. mov code:[bx][di].prModFlag,al
  520. add di,SIZE PortRec
  521. loop @B
  522. mov [SingleRegMod],al
  523. POP BX ; Restore environment
  524. pop di ; Restore environment
  525. pop cx ; Restore environment
  526. ret
  527. ChangeRegs endp
  528. subttl SetMode
  529. page
  530. ;
  531. ; SetMode - shadow int 10h SetMode functionality (subfunction 00h)
  532. ;
  533. ; This code is executed when a BIOS setmode call is made.  It must
  534. ; predict which mode table the BIOS will use, so the BIOS decision
  535. ; logic is duplicated here.
  536. ;
  537. ; ENTRY
  538. ; SaveAX =  original ax on entry with mode in al
  539. ; ds =  cs
  540. ; EXIT
  541. ; none
  542. ; DESTROYS
  543. ; ax, si, ds, flags
  544. ;
  545. assume cs:CODE, ds:CODE, es:nothing, ss:nothing
  546. SetMode  proc near
  547. xor ax,ax
  548. mov ds,ax
  549. assume ds:INTVEC
  550. mov al,byte ptr [EquipFlag] ; Get planar switch setting
  551. mov ah,byte ptr [SaveAX] ; AH = mode
  552. and ah,01111111b ; Reset noclear bit
  553. test [Info],00000010b ; If EGA has color monitor
  554. jz smNoMonochrome ;  skip mono tests
  555. test al,030h  ; If default video is color,
  556. jnz smNoChange ;  get out now
  557. mov al,0B4h  ; IO addr = 3Bx
  558. cmp ah,00Fh  ; If mono hi-res graphics,
  559. je @F ;  do it
  560. mov ah,007h  ; Else force mono alpha
  561. jmp short @F ;  do it
  562. smNoMonochrome:
  563. test al,030h  ; If default video mono,
  564. jz smNoChange ;  get out now
  565. mov al,0D4h  ; IO addr = 3Dx
  566. @@:
  567. push ax ; Save video mode
  568. call ChangeRegs ; Initialize shadow maps
  569. assume ds:CODE
  570. pop ax ; Recover mode
  571. push bx ; We need it
  572. mov bx,0FF01h ; Assume mono 8x14 font
  573. cmp [fVga],FALSE ; Do we have a VGA Card?
  574. je @F ; No - skip
  575. mov bl,4 ; Assume mono 8x16 font
  576. @@:
  577. cmp ah,7 ; If mode is mono alpha,
  578. je smDoFonts ;  do it
  579. mov bl,0FFh  ; Assume no fonts (graphics)
  580. cmp ah,3 ; If mode is graphics,
  581. ja smDoFonts ;  do it
  582. mov bl,001h  ; Assume 8x14 font
  583. cmp [fVga],FALSE ; Do we have a VGA Card?
  584. je @F ; No - skip
  585. mov bl,004h  ; Assume 8x16 font
  586. @@:
  587. call BrstDet  ; If 350 scanlines,
  588. jnc smDoFonts ;  do it
  589. mov bl,2 ; Else show 8x8 font
  590. smDoFonts:
  591. mov word ptr [FontBank][0],bx ; Stash bl:bh
  592. mov word ptr [FontBank][2],0FFFFh ; Stash 0FFh:0FFh
  593. pop bx
  594. smNoChange:
  595. assume ds:nothing
  596. ret
  597. SetMode  endp
  598. if CallTableNeeded
  599. subttl SetCursorType
  600. page
  601. ;
  602. ; SetCursorType - shadow int 10h SetCursorType functionality (subfunction 01h)
  603. ;
  604. ; ENTRY
  605. ; ch =  bits 0-4: start scanline for cursor
  606. ;    bits 5-6: visibility attributes
  607. ; cl =  bits 0-4: stop scanline for cursor
  608. ; ds =  cs
  609. ; EXIT
  610. ; none
  611. ; DESTROYS
  612. ; ax, flags
  613. ;
  614. assume cs:CODE, ds:CODE, es:nothing, ss:nothing
  615. SetCursorType proc near
  616. push bx ; Save environment
  617. push ds ; Save environment
  618. xor ax,ax
  619. mov ds,ax
  620. assume ds:INTVEC
  621. mov bx,cx ; BX = cursor type
  622. test [Info],00001000b ; If EGA not active,
  623. jnz sctStash ;  just stash the raw values
  624. mov al,bh ; AL = raw start
  625. and al,01100000b ; Extract visibility attributes
  626. cmp al,00100000b ; If cursor-off flag not set,
  627. jne @F ;  continue
  628. mov bx,01E00h ; Else emulate cursor off
  629. jmp short sctStash
  630. @@:
  631. test [Info],00000001b ; If not emulating cursor,
  632. jnz sctStash ;  just stash the raw values
  633. cmp [CrtMode],3 ; If not alpha mode,
  634. ja sctNoBump2 ;  avoid special alpha tests
  635. call BrstDet  ; If 200 lines,
  636. jc sctNoBump2 ;  avoid 350 line heuristics
  637. mov al,005h  ; Magic number
  638. cmp bh,al ; If start < 5,
  639. jb @F ;  leave it alone
  640. add bh,al ; Else bump it up
  641. @@:
  642. cmp bl,al ; If stop < 5,
  643. jb sctNoBump2 ;  leave it alone
  644. add bl,al ; Else bump it up
  645. sctNoBump2:
  646. inc bl ; Bump stop
  647. or bh,bh ; If start = 0,
  648. jz @F ;  check for wraparound
  649. cmp bl,byte ptr [Points] ; If stop < char cell height,
  650. jb @F ;  proceed to final test
  651. xor bl,bl ; Else stop = 0
  652. @@:
  653. mov ax,bx ; Get copy into ax
  654. sub al,ah
  655. cmp al,16 ; If stop - start != magic
  656. jne sctStash ;  continue
  657. inc bl ; Else bump stop
  658. sctStash:
  659. pop ds ; Restore environment
  660. assume ds:CODE
  661. xchg bh,bl ; Flip start/stop
  662. mov word ptr [CRTCRegs][10],bx ; Stash computed value
  663. pop bx ; Restore environment
  664. if2 ; Pass 2 of the assembler
  665. .ERRNZ ($ - Ignore) ; Drop into Ignore
  666. endif ; Pass 2 of the assembler
  667. SetCursorType endp
  668. ;
  669. ; Ignore - Unsupported device driver calls enter here
  670. ;
  671. ; ENTRY
  672. ; none
  673. ; EXIT
  674. ; none
  675. ; DESTROYS
  676. ; none
  677. ; NOTE:
  678. ; We are using the RET instruction from SetMode above
  679. ;
  680. assume cs:CODE, ds:nothing, es:nothing, ss:nothing
  681. Ignore proc near ; Enter here just to use the ret
  682. ret
  683. Ignore endp
  684. subttl ScrollUpDown
  685. page
  686. ;
  687. ; ScrollUpDown - shadow int 10h Scroll functionality (subfunctions 06h, 07h)
  688. ;
  689. ; ENTRY
  690. ; al  = current video mode
  691. ; ah  = static copy of ega info byte
  692. ;
  693. ; EXIT
  694. ; none
  695. ; DESTROYS
  696. ; ax, flags
  697. ;
  698. assume cs:CODE, ds:CODE, es:nothing, ss:nothing
  699. ScrollUpDown proc near
  700. push bp
  701. mov bp,sp ; Watch out for stack!
  702. push bx
  703. mov bh,byte ptr [bp].userAX ; BH = num lines to scroll
  704. or bh,bh ; If bh = 0,
  705. jz sudSetSeq ;  only change sequencer
  706. mov bl,dh ; BL = lower row of window
  707. sub bl,ch ; BL = lower row - upper row
  708. inc bx ; Make 1-based
  709. cmp bl,bh ; If size window = num lines,
  710. je sudSetSeq ;  treat as blank whole window
  711. mov bl,010h  ; Assume odd/even addressing
  712. cmp al,00Fh  ; If mode < 0Fh,
  713. jb @F ;  assumption is correct
  714. test ah,01100000b ; If EGA memory is 64K,
  715. jz @F ;  assumption is correct
  716. xor bl,bl ; Else use enhanced default
  717. @@:
  718. mov [GraphicsRegs][005h],bl ; Stash the default
  719. sudSetSeq:
  720. mov [SeqRegs][002h],00Fh ; Stash another default
  721. pop bx
  722. pop bp
  723. ret
  724. ScrollUpDown endp
  725. subttl ReadChar
  726. page
  727. ;
  728. ; ReadChar - shadow int 10h ReadChar functionality (subfunction 08h)
  729. ;
  730. ; ENTRY
  731. ; al  = current video mode
  732. ; ah  = static copy of ega info byte
  733. ;
  734. ; EXIT
  735. ; none
  736. ; DESTROYS
  737. ; ax, flags
  738. ;
  739. assume cs:CODE, ds:CODE, es:nothing, ss:nothing
  740. ReadChar proc near
  741. cmp al,00Fh  ; If mode <  0Fh,
  742. mov al,0 ; (reuse al and assume default)
  743. jb @F ;  no more processing needed
  744. test ah,0110000b ; If EGA memory >64K
  745. jnz @F ;  no more processing needed
  746. mov al,010h  ; Else use crippled default
  747. @@:
  748. mov [GraphicsRegs][005h],al ; Put al in r/w mode reg
  749. ret
  750. ReadChar endp
  751. subttl WriteChar
  752. page
  753. ;
  754. ; WriteChar - shadow int 10h WriteChar functionality (subfunctions 09h, 0Ah)
  755. ;
  756. ; ENTRY
  757. ; al  = current video mode
  758. ; ah  = static copy of ega info byte
  759. ;
  760. ; EXIT
  761. ; none
  762. ; DESTROYS
  763. ; ax, flags
  764. ;
  765. assume cs:CODE, ds:CODE, es:nothing, ss:nothing
  766. WriteChar proc near
  767. mov [GraphicsRegs][003h],0 ; Put 000h in data rotate reg
  768. mov [SeqRegs][002h],00Fh ; Put 00Fh in map mask reg
  769. scpGetOut: ; Mind if we use your ret?  Thanks.
  770. assume ds:nothing
  771. ret
  772. WriteChar endp
  773. subttl SetCGAPalette
  774. page
  775. ;
  776. ; SetCGAPalette - shadow int 10h SetCGAPalette functionality (subfunction 0Bh)
  777. ;
  778. ; SetCGAPalette is a quirky function, even on a CGA system.  Note the
  779. ; following points carefully:
  780. ;
  781. ; 1.  When using bh = 0 to set background/overscan, the call will fall
  782. ;     through to the bh = 1 code because bit 4 is the palette intensity
  783. ;     which must be combined with the current palette selection. Thus
  784. ;     when making a set background call, you are also implicitly making
  785. ;     a set palette intensity call (subject to constraints that follow).
  786. ;
  787. ; 2.  In alpha modes, you may only set the overscan color if you are in
  788. ;     a CGA compatible (200 lines, 15KHz) sweep mode.  Attempting to do
  789. ;     this in 350 line alpha will cause display problems and therefore is
  790. ;     a nop in this function.  It is also meaningless to set the palette
  791. ;     and the background color in either alpha sweep mode, and thus is a
  792. ;     nop.
  793. ;
  794. ; ENTRY
  795. ; bh =  0: set background/overscan color
  796. ; bl =  bits 0-3: irgb color for background/overscan
  797. ;    bit   4: palette intensity
  798. ;    bits 5-7: unused
  799. ; bh =  1: set foreground palette
  800. ; bl =  0: set palette 0 (green/red/brown)
  801. ;    1: set palette 1 (cyan/magenta/white)
  802. ; ds =  cs
  803. ; EXIT
  804. ; none
  805. ; DESTROYS
  806. ; ax, si, ds, flags
  807. ;
  808. assume cs:CODE, ds:CODE, es:nothing, ss:nothing
  809. SetCgaPalette proc near
  810. xor ax,ax
  811. mov ds,ax
  812. assume ds:INTVEC
  813. cmp byte ptr [Addr6845],0B4h; If mono active,
  814. je scpGetOut ;  get out
  815. test [Info],00000010b ; If EGA has no color monitor,
  816. jnz scpGetOut ;  get out
  817. mov ah,[CrtMode] ; AH = video mode
  818. mov al,[CrtPalette]  ; AL = CGA palette byte
  819. mov si,cs ; DS = Code segment
  820. mov ds,si ; Two instructions needed
  821. assume ds:CODE
  822. push bx
  823. or bh,bh ; If bh != 0,
  824. jnz scpPal ;  go set CGA palette colors
  825. and al,11100000b ; Clear old backgnd, pal intense
  826. and bl,00011111b ; Isolate new backgnd, pal int
  827. or al,bl ; AL = new palette byte
  828. mov bh,bl ; Get a copy into bh
  829. shl bl,1 ; Shift intensity into position
  830. and bx,0000011100010000b ; And isolate it
  831. ; Isolate rgb in bh
  832. or bh,bl ; BH = EGA compatible background
  833. cmp ah,3 ; If in graphics mode,
  834. ja @F ;  do background and overscan
  835. call BrstDet  ; If 200 lines,
  836. jc scpOverScan ;  do overscan only
  837. jmp short scpX ; Else nothing left to do
  838. @@:
  839. mov [AttrRegs][000h],bh ; Stash background
  840. scpOverScan:
  841. mov [AttrRegs][011h],bh ; Stash overscan
  842. mov bl,al ; Recover new palette byte
  843. and bl,00100000b ; Isolate palette bit
  844. ifdef OS2
  845. rol bl,3 ; And get into bit 0
  846. else ; NOT OS2
  847. rol bl,1 ; And get into bit 0
  848. rol bl,1
  849. rol bl,1
  850. endif ; NOT OS2
  851. scpPal:
  852. cmp ah,3 ; If in alpha mode,
  853. jbe scpX ;  don't bother with palettes
  854. and bl,00000001b ; Only allow palettes 0 and 1
  855. and al,00010000b ; Isolate palette intensity bit
  856. or al,bl ; Or intensity into palette
  857. or al,2 ; Green (2) or cyan (3)
  858. mov [AttrRegs][001h],al ; Stash color 1
  859. inc ax ; Red (4) or magenta (5)
  860. inc ax ; "
  861. mov [AttrRegs][002h],al ; Stash color 2
  862. inc ax ; Brown/yellow (6) or white (7)
  863. inc ax ; "
  864. mov [AttrRegs][003h],al ; Stash color 3
  865. scpX:
  866. pop bx
  867. ret
  868. SetCgaPalette endp
  869. subttl WriteDot
  870. page
  871. ;
  872. ; WriteDot - shadow int 10h WriteDot functionality (subfunction 0Ch)
  873. ;
  874. ; ENTRY
  875. ; al  = current video mode
  876. ; ah  = static copy of ega info byte
  877. ;
  878. ; EXIT
  879. ; none
  880. ; DESTROYS
  881. ; ax, flags
  882. ;
  883. assume cs:CODE, ds:CODE, es:nothing, ss:nothing
  884. WriteDot proc near
  885. mov al,0FFh
  886. mov [GraphicsRegs][003h],ah ; Put 000h in data rotate reg
  887. mov [GraphicsRegs][008h],al ; Put 0FFh in bit mask reg
  888. mov [SeqRegs][002h],al ; Put 0FFh in map mask reg
  889. ret
  890. WriteDot endp
  891. subttl ReadDot
  892. page
  893. ;
  894. ; ReadDot - shadow int 10h ReadDot functionality (subfunction 0Dh)
  895. ;
  896. ; ENTRY
  897. ; al  = current video mode
  898. ; ah  = static copy of ega info byte
  899. ;
  900. ; EXIT
  901. ; none
  902. ; DESTROYS
  903. ; ax, flags
  904. ;
  905. assume cs:CODE, ds:CODE, es:nothing, ss:nothing
  906. ReadDot  proc near
  907. push bx
  908. mov bl,003h  ; Assume >64K or modes 0Dh/0Eh
  909. cmp al,00Fh  ; If mode < 0Fh,
  910. jb @F ;  assumption is correct
  911. test ah,01100000b ; If EGA memory > 64K,
  912. jnz @F ;  assumption is correct
  913. dec bx ; Else use crippled default
  914. @@:
  915. mov [GraphicsRegs][004h],bl ; Put in read map reg
  916. pop bx
  917. ret
  918. ReadDot  endp
  919. subttl SetEGAPalette
  920. page
  921. ;
  922. ; SetEGAPalette - shadow int 10h SetEGAPalette functionality (subfunction 10h)
  923. ;
  924. ; ENTRY
  925. ; (Source - Direct quote from IBM Enhanced Graphics Adapter manual)
  926. ;   SubFunctions:
  927. ; (AL) = 0               Set individual palette register
  928. ;  BL = Palette register to be set
  929. ;  BH = Value to set
  930. ;
  931. ; AL = 1                Set overscan register
  932. ; BH = Value to set
  933. ;
  934. ; AL = 2                Set all palette register and overscan
  935. ; ES:BX points to a 17 byte table
  936. ; Bytes 0 - 15 are the palette values, respectively
  937. ; Byte 16 is the overscan value
  938. ;
  939. ; AL = 3                Toggle intensity/blinking bit
  940. ; BL - 0        Enable intensity
  941. ; BL - 1        Enable blinking
  942. ;
  943. ; EXIT
  944. ; none
  945. ; DESTROYS
  946. ; ax, si, ds, flags
  947. ;
  948. assume cs:CODE, ds:CODE, es:nothing, ss:nothing
  949. SetEgaPalette proc near
  950. push bp
  951. mov bp,sp
  952. xor ax,ax
  953. mov ds,ax
  954. assume ds:INTVEC
  955. mov al,0D4h  ; Assume color
  956. test [Info],00000010b ; If EGA has color monitor,
  957. jz @F ;  go check Addr6845
  958. mov al,0B4h  ; Else try mono
  959. @@:
  960. cmp byte ptr [Addr6845],al ; If no agreement with Addr6845,
  961. jne sepX0 ;  get out
  962. push bx
  963. mov al,byte ptr [bp].userAX ; AL = original subfunction
  964. xor ah,ah ; Allows dec ax instruction
  965. or al,al ; If al != 0 (set one reg),
  966. jnz @F ;  try next subfunction
  967. cmp bl,NumAttrRegs - 1 ; If user gave us bogus index,
  968. ja sepX1 ;  get out or we'll lunch
  969. mov al,bh ; Copy data
  970. xor bh,bh ; Zero bh for the index
  971. mov [AttrRegs][bx],al ; Stash it
  972. jmp short sepX1
  973. @@:
  974. dec ax ; If al != 1 (set overscan reg),
  975. jnz @F ;  try next subfunction
  976. mov [AttrRegs][011h],bh ; Stash overscan reg
  977. jmp short sepX1
  978. @@:
  979. push es
  980. dec ax ; If al != 2 (set all regs),
  981. jnz @F ;  try next subfunction
  982. push cx
  983. push di
  984. mov ax,es
  985. mov ds,ax ; DS = ES
  986. assume ds:nothing
  987. mov ax,cs
  988. mov es,ax ; ES = CS
  989. assume es:CODE
  990. mov si,dx ; DS:SI -> src table
  991. mov di,offset AttrRegs ; ES:DI -> AttrReg array
  992. mov cx,8 ; Do first 16 bytes
  993. rep movsw
  994. inc di ; Bump past mode control
  995. movsb ; Stash overscan
  996. pop di
  997. pop cx
  998. jmp short sepX
  999. @@:
  1000. assume ds:INTVEC, es:nothing
  1001. dec ax ; If al != 3 (toggle blink),
  1002. jnz sepX ;  get out
  1003. ;
  1004. ; Legal values of bl (0 or 1) should be used to act NOT on the current
  1005. ; setting of the mode reg, but on the default value pointed to by the parm
  1006. ; ptr in the save ptr table.  Illegal values for bl cause this reg to be
  1007. ; restored to the default value given by the parm ptr. See IBM EGA BIOS
  1008. ; pg.  148
  1009. ;
  1010. mov ah,[CrtMode] ; AH = video mode
  1011. call MakeBase
  1012. assume es:nothing
  1013. mov al,es:[si][51] ; Get default attr mode value
  1014. or bl,bl ; If bl != 0 (reset bit)
  1015. jnz @F ;  try next subfunction
  1016. and al,11110111b ; Reset blink bit
  1017. jmp short sepStoreBit
  1018. @@:
  1019. dec bl ; If bl still not 0,
  1020. jnz sepStoreBit ;  give'em a default
  1021. or al,00001000b ; Set blink bit
  1022. sepStoreBit:
  1023. mov [AttrRegs][010h],al
  1024. sepX:
  1025. assume ds:nothing, es:nothing
  1026. pop es
  1027. assume es:nothing
  1028. sepX1:
  1029. pop bx
  1030. sepX0:
  1031. assume ds:INTVEC, es:nothing
  1032. pop bp
  1033. ret
  1034. SetEgaPalette endp
  1035. subttl DownloadFont
  1036. page
  1037. ;
  1038. ; DownloadFont - shadow int 10h DownloadFont functionality (subfunction 11h)
  1039. ;
  1040. ; ENTRY
  1041. ; (Source - Direct quote from IBM Enhanced Graphics Adapter manual)
  1042. ;   SubFunctions:
  1043. ; Note: This call will initiate a mode set, completely
  1044. ; resetting the video environment but maintaining
  1045. ; the regen buffer.
  1046. ;
  1047. ; AL = 00   User alpha load
  1048. ; ES:BP - Pointer to user table
  1049. ; CX    - Count to store
  1050. ; DX    - Character offset into table
  1051. ; BL    - Block to load
  1052. ; BH    - Number of bytes per character
  1053. ; AL = 01   ROM monochrome set
  1054. ; BL    - Block to load
  1055. ; AL = 02   ROM 8x8 double dot
  1056. ; BL    - Block to load
  1057. ; AL = 03   Set block specifier
  1058. ; BL    - Char gen block specifier
  1059. ; D3-D2  Attr bit 3 one,   char gen 0-3
  1060. ; D1-D0  Attr bit 3 zero,  char gen 0-3
  1061. ; Note:  When using AL = 03 a function call
  1062. ; AX = 1000H
  1063. ; BX = 0712H
  1064. ; is recommended to set the color planes
  1065. ; resulting in 512 characters and eight
  1066. ; consistant colors
  1067. ;
  1068. ; Note : The following interface (AL=1X) is similar in function
  1069. ; to (AL=0X) except that :
  1070. ; - Page zero must be active
  1071. ; - Points (bytes/char) will be recalculated
  1072. ; - Rows will be calculated from the following:
  1073. ; INT((200 or 350) / points) - 1
  1074. ; - CRT_LEN will be calculated from :
  1075. ; (rows + 1) * CRT_COLS * 2
  1076. ; - The CRTC will be reprogrammed as follows :
  1077. ; R09H = points - 1       Max scan line
  1078. ; R09H done only in mode 7
  1079. ; R0AH = points  2        Cursor start
  1080. ; R0BH = 0                Cursor end
  1081. ; R12H =                  Vert disp end
  1082. ; ((rows + 1) * points) - 1
  1083. ; R14H = points           Underline loc
  1084. ;
  1085. ; The above register calculations must be close to the
  1086. ; original table values or undetermined results will
  1087. ; occur.
  1088. ;
  1089. ; Note : The following interface is designed to be
  1090. ; called only immediately after a mode set has
  1091. ; been issued.  Failure to adhere to this practice
  1092. ; may cause undetermined results.
  1093. ;
  1094. ; AL = 10   User alpha load
  1095. ; ES:BP - Pointer to user table
  1096. ; CX    - Count to store
  1097. ; DX    - Character offset into table
  1098. ; BL    - Block to load
  1099. ; BH    - Number of bytes per character
  1100. ; AL = 11   ROM monochrome set
  1101. ; BL    - Block to load
  1102. ; AL = 12   ROM 8x8 double dot
  1103. ; BL    - Block to load
  1104. ;
  1105. ; Note : The following interface is designed to be
  1106. ; called only immediately after a mode set has
  1107. ; been issued.  Failure to adhere to this practice
  1108. ; may cause undetermined results.
  1109. ;
  1110. ; AL = 20   User graphics chars   INT 01FH (8x8)
  1111. ; ES:BP - Pointer to user table
  1112. ; AL = 21   User graphics chars
  1113. ; ES:BP - Pointer to user table
  1114. ; CX    - Points (bytes per character)
  1115. ; BL    - Row specifier
  1116. ;
  1117. ; BL = 0  User
  1118. ; DL - Rows
  1119. ; BL = 1  14 (0EH)
  1120. ; BL = 2  25 (19H)
  1121. ; BL = 3  43 (28H)
  1122. ;
  1123. ; AL = 22   ROM 8 x 14 set
  1124. ; BL    - Row specifier
  1125. ; AL = 23   ROM 8 x 8 double dot
  1126. ; BL    - Row specifier
  1127. ;
  1128. ; AL = 30   Information
  1129. ; CX    - Points
  1130. ; DL    - Rows
  1131. ; BH    - 0       Return current INT 1FH Ptr
  1132. ; ES:BP - Ptr to table
  1133. ; BH    - 1       Return current INT 44H Ptr
  1134. ; ES:BP - Ptr to table
  1135. ; BH    - 2       Return ROM 8 x 14 Ptr
  1136. ; ES:BP - Ptr to table
  1137. ; BH    - 3       Return ROM double dot Ptr
  1138. ; ES:BP - Ptr to table
  1139. ; BH    - 4       Return ROM double dot Ptr (TOP)
  1140. ; ES:BP - Ptr to table
  1141. ; BH    - 5       Return ROM alpha alternate 9 x 14
  1142. ; ES:BP - Ptr to table
  1143. ;
  1144. ; EXIT
  1145. ; None
  1146. ;
  1147. ; DESTROYS
  1148. ; AX, SI
  1149. ;
  1150. assume cs:CODE, ds:CODE, es:nothing, ss:nothing
  1151. DownloadFont proc near
  1152. push bp ; Save environment
  1153. mov bp,sp
  1154. mov al,byte ptr [bp].userAX ; Recover original subfunction
  1155. cmp al,20h ; If not one of the alpha loads,
  1156. jae dfX0 ;  get out
  1157. cmp al,3 ; If only changing banks,
  1158. je dfSetBlock ;  go do it
  1159. and al,00001111b ; Else extract sub-subfunction
  1160. cmp al,3 ; If not 0, 1, or 2,
  1161. jae dfX0 ;   get out
  1162. mov si,bx ; Get row specifier
  1163. and si,000000000000011b ; Extract font bank
  1164. mov byte ptr [FontBank][si],al ; Stash font id in table
  1165. xor ax,ax
  1166. mov ds,ax ; DS = 0
  1167. assume ds:INTVEC
  1168. mov ah,[CrtMode] ; Get current video mode
  1169. push bx ; Save environment
  1170. mov bl,ah ; Save a copy for later
  1171. mov al,byte ptr [Addr6845] ; Get low byte CRTC io address
  1172. call ChangeRegs ; Re-initialize all regs
  1173. assume ds:CODE
  1174. mov al,byte ptr [bp].userAX ; Get original subfunction
  1175. sub al,010h  ; Check 1x series
  1176. js dfX ; If not 1x series, we're done
  1177. jz dfSetUnderLine ; If al was 10h, bh set by user
  1178. mov bh,14 ; Assume 8x14 font
  1179. cmp [fVga],FALSE ; Do we have a VGA Card?
  1180. je @F ; No - skip
  1181. mov bh,16 ; Assume 8x16 font
  1182. @@:
  1183. dec al ; If al was 11h,
  1184. jz dfSetUnderLine ;  go check underline
  1185. mov bh,008h  ; Assume 8x8 font
  1186. dec al ; If al was not 12h,
  1187. jnz dfX ;  then invalid code
  1188. dfSetUnderLine:
  1189. cmp bl,007h  ; If not mono alpha,
  1190. jne @F ;  don't set underline
  1191. mov [CRTCRegs][014h],bh ; Set underline position
  1192. @@:
  1193. dec bh ; Make 0-based
  1194. mov [CRTCRegs][009h],bh ; Set last char line
  1195. mov ax,350 ; Assume 350 total scan lines
  1196. cmp bl,003h  ; If not color alpha,
  1197. ja @F ;  skip special alpha tests
  1198. call BrstDet  ; If 350 lines,
  1199. jnc @F ;  our assumption was good
  1200. mov ax,200 ; Else show 200 lines
  1201. @@:
  1202. inc bh ; Make char lines 1-based
  1203. div bh
  1204. mul bh
  1205. dec ax ; Make total lines 0-based
  1206. mov [CRTCRegs][012h],al ; Stash new vertical total
  1207. dfX:
  1208. pop bx ; Restore environment
  1209. dfX0:
  1210. pop bp ; Restore environment
  1211. ret
  1212. dfSetBlock:
  1213. mov [SeqRegs][003h],bl ; Stash new font bank selection
  1214. pop bp ; Restore environment
  1215. ret
  1216. DownloadFont endp
  1217. endif ; CallTableNeeded
  1218. subttl Read Register
  1219. page
  1220. ;
  1221. ; ReadReg - Read a single EGA register from shadow maps
  1222. ;
  1223. ; ENTRY
  1224. ; urAH =  0F0h
  1225. ; bx =  register index if register id is indexed chip
  1226. ;    ignored if register id is single reg
  1227. ; dx =  register id
  1228. ; EXIT
  1229. ; bl =  current register data
  1230. ; DESTROYS
  1231. ; ax, si, flags
  1232. ;
  1233. assume cs:CODE, ds:CODE, es:nothing, ss:nothing
  1234. ReadReg proc near
  1235. cmp dl,18h ; Is it Attr reg?
  1236. jne @F ; No - skip
  1237. cmp bl,10h ; Is it palette reg?
  1238. jae @F ; No - skip
  1239. mov [fPalette],dl ; fPalette = TRUE
  1240. @@:
  1241. call UpdateCRTCMap ; Get latest readable regs
  1242. mov si,dx ; Reg id indexes PortTable
  1243. mov si,[PortTable][si].prCurrTable
  1244. cmp dl,NumPtrData * SIZE PortRec ; If not a chip,
  1245. jae @F ;  no need for bx
  1246. mov bl,CODE:[si][bx] ; Read indexed chip data
  1247. ret
  1248. @@:
  1249. mov bl,CODE:[si]  ; Read a single reg
  1250. ret
  1251. ReadReg endp
  1252. subttl Write Register
  1253. page
  1254. ;
  1255. ; WriteReg - write to a single EGA register and update shadow maps
  1256. ;
  1257. ; ENTRY
  1258. ; urAH =  0F1h
  1259. ; bl =  register index if register id is indexed chip
  1260. ;    data to be written if register id is single reg
  1261. ; bh =  data to be written if register id is indexed chip
  1262. ; =  ignored if register id is single reg
  1263. ; dx =  register id
  1264. ; EXIT
  1265. ; none
  1266. ; DESTROYS
  1267. ; ax, bh, dx, si, flags
  1268. ;
  1269. assume cs:CODE, ds:CODE, es:nothing, ss:nothing
  1270. WriteReg proc near
  1271. mov ax,bx
  1272. mov si,dx ; Reg id indexes PortTable
  1273. cli ; Disable interrupts
  1274. or [PortTable][si].prModFlag,3
  1275. cmp dl,NumPtrData * SIZE PortRec ; If not a chip,
  1276. mov dx,[PortTable][si].prPortAddr
  1277. mov si,[PortTable][si].prCurrTable
  1278. jae WRegNotPtr ; Just write it directly
  1279. xor bh,bh ; Zero bh for indexing
  1280. mov CODE:[si][bx],ah ; Update shadow map
  1281. cmp dl,AttCtrlAddrReg AND 0FFh ; If not attribute chip,
  1282. jne @F ; Skip special processing
  1283. OutWordAttr ax,NoInts ; Write index/data to AttrAddr
  1284. sti ; Restore interrupt state
  1285. ret
  1286. @@:
  1287. OutWord NoInts,DestroyAX,DestroyDX
  1288. sti ; Restore interrupt state
  1289. ret
  1290. WRegNotPtr:
  1291. mov CODE:[si],al  ; Update shadow map
  1292. or [SingleRegMod],3 ; Show a single reg is dirty
  1293. out dx,al ; And finally send out data
  1294. sti ; Restore interrupt state
  1295. ret
  1296. WriteReg endp
  1297. subttl Read Register Range
  1298. page
  1299. ;
  1300. ; ReadRange - read a range of EGA registers from shadow maps
  1301. ;
  1302. ; ENTRY
  1303. ; urAH =  0F2h
  1304. ; dx =  register id (must be an indexed chip!)
  1305. ; cl =  # of registers to read (must be > 1 !)
  1306. ; ch =  starting register index
  1307. ; es:bx -> buffer to put reg data
  1308. ; EXIT
  1309. ; none
  1310. ; DESTROYS
  1311. ; ax, cx, si, flags
  1312. ;
  1313. assume cs:CODE, ds:CODE, es:nothing, ss:nothing
  1314. ReadRange proc near
  1315. cmp dl,18h ; Is it Attr reg?
  1316. jne @F ; No - skip
  1317. cmp ch,10h ; Is it palette reg?
  1318. jae @F ; No - skip
  1319. mov [fPalette],dl ; fPalette = TRUE
  1320. @@:
  1321. call UpdateCRTCMap ; Get latest readable regs
  1322. push di
  1323. mov di,bx ; DI = ptr to user table
  1324. mov si,dx ; Reg id indexes PortTable
  1325. mov si,[PortTable][si].prCurrTable
  1326. xor ax,ax ; AX = 0
  1327. xchg al,ch ; AX = reg offset, ch = 0
  1328. add si,ax ; Adjust si for offset
  1329. shr cx,1 ; CX now has reg count
  1330. rep movsw ; Blast shadow map to user table
  1331. rcl cx,1
  1332. rep movsb
  1333. pop di
  1334. ret
  1335. ReadRange endp
  1336. subttl Write Register Range
  1337. page
  1338. ;
  1339. ; WriteRange - write to a range of EGA registers and update shadow maps
  1340. ;
  1341. ; ENTRY
  1342. ; urAH =  0F3h
  1343. ; dx =  register id (must be an indexed chip!)
  1344. ; cl =  # of registers to write (must be > 1 !)
  1345. ; ch =  starting register index
  1346. ; es:bx -> buffer to get reg data
  1347. ; EXIT
  1348. ; none
  1349. ; DESTROYS
  1350. ; ax, bx, dx, si, flags
  1351. ;
  1352. assume cs:CODE, ds:CODE, es:nothing, ss:nothing
  1353. WriteRange proc near
  1354. push di
  1355. push es
  1356. mov si,bx ; SI = ptr to user table
  1357. mov di,dx ; Reg id indexes PortTable
  1358. mov bx,offset PortTable ; Start at beginning
  1359. cli ; Disable interrupts
  1360. or code:[bx][di].prModFlag,3
  1361. mov dx,code:[bx][di].prPortAddr
  1362. mov di,code:[bx][di].prCurrTable ; DI = ptr to shadow map
  1363. mov ax,es ; XCHG ES,DS
  1364. mov bx,ds
  1365. mov es,bx
  1366. assume es:CODE
  1367. mov ds,ax
  1368. assume ds:nothing
  1369. xor ax,ax ; AX = 0
  1370. xchg al,ch ; AX = reg offset, ch = 0
  1371. add di,ax ; Adjust di for offset
  1372. push cx ; CX now has reg count
  1373. shr cx,1
  1374. rep movsw ; Blast table to shadow map
  1375. rcl cx,1
  1376. rep movsb
  1377. mov ds,bx ; DS = CS
  1378. assume ds:CODE
  1379. pop cx ; Restore reg count
  1380. sub di,cx ; Rewind di
  1381. cmp dl,AttCtrlAddrReg AND 0FFh ; If not attribute chip,
  1382. jne WRangeNotAttr ; Skip special processing
  1383. @@:
  1384. mov ah,CODE:[di]  ; AH = reg data, al = reg index
  1385. IODelay
  1386. OutWordAttr ,NoInts ; Write index/data to AttrAddr
  1387. inc di
  1388. inc ax ; INC reg index (al)
  1389. loop @B
  1390. jmp short @F ; All done for this chip
  1391. WRangeNotAttr:
  1392. mov ah,CODE:[di]  ; AH = reg data, al = reg index
  1393. IODelay
  1394. OutWord NoInts
  1395. inc di
  1396. inc ax ; INC reg index (al)
  1397. loop WRangeNotAttr
  1398. @@:
  1399. pop es
  1400. assume es:nothing
  1401. pop di
  1402. sti ; Restore interrupt state
  1403. ret
  1404. WriteRange endp
  1405. subttl Read Register Set
  1406. page
  1407. ;
  1408. ; ReadSet - read a set of EGA registers from shadow maps
  1409. ;
  1410. ; ENTRY
  1411. ; urAH =  0F4h
  1412. ; cx =  # of registers to read (must be > 1 !)
  1413. ; es:bx -> buffer of contiguous SetRec
  1414. ;    structures, one for each register
  1415. ;    to be read
  1416. ; EXIT
  1417. ; none
  1418. ; DESTROYS
  1419. ; ax, cx, si, flags
  1420. ;
  1421. assume cs:CODE, ds:CODE, es:nothing, ss:nothing
  1422. ReadSet  proc near
  1423. push cx ; Save count
  1424. push bx ; Save buffer address
  1425. LookForPalette:
  1426. cmp byte ptr es:[bx][0],18h ; Is it Attr reg?
  1427. jne @F ; No - skip
  1428. cmp byte ptr es:[bx][2],10h ; Is it palette reg?
  1429. jae @F ; No - skip
  1430. mov [fPalette],cl ; fPalette = TRUE
  1431. jmp short LookForPaletteDone
  1432. @@:
  1433. add bx,4 ; Next entry
  1434. loop LookForPalette ; Continue through the list
  1435. LookForPaletteDone:
  1436. pop bx ; Restore buffer address
  1437. pop cx ; Restore count
  1438. call UpdateCRTCMap ; Get latest readable regs
  1439. push di
  1440. mov di,bx
  1441. @@:
  1442. mov si,es:[di].srPortNum ; SI =  reg id
  1443. mov si,[PortTable][si].prCurrTable ; SI -> our shadow map
  1444. mov al,es:[di].srPtr ; AL =  reg index
  1445. cbw
  1446. add si,ax ; Adjust si for index
  1447. add di,srData ; DI -> stash location
  1448. movsb
  1449. loop @B
  1450. pop di
  1451. ret
  1452. ReadSet  endp
  1453. subttl Write Register Set
  1454. page
  1455. ;
  1456. ; WriteSet - write to a set of EGA registers and update shadow maps
  1457. ;
  1458. ; ENTRY
  1459. ; urAH =  0F5h
  1460. ; cx =  # of registers to write (must be > 1 !)
  1461. ; es:bx -> buffer of contiguous SetRec
  1462. ;    structures, one for each register
  1463. ;    to be written
  1464. ; EXIT
  1465. ; none
  1466. ; DESTROYS
  1467. ; ax, cx, si, flags
  1468. ;
  1469. assume cs:CODE, ds:CODE, es:nothing, ss:nothing
  1470. WriteSet proc near
  1471. push di
  1472. push dx
  1473. mov di,bx
  1474. cli ; Disable interrupts
  1475. WSetNextEntry:
  1476. mov si,es:[di].srPortNum ; SI =  reg id
  1477. or [PortTable][si].prModFlag,3
  1478. mov dx,[PortTable][si].prPortAddr
  1479. mov si,[PortTable][si].prCurrTable ; SI -> our shadow map
  1480. mov al,es:[di].srPtr ; AL =  reg index
  1481. cbw
  1482. add si,ax ; Adjust si for index
  1483. mov ah,es:[di].srData ; AH = reg data
  1484. mov CODE:[si],ah  ; Update shadow map
  1485. cmp dl,AttCtrlAddrReg AND 0FFh ; If not attribute chip,
  1486. jne WSetNotAttr ; Skip special processing
  1487. OutWordAttr ax,NoInts ; Write index/data to AttrAddr
  1488. jmp short @F ; All done for this register
  1489. WSetNotAttr:
  1490. OutWord NoInts,DestroyAX,DestroyDX
  1491. @@:
  1492. add di,SIZE SetRec ; Bump to next record
  1493. loop WSetNextEntry
  1494. pop dx
  1495. pop di
  1496. sti ; Restore interrupt state
  1497. DDefExit: ; Mind if we use your ret?  Thanks.
  1498. ret
  1499. WriteSet endp
  1500. subttl Define Default Shadow Maps
  1501. page
  1502. ;
  1503. ; DefineDefault - load up default shadow maps from user buffer
  1504. ;
  1505. ; ENTRY
  1506. ; urAH =  0F7h
  1507. ; cx =  'TH' if user wants to program VGA specific color select
  1508. ; register.  This was added version 2.07.12.
  1509. ; dx =  register id
  1510. ;    If high bit of dx set, an internal RevertDefault will
  1511. ;    occur after the default shadow maps have been updated.
  1512. ;
  1513. ; es:bx -> buffer of default values for specified register id.
  1514. ;    If register id is a chip, all values must be present.
  1515. ; EXIT
  1516. ; none
  1517. ; DESTROYS
  1518. ; ax, bx, si, flags
  1519. ;
  1520. assume cs:CODE, ds:CODE, es:nothing, ss:nothing
  1521. DefineDefault proc near
  1522. push di
  1523. push cx
  1524. mov di,dx ; Reg id indexes PortTable
  1525. and di,7FFFh ; Strip "revert" flag
  1526. mov si,cx ; SI = Possible special VGA code
  1527. xor ch,ch ; No high byte
  1528. mov cl,[PortTable][di].prNumRegs
  1529. cmp [fVGA],ch ; Are we on a VGA?
  1530. je @F ; No - skip
  1531. cmp di,18h ; Is it the attribute controller regs?
  1532. jne @F ; No - skip
  1533. cmp si,'TH' ; Is it code for VGA color select?
  1534. je @F ; Yes - skip
  1535. dec cx ; Don't deal with color select register
  1536. @@:
  1537. mov si,bx ; SI -> user buffer
  1538. mov al,1
  1539. mov bx,offset PortTable ; Start at beginning
  1540. or code:[bx][di].prModFlag,al
  1541. or [SingleRegMod],al
  1542. mov di,code:[bx][di].prDefTable ; DI -> default shadow map
  1543. mov ax,es ; XCHG ES,DS
  1544. mov bx,ds
  1545. mov es,bx
  1546. assume es:CODE
  1547. mov ds,ax
  1548. assume ds:nothing
  1549. shr cx,1
  1550. rep movsw ; Blast to default shadow map
  1551. rcl cx,1
  1552. rep movsb
  1553. mov es,ax ; Recover old es
  1554. assume es:NOTHING
  1555. mov ds,bx ; DS = CS
  1556. assume ds:CODE
  1557. pop cx
  1558. pop di
  1559. or dh,dh ; If not "revert" flag,
  1560. jns DDefExit ;  just leave
  1561. ; Else make defaults active
  1562. if2 ; Pass 2 of the assembler
  1563. .errnz ($ - RevertDefault) ; Drop into RevertDefault
  1564. endif ; Pass 2 of the assembler
  1565. DefineDefault endp
  1566. subttl Revert to Default Shadow Maps
  1567. page
  1568. ;
  1569. ; RevertDefault - blast default shadow maps to EGA and update shadow maps
  1570. ;
  1571. ; ENTRY
  1572. ; urAH =  0F6h
  1573. ; EXIT
  1574. ; none
  1575. ; DESTROYS
  1576. ; ax, si, flags
  1577. ;
  1578. assume cs:CODE, ds:CODE, es:nothing, ss:nothing
  1579. RevertDefault proc near
  1580. push di ; Save environment
  1581. push es ; Save environment
  1582. push dx ; Save environment
  1583. push cx ; Save environment
  1584. push bx ; Save environment
  1585. mov ax,ds
  1586. mov es,ax ; ES = DS = CS
  1587. assume es:CODE
  1588. mov bx,offset PortTable ; Start at beginning
  1589. xor cx,cx
  1590. RDefNextPtrData:
  1591. test CODE:[bx].prModFlag,1 ; If dirty flag = 0,
  1592. jz ToRDefNotModified ;  done with this map
  1593. mov CODE:[bx].prModFlag,2 ; Else clear dirty flag
  1594. mov cl,CODE:[bx].prNumRegs
  1595. mov di,CODE:[bx].prCurrTable
  1596. mov si,CODE:[bx].prDefTable
  1597. mov dl,cl ; Save count
  1598. shr cx,1
  1599. rep movsw ; Blast default map to current map
  1600. rcl cx,1
  1601. rep movsb
  1602. mov al,ch ; CH still 0 from above
  1603. mov cl,dl ; Restore count
  1604. sub si,cx ; Rewind si
  1605. mov dx,CODE:[bx].prPortAddr
  1606. cmp dl,AttCtrlAddrReg AND 0FFh ; If not attribute chip,
  1607. jne RDefNotAttr ; Skip special processing
  1608. pushf ; Save interrupt flag state
  1609. WaitRetrace ; Also disables interrupts
  1610. mov al,ch ; Restore index (0)
  1611. mov dl,AttCtrlAddrReg AND 0FFh ; Restore dx to AttrAddr
  1612. @@:
  1613. mov ah,CODE:[si]  ; Get data
  1614. OutWordAttr ,NoInts ; Write index/data to AttrAddr
  1615. IODelay
  1616. inc si
  1617. inc ax
  1618. loop @B
  1619. mov al,PaletteAddressSource ; Since dx still has AttrAddr,
  1620. out dx,al ;  Enable video now
  1621. IOdelay
  1622. InitFlipFlop NoSaveAX ; Be sure to reset the flip-flop
  1623. popf ; Restore interrupt flag state
  1624. ToRDefNotModified:
  1625. jmp short RDefNotModified ; All done for Attr chip
  1626. RDefNotAttr:
  1627. mov ah,CODE:[si]
  1628. cmp dl,(EGA_BASE + SEQ_ADDR) AND 0FFh ; SAS 06/09/86
  1629. jne RDefNotAttr1 ; SAS 06/09/86
  1630. cmp al,SeqClMReg ; SAS 06/09/86
  1631. je @F ; SAS 06/09/86
  1632. RDefNotAttr1:
  1633. cmp dl,(EGA_BASE + GRAF_CONT) AND 0FFh
  1634. jne RDefOut
  1635. cmp al,GRAF_MISC_REG
  1636. je @F
  1637. RDefOut:
  1638. OutWord
  1639. @@:
  1640. inc si
  1641. inc ax
  1642. loop RDefNotAttr
  1643. RDefNotModified:
  1644. add bx,SIZE PortRec
  1645. cmp bx,offset PortTable + (NumPtrData * SIZE PortRec)
  1646. jnb @F
  1647. jmp RDefNextPtrData
  1648. @@:
  1649. InitFlipFlop NoSaveAX ; Reset FF and get FeatAddr!
  1650. IOdelay
  1651. test [SingleRegMod],1 ; If singles dirty flag = 0,
  1652. jz @F ;  we're done
  1653. mov [SingleRegMod],2 ; Clear singles dirty flag
  1654. mov al,[DefFeatureReg]
  1655. mov [FeatureReg],al  ; Since dx still has FeatAddr,
  1656. out dx,al ;  program it now
  1657. IOdelay
  1658. mov dl,MiscAddr AND 0FFh ; Deal with MiscOut reg
  1659. mov al,[DefMiscOutReg]
  1660. mov [MiscOutReg],al
  1661. out dx,al
  1662. IOdelay
  1663. cmp [fVga],CL ; If VGA is present,
  1664. jne @F ;  skip GR1&2 processing
  1665. mov dl,Gr1PosAddr AND 0FFh
  1666. mov al,[DefGR1PosReg]
  1667. mov [GR1PosReg],al
  1668. out dx,al
  1669. IOdelay
  1670. mov dl,Gr2PosAddr AND 0FFh
  1671. mov al,[DefGR2PosReg]
  1672. mov [GR2PosReg],al
  1673. out dx,al
  1674. @@:
  1675. pop bx ; Restore environment
  1676. pop cx ; Restore environment
  1677. pop dx ; Restore environment
  1678. pop es ; Restore environment
  1679. assume es:nothing
  1680. pop di ; Restore environment
  1681. ret
  1682. RevertDefault endp
  1683. subttl Get Default Shadow Maps
  1684. page
  1685. ;
  1686. ; GetDefault - dump default shadow maps to user buffer
  1687. ;
  1688. ; ENTRY
  1689. ; urAH =  0F8h
  1690. ; dx =  register id
  1691. ; es:bx -> buffer to receive default values
  1692. ;    If register id is a chip, table must have room for all
  1693. ;    regs in chip.
  1694. ; EXIT
  1695. ; none
  1696. ; DESTROYS
  1697. ; ax, si, flags
  1698. ;
  1699. assume cs:CODE, ds:CODE, es:nothing, ss:nothing
  1700. GetDefault proc near
  1701. push di
  1702. push cx
  1703. mov di,bx ; DI -> user buffer
  1704. mov si,dx ; Reg id indexes PortTable
  1705. xor ch,ch
  1706. mov cl,[PortTable][si].prNumRegs
  1707. mov si,[PortTable][si].prDefTable ; SI -> default shadow map
  1708. shr cx,1
  1709. rep movsw ; Blast default map to user buffer
  1710. rcl cx,1
  1711. rep movsb
  1712. pop cx
  1713. pop di
  1714. ret
  1715. GetDefault endp
  1716. subttl EGA Context Functions
  1717. page
  1718. ;
  1719. ; ContextInfo - Save/Restore full EGA.SYS context information
  1720. ;
  1721. ; This entrypoint was added for TSR's and environment managers like
  1722. ; Windows and Presentation Manager that must be able to save/restore the
  1723. ; EGA.SYS context information as well as the state of the EGA hardware.
  1724. ; Without this functionality, Windows is unable to properly preserve the
  1725. ; state of variables internal to EGA.SYS such as the dirty flags and/or
  1726. ; the state of the EGA data latches.  It also provides software
  1727. ; developers a more rapid mechanism for context switching the EGA, as it
  1728. ; dispenses with the need to make numerous Read/WriteRange and
  1729. ; Read/WriteSet calls.
  1730. ;
  1731. ; Secondly, there are two types of context information that developers
  1732. ; must implicitly handle:  1) the screen data, and 2) the font data (for
  1733. ; alpha modes).  Since shadowing the EGA registers alone does not
  1734. ; provide sufficient information for efficiently handling downloaded
  1735. ; font data, a call has been added to retrieve the current status of
  1736. ; each alpha font bank programmed through int 010h, subfunction 011h.
  1737. ;
  1738. ; ENTRY
  1739. ; urAH =  0F9h
  1740. ; urAL =  000h  GetContextSize
  1741. ; =  001h  SaveContext
  1742. ; =  002h  RestoreContext
  1743. ; =  003h  GetFontInfo
  1744. ; =  004h  GetInBiosFlag
  1745. ;
  1746. ; other regs per function being called
  1747. ; EXIT
  1748. ; per function being called
  1749. ; DESTROYS
  1750. ; ax, si for this particular procedure,
  1751. ; otherwise,  per function being called
  1752. ;
  1753. assume cs:CODE, ds:CODE, es:nothing, ss:nothing
  1754. ContextInfo proc near
  1755. push bp ; Save environment
  1756. mov bp,sp ; Set up stack addressing
  1757. mov al,byte ptr [bp].userAX ; Get old ax from stack
  1758. pop bp ; Restore environment
  1759. cmp al,MaxContextCall ; If not one of our subfunctions,
  1760. ja ciX ;  get out now
  1761. xor ah,ah ; Reset ah for dispatch
  1762. shl ax,1 ; *2 for word addresses
  1763. mov si,ax
  1764. jmp [ContextTable][si] ; MUST jmp for stack integrity
  1765. ContextInfo endp
  1766. ;
  1767. ; GetContextSize - return size in bytes needed to save EGA.SYS context
  1768. ;
  1769. ; ENTRY
  1770. ; none
  1771. ; EXIT
  1772. ; userAX =  size in bytes needed to save EGA.SYS context
  1773. ; DESTROYS
  1774. ; AX
  1775. ;
  1776. assume cs:CODE, ds:CODE, es:nothing, ss:nothing
  1777. GetContextSize proc near
  1778. push bp ; Save environment
  1779. mov bp,sp ; Set up stack addressing
  1780. mov [bp].userAX,SizeEGAContext ; Stash size on stack for ax
  1781. pop bp ; Restore environment
  1782. ciX: ; Mind if we use your ret?  Thanks.
  1783. ret
  1784. GetContextSize endp
  1785. page
  1786. ;
  1787. ; SaveContext - dump current EGA.SYS context data to user buffer
  1788. ;
  1789. ; If an app or TSR must change the EGA regs, but wants to restore
  1790. ; EGA.SYS and the hardware to the original state on entry, it should
  1791. ; first call GetContextSize.  Based on the value returned, it should
  1792. ; allocate the necessary buffer (possibly on the stack), set es:bx to
  1793. ; point to it, and issue this call.  The app is then free to issue other
  1794. ; EGA.SYS or int 10h calls at will.  When finished, it should call
  1795. ; RestoreContext data with a pointer to the saved context data.  Since
  1796. ; the current state of the dirty flags is included in the context data,
  1797. ; these too will be properly restored.
  1798. ;
  1799. ; Note that apps must not assume a given size for the context data.
  1800. ; An app should call GetContextSize at least once, beforehand, to
  1801. ; determine how much memory to provide.  Also, apps must not assume a
  1802. ; given structure for the context data or modify it in any way.
  1803. ;
  1804. ; If an app or TSR plans to make semi-permanent changes to the EGA regs,
  1805. ; it may avoid the Save/Restore context calls.  EGA.SYS will shadow any
  1806. ; int 10h calls that modify the EGA regs, updating both the default and
  1807. ; current shadow maps, but not touching any of the dirty flags.  This
  1808. ; allows the interrupted app to continue making RevertDefault calls, yet
  1809. ; keeps the new changes in effect until the app explicitly changes a reg
  1810. ; which the TSR modified.
  1811. ;
  1812. ; ENTRY
  1813. ; es:bx ->  user save area buffer for EGA context
  1814. ; EXIT
  1815. ; none
  1816. ; DESTROYS
  1817. ; ax, si, ds, flags
  1818. ;
  1819. assume cs:CODE, ds:CODE, es:nothing, ss:nothing
  1820. SaveContext proc near
  1821. push cx ; Save environment
  1822. push dx ; Save environment
  1823. push di ; Save environment
  1824. push bx ; Save environment
  1825. call GetLatchLocation ; Get EGA/VGA latch save location
  1826. or di,di ; Are we in text mode?
  1827. jz @F ; Yes - skip
  1828. ;
  1829. ; Save the EGA/VGA latches
  1830. ;
  1831. mov ah,ReadRegNum ; Read 1 register
  1832. mov dx,10h ; Graphics port register
  1833. mov bx,5 ; Index 5
  1834. int 10h ; Get it
  1835. mov si,ds ; Find a place for our byte
  1836. ; in vram, past visible memory
  1837. mov dx,egamem
  1838. mov ds,dx
  1839. assume ds:egamem
  1840. mov ax,(MR_SET shl 8) or GRAF_MODE_REG ; Set mode reg
  1841. ; to writethrough (mode 1)
  1842. mov dx,EGA_BASE + GRAF_CONT ; Set the port
  1843. OutWord ,DestroyAX,DestroyDX
  1844. mov egamem:[di],al ; Actually write to vram and store
  1845. ; latches at offset [bx]
  1846. mov bh,bl ; Position it properly
  1847. mov bl,5 ; Index 5
  1848. mov ah,WriteRegNum ; Write 1 register
  1849. mov dx,10h ; Graphics port register
  1850. int 10h ; Restore original port value
  1851. mov ds,si
  1852. assume ds:CODE
  1853. ;
  1854. ; Save the EGA/VGA registers
  1855. ;
  1856. @@:
  1857. call UpdateCRTCMap ; Get latest readable regs
  1858. pop bx ; Restore environment
  1859. mov di,bx
  1860. mov si,offset StartEGAContext
  1861. mov cx,SizeEGAContext / 2
  1862. if SizeEgaContext AND 1
  1863. movsb
  1864. endif ; SizeEgaContext AND 1
  1865. rep movsw
  1866. pop di ; Restore environment
  1867. pop dx ; Restore environment
  1868. pop cx ; Restore environment
  1869. ret
  1870. SaveContext endp
  1871. page
  1872. ;
  1873. ; RestoreContext - restore EGA.SYS context data from user buffer
  1874. ;
  1875. ; RestoreContext copies a previously saved EGA context pointed to by
  1876. ; es:bx to the internal data areas of EGA.SYS and updates the hardware
  1877. ; to reflect the restored state. The only caveat is that the state of
  1878. ; the Attribute index/data flip-flop is reset to the "index" state since
  1879. ; SaveContext is unable to save this information.  Note that this should
  1880. ; not be a problem if the caller checks the fInBIOS flag before
  1881. ; attempting to reprogram the EGA and if the interrupted application
  1882. ; only uses EGA.SYS or int 010h to modify the hardware.  This is because
  1883. ; EGA.SYS and int 010h always reset this flip-flop to the "index" state
  1884. ; on return.
  1885. ;
  1886. ; ENTRY
  1887. ; es:bx -> previously saved EGA context
  1888. ; EXIT
  1889. ; none
  1890. ; DESTROYS
  1891. ; ax, si, ds, flags
  1892. ;
  1893. assume cs:CODE, ds:CODE, es:nothing, ss:nothing
  1894. RestoreContext proc near
  1895. push cx ; Save environment
  1896. push dx ; Save environment
  1897. push di ; Save environment
  1898. push es ; Save environment
  1899. ;
  1900. ; Restore the EGA/VGA latches
  1901. ;
  1902. call GetLatchLocation ; Get EGA/VGA latch save location
  1903. or di,di ; Are we in text mode?
  1904. jz @F ; Yes - skip
  1905. mov dx,egamem
  1906. mov ds,dx
  1907. assume ds:egamem
  1908. mov dx,EGA_BASE + GRAF_ADDR ; Setup for writethrough mode
  1909. mov ax,(DR_SET shl 8) or GRAF_DATA_ROT
  1910. pushf ; Save interrupt flag state
  1911. cli ; No interrupts while changing regs
  1912. OutWord NoInts,DestroyAX
  1913. IOdelay
  1914. mov ax,(0ffh shl 8) or GRAF_BIT_MASK ; Don't mask any bits
  1915. OutWord NoInts,DestroyAX,DestroyDX
  1916. IOdelay
  1917. ; DH already set correctly
  1918. mov dl,SEQ_ADDR ; Enable all planes, set seq
  1919. mov  ax,(MM_ALL shl 8) or SEQ_MAP_MASK ; Addr reg to point
  1920. OutWord NoInts,DestroyAX,DestroyDX ; to map mask reg
  1921. popf ; Restore interrupt flag state
  1922. mov al,egamem:[di] ; Actually write to vram to
  1923. ; restore the latches
  1924. @@:
  1925. mov si,bx
  1926. mov di,offset StartEGAContext
  1927. mov ax,es ; ES = CS
  1928. mov dx,cs ; DS = Old ES
  1929. mov es,dx ; "
  1930. assume es:CODE
  1931. mov ds,ax ; Get new clocking mode 1st
  1932. assume ds:nothing
  1933. mov al,ds:[si + offset SeqRegs - offset StartEgaContext + 01h]
  1934. cmp al,CODE:[di + offset SeqRegs - offset StartEgaContext + 01h]
  1935. jne @F ; If same, compare mem mode
  1936. mov al,ds:[si + offset SeqRegs - offset StartEgaContext + 04h]
  1937. cmp al,CODE:[di + offset SeqRegs - offset StartEgaContext + 04h]
  1938. jne @F ; If same, compare misc regs
  1939. mov al,ds:[si + offset GraphicsRegs - offset StartEgaContext + 06h]
  1940. cmp al,CODE:[di + offset GraphicsRegs - offset StartEgaContext + 06h]
  1941. @@:
  1942. mov cx,SizeEGAContext / 2
  1943. if SizeEgaContext AND 1
  1944. movsb
  1945. endif ; SizeEgaContext AND 1
  1946. rep movsw
  1947. pop es ; ES = old ES
  1948. assume es:nothing
  1949. mov ds,dx ; DS = CS
  1950. assume ds:CODE
  1951. mov cl,NumSeqRegs - 2  ; Don't do clocking/memory modes
  1952. mov dh,3 ; "prefix" for port addresses
  1953. mov si,offset SeqRegs
  1954. je @F   ; Jump if no changes here
  1955. mov ax,0100h
  1956. mov dl,(EGA_BASE + SEQ_ADDR) AND 0FFh
  1957. pushf ; Save interrupt flag state
  1958. cli ; RAM refresh will be off now!
  1959. OutWord NoInts ; Synchronous reset to sequencer
  1960. IOdelay
  1961. inc ax ; Now select clocking mode reg
  1962. mov ah,CODE:[si + 01h]
  1963. OutWord NoInts,DestroyAX ; Write its new value (in ah)
  1964. IOdelay
  1965. mov al,04h ; Now select memory mode reg
  1966. mov ah,CODE:[si + 04h]
  1967. OutWord NoInts,DestroyAX,DestroyDX ; Write its new value (in ah)
  1968. IOdelay
  1969. mov dl,(EGA_BASE + GRAF_CONT) AND 0FFh
  1970. mov al,06h ; Now select grphx misc reg
  1971. mov ah,[GraphicsRegs + 06h]
  1972. OutWord NoInts,DestroyAX,DestroyDX ; Write its new value, too (ah)
  1973. popf ; Restore interrupt flag state
  1974. @@:
  1975. mov dl,(EGA_BASE + SEQ_ADDR) AND 0FFh ; Setup for seq loop
  1976. mov al,ch ; AL = 0
  1977. recSeqLoop:
  1978. mov ah,CODE:[si]
  1979. IOdelay
  1980. OutWord  ; No ints can occur until after
  1981. @@:
  1982. inc si
  1983. inc ax
  1984. cmp al,01h ; Clocking mode reg next?
  1985. je @B ; If so, skip it
  1986. loop recSeqLoop ; Otherwise continue if more
  1987. mov al,cl ; AL = 0
  1988. mov cl,NumGraphicsRegs - 1
  1989. mov si,offset GraphicsRegs
  1990. mov dl,(EGA_BASE + GRAF_CONT) AND 0FFh
  1991. recGrphLoop:
  1992. mov ah,CODE:[si]
  1993. IOdelay
  1994. OutWord
  1995. @@:
  1996. inc si
  1997. inc ax
  1998. cmp al,06h ; Grphx misc reg next?
  1999. je @B ; If so, skip it
  2000. loop recGrphLoop ; Otherwise continue if more
  2001. mov al,cl ; AL = 0
  2002. mov cl,NumCRTCRegs
  2003. mov dl,byte ptr [PortTable][0].prPortAddr
  2004. mov si,offset CRTCRegs
  2005. @@:
  2006. mov ah,CODE:[si]
  2007. IOdelay
  2008. OutWord
  2009. inc si
  2010. inc ax
  2011. loop @B
  2012. mov cl,[PortTable][3 * SIZE PortRec].prNumRegs
  2013. mov si,offset AttrRegs
  2014. pushf ; Save interrupt flag state
  2015. WaitRetrace ; Also disables interrupts
  2016. mov al,ch ; Restore index (0)
  2017. mov dl,AttCtrlAddrReg AND 0FFh ; Restore dx to AttrAddr
  2018. @@:
  2019. mov ah,CODE:[si]  ; Get data
  2020. IOdelay
  2021. OutWordAttr ,NoInts ; Write index/data to AttrAddr
  2022. inc si
  2023. inc ax
  2024. loop @B
  2025. mov al,PaletteAddressSource ; Since dx still has AttrAddr,
  2026. IOdelay
  2027. out dx,al ; enable video now
  2028. IOdelay
  2029. InitFlipFlop NoSaveAX ; Reset FF and get FeatAddr!
  2030. popf ; Restore interrupt flag state
  2031. IOdelay
  2032. mov al,[FeatureReg]  ; Since dx still has FeatAddr,
  2033. out dx,al ; program it now
  2034. IOdelay
  2035. mov dl,MiscAddr AND 0FFh
  2036. mov al,[MiscOutReg]
  2037. out dx,al
  2038. cmp [fVga],CL ; If VGA is present,
  2039. jne @F ;  skip GR1&2 processing
  2040. mov dl,Gr1PosAddr AND 0FFh
  2041. mov al,[GR1PosReg]
  2042. IOdelay
  2043. out dx,al
  2044. IOdelay
  2045. mov dl,Gr2PosAddr AND 0FFh
  2046. mov al,[GR2PosReg]
  2047. out dx,al
  2048. @@:
  2049. pop di ; Restore environment
  2050. pop dx ; Restore environment
  2051. pop cx ; Restore environment
  2052. ret
  2053. RestoreContext endp
  2054. page
  2055. ;
  2056. ; GetLatchLocation - dump current EGA.SYS context data to user buffer
  2057. ;
  2058. ; ENTRY
  2059. ; None
  2060. ; EXIT
  2061. ; If currently in graphics mode
  2062. ; DI -> Latch location
  2063. ; Else (Text mode)
  2064. ; DI = 0
  2065. ; DESTROYS
  2066. ; AX
  2067. ;
  2068. assume cs:CODE, ds:CODE, es:nothing, ss:nothing
  2069. GetLatchLocation proc near
  2070. xor di,di ; Assume text mode
  2071. mov al,[biosmode] ; Get current video mode
  2072. and al,01111111b ; Reset noclear bit
  2073. cmp al,13h ; Is it a mode we can handle?
  2074. ja @F ; No - skip (fake text mode)
  2075. sub al,0dh ; Adjust to zero base
  2076. js @F ; Skip if text mode
  2077. xor ah,ah ; No high byte
  2078. add di,ax ; Position to video mode in table
  2079. mov di,CODE:[di] + offset EGALatchTable ; Get desired latch location
  2080. @@:
  2081. ret
  2082. GetLatchLocation endp
  2083. page
  2084. ;
  2085. ; GetFontInfo - dump current font data in FontInfo format to user buffer
  2086. ;
  2087. ; GetInfo is provided for environments like Windows that need to know
  2088. ; which alpha fonts have been downloaded and which banks they are in.
  2089. ;
  2090. ; This call copies the current EGA.SYS FontInfo structure to a user
  2091. ; buffer pointed to by es:bx.  Based on this information, the caller can
  2092. ; determine the need to save alpha font data in plane 2, as well as
  2093. ; determine the most efficient way to do it.  For example, font ID's
  2094. ; 001h and 002h need not be saved since a copy exists in the EGA ROM.
  2095. ;
  2096. ; Graphics font data is maintained by the EGA BIOS via int 01Fh and int
  2097. ; 043h and does not exist in the EGA hardware.  Since these interrupts
  2098. ; can be directly manipulated for Save/Restore operations, EGA.SYS does
  2099. ; not attempt to record any graphics font information.
  2100. ;
  2101. ; FontInfo format:
  2102. ;
  2103. ; FontInfo struc
  2104. ;   fibank0 db ?
  2105. ;   fibank1 db ?
  2106. ;   fibank2 db ?
  2107. ;   fibank3 db ?
  2108. ; FontInfo ends
  2109. ;
  2110. ; where each fiBankx contains a byte defined as follows:
  2111. ;
  2112. ; 000h -  user font in specified bank
  2113. ; 001h -  08x14 ROM font in specified bank (Default for EGA)
  2114. ; 002h -  08x08 ROM font in specified bank
  2115. ; 004h -  08x16 ROM font in specified bank (Default for VGA)
  2116. ; 0FFh -  empty bank
  2117. ;
  2118. ; ENTRY
  2119. ; es:bx -> user buffer for FontInfo
  2120. ; EXIT
  2121. ; none
  2122. ; DESTROYS
  2123. ; ax
  2124. ;
  2125. assume cs:CODE, ds:CODE, es:nothing, ss:nothing
  2126. GetFontInfo proc near
  2127. mov ax,word ptr [FontBank][0]
  2128. mov es:[bx],ax
  2129. mov ax,word ptr [FontBank][2]
  2130. mov es:[bx][2],ax
  2131. ret
  2132. GetFontInfo endp
  2133. ;
  2134. ; GetInBiosFlag - return segment:offset of the InBiosFlag
  2135. ;
  2136. ; ENTRY
  2137. ; none
  2138. ; EXIT
  2139. ; es:bx ->  InBiosFlag
  2140. ; DESTROYS
  2141. ; none
  2142. ;
  2143. assume cs:CODE, ds:CODE, es:nothing, ss:nothing
  2144. GetInBiosFlag proc near
  2145. mov bx,cs
  2146. mov es,bx
  2147. assume es:CODE
  2148. mov bx,offset fInBIOS
  2149. ret
  2150. GetInBiosFlag endp
  2151. subttl InquireDriver
  2152. page
  2153. ;
  2154. ; InquireDriver - return ptr to driver version number
  2155. ;
  2156. ; ENTRY
  2157. ; none
  2158. ; EXIT
  2159. ; es:bx -> DriverInfo data area
  2160. ; DESTROYS
  2161. ; None
  2162. ;
  2163. assume cs:CODE, ds:CODE, es:nothing, ss:nothing
  2164. InquireDriver proc near
  2165. mov bx,ds
  2166. mov es,bx
  2167. assume es:CODE
  2168. mov bx,offset DriverInfo
  2169. ret
  2170. InquireDriver endp
  2171. ifdef Sys
  2172. include int10rtn.inc ; Contains Int10Routine and Int2FRoutine
  2173. ; Also in load.inc for .COM version
  2174. endif ; Sys
  2175. EndOfResidentCode label near
  2176. ;
  2177. ; I N C L U D E S
  2178. ;
  2179. include load.inc
  2180. CODE ends
  2181. end main