saveega.new
资源名称:DOS系统的源代码.rar [点击查看]
上传用户:xiaoan1112
上传日期:2013-04-11
资源大小:19621k
文件大小:28k
源码类别:
操作系统开发
开发平台:
Visual C++
- ;*
- ;* CW : Character Windows
- ;*
- ;* ega.asm : DOS3 TWIN compatible screen driver
- ;*
- ;*****************************************************************************
- ;* * Special screen save
- NonStandard CbSizeVidsCsd
- NonStandard FSaveVidsCsd
- NonStandard FRestoreVidsCsd
- NonStandard SetVideoMode
- NonStandard SaveVidDataCsd
- NonStandard RestoreVidDataCsd
- NonStandard EnableVidsMonitorCsd
- ;********** CbSizeVidsCsd **********
- ;* * CSD entry point (see documentation for interface)
- cProc CbSizeVidsCsd, <FAR, PUBLIC, ATOMIC>
- cBegin CbSizeVidsCsd
- mov ax,SIZE EGA_VIDS
- mov bx,OFF_lpwDataCsd ;* Data in data segment
- test [bx].fvmCurAdap, fvmEGA or fvmVGA or fvm64KEGA or fvmEGAM or fvmMCGA
- jnz notCGAVids
- sub ax,24 ;for EGA palette settings
- jmp short CbSizeExit
- notCGAVids:
- test [bx].fvmCurAdap, fvmMCGA or fvmVGA
- jz CbSizeExit
- add ax,255*3 ;for PS2 palette settings
- CbSizeExit:
- inc ax ;get even cb
- and ax,0FFFEh
- cEnd CbSizeVidsCsd
- ;********** FSaveVidsCsd ********
- ;* entry: pvidsSave = near pointer to VIDS structure
- ;* pinst = near pointer to INST for new mode
- ;* * fill *pvidsSave with state of current screen mode (not screen data)
- ;* exit: AX != 0 if ok, == 0 if error
- cProc FSaveVidsCsd, <FAR, PUBLIC, ATOMIC>, <si, di>
- parmDP pvidsSave
- parmDP pinst
- cBegin FSaveVidsCsd
- mov di,pvidsSave
- mov ah,0Fh
- int 10h ;* GetMode and page
- and al,07Fh ; clear msb
- mov [di].modeVids,al
- mov [di].pageVids,bh
- mov [di].fClearRegenVids,00H
- mov ax,SIZE EGA_VIDS - cbVidsMin ;default EGA
- mov bx,OFF_lpwDataCsd ;* Data in data segment
- test [bx].fvmCurAdap, fvmEGA or fvmVGA or fvm64KEGA or fvmEGAM or fvmMCGA
- jnz notFSCGA
- sub ax,24 ;EGA palette regs
- jmp short notFSPS2
- notFSCGA:
- test [bx].fvmCurAdap, fvmMCGA or fvmVGA
- jz notFSPS2
- add ax,255*3 ;DAC color regs
- notFSPS2:
- inc ax ;get even cb
- and ax,0FFFEh
- shr ax,1
- mov [di].cwExtraVids,ax
- mov ah,3
- int 10h ;* GetCursorPos
- mov [di].vparmCursorVids,cx
- mov ax,ds
- mov es,ax
- mov dx,di
- lea di,[di].rgwCursorPosVids ;* save cursor positions here
- push ds
- xor ax,ax
- mov ds,ax
- mov si,BIOS_cursor_posn ;* 8 Cursor positions in BIOS
- mov cx,8
- rep movsw
- pop ds
- mov di,dx ; restore di
- public saveCGAPal ;UNDONE - remove these two lines
- saveCGAPal: ;UNDONE
- ;
- ; Assumes bCGABg is immediately before bCGAPal
- ; and bCGABgVids is immediately before bCGAPalVids
- ;
- .errnz (bCGABgVids+1) - bCGAPalVids
- .errnz (bCGABg+1) - bCGAPal
- mov ax, word ptr cs:[bCGABg]
- mov word ptr [di].bCGABgVids, ax
- mov dl, [di].modeVids
- cmp dl,40H ;Olivetti
- jz @F
- test [bx].fvmCurAdap, fvmCGA
- jz skipCGA
- @@:
- ;* for CGA only
- xor ax,ax
- mov es,ax
- mov al, byte ptr es:[466H]
- mov [di].ayOverScanVids, al
- mov ax, 80*25 ; Maybe we can get by just saving what we use (4k b).
- cmp dl, 2
- je save_not_graphics
- cmp dl, 3
- je save_not_graphics
- mov ax, 8*1024 ; Must mode switch (4,5,6) so must save all of regen(16k b)
- cmp dl, 40H ; Is this an Olivetti graphics screen mode?
- jne @F
- add ax, ax ; Yes, there is twice as much memory to save
- @@:
- save_graphics:
- and [di].fvidsVids,not fvidsChAttr ;graphics modes
- save_not_graphics: ;* ax = # of words to swap
- mov [di].cwSwapVids,ax
- jmp EgaSS_Exit
- skipCGA:
- test [bx].fvmCurAdap, fvmEGA or fvmVGA or fvm64KEGA or fvmEGAM or fvmMCGA
- jz @F
- cCall EgaSavePalette ;save palette regs
- @@:
- push bp
- mov ax,1130h ; get info
- xor bx,bx
- xor cx,cx
- int 10h
- pop bp
- inc dl ; dl = scan lines
- mov [di].ayMacVids,dl ; rows
- mov [di].ayPointsVids,cl ; cl = number of lines in char
- cmp [di].modeVids,4 ;check simple graphics
- jb notmode4to6
- cmp [di].modeVids,6
- ja notmode4to6
- mov ax,8*1024 ; Must mode switch (4,5,6) so must save all of regen(16k b)
- mov [di].cwSwapVids,ax
- and [di].fvidsVids,not fvidsChAttr ;graphics modes
- jmp EgaSS_Exit
- notmode4to6:
- mov ax,80 ;default 80 columns
- mov si,pinst
- cmp dl,[si].ayMacInst ;rows
- ja AboveNewAy
- mov dl,[si].ayMacInst ;assume going into text mode
- AboveNewAy:
- mul dl ;columns * rows
- mov cl,[di].modeVids
- cmp cl, 08H
- ja EgaSS_Hard
- cmp cl, 07H
- jb NotHerc
- ; We are in mode 7 or 8 so we might have a Hercules card.
- push ax ;Save cwSwap
- mov ah,0efH
- mov dl, -1
- int 10H
- pop ax ;restore cwSwap
- inc dl
- jz NotHerc ;DL not changed by INT 10 unless herc.
- mov ax,8*1024 ;Must save 8k words for herc
- ;We would only have to save 4K words
- ;If it weren't for Compaq's stupid
- ;BIOS which always clears 16K bytes
- ;when switching into mode 7.
- mov [di].fClearRegenVids,80H
- NotHerc:
- mov [di].cwSwapVids,ax
- mov [di].fvidsVids,fvidsChAttr ;Text modes
- jmp EgaSS_Exit
- ; *** Graphics Text ***
- ; Ok, we are in one of the difficult graphics modes.
- ; We must save cLines*80 words from bit plane 0 and the same from bit plane 1
- ; and we must save 4k words from bit plane 2 (because the character
- ; generator gets loaded into this area when we switch to alpha mode).
- EgaSS_Hard:
- mov [di].cwSwapVids,ax
- and [di].fvidsVids,not fvidsChAttr ;graphics modes
- mov ax, 2*1024 ; MCGA uses 2k words
- mov bx,OFF_lpwDataCsd ;* Data in data segment
- test [bx].fvmCurAdap, fvmMCGA
- jnz EgaSS_Alloc
- mov ax,[di].cwSwapVids ; ax == cLines*cColumns words
- shl ax,1 ; for bit plane 0 and 1
- EgaSS_Alloc:
- add ax, 4*1024 ; Save 4k words of bit plane 2
- test [bx].fvmCurAdap, fvm64KEGA
- jz EgaSS_Exit
- ; More memory gets trashed by the BIOS doing a mode reset on a 64k Ega.
- ; Note: On a 64k Ega, the 4k words starting at 16k of bit plane 2 also get
- ; trashed by the BIOS for some reason (so we gotta save that too).
- add ax,4*1024
- EgaSS_Exit:
- mov [di].cwVidDataVids,ax
- mov ax,sp ;* success
- cEnd FSaveVidsCsd
- ;********** EgaSavePalette ********
- ;*
- ;* entry: ds:[di] => Vids
- cProc EgaSavePalette,<NEAR,PUBLIC>,<SI,DI,ES>
- cBegin EgaSavePalette
- mov bx,OFF_lpwDataCsd ;* Data in data segment
- mov ax,ds
- mov es,ax
- test [bx].fvmCurAdap, fvmMCGA or fvmVGA ;PS2 ?
- jz @F
- lea dx, [di].rgbPS2PaletteVids
- mov ax, 1017H ; Read block of Palette regs
- xor bx,bx ; start at reg 0
- mov cx, 256 ; read 256 regs
- int 10H
- @@:
- mov bx,OFF_lpwDataCsd ;* Data in data segment
- test [bx].fvmCurAdap, fvmEGA or fvmVGA or fvm64KEGA or fvmEGAM
- jz @F
- push ds
- pop es
- lea di, [di].rgbEgaPaletteVids ;es:[di] -> buffer
- push cs
- pop ds
- mov si, DrvOffset EGAPaletteMirror
- mov cx,17 ;16 palette + overscan regs
- rep movsb
- push ss
- pop ds ;restore ds
- @@:
- cEnd EgaSavePalette
- ;********** FRestoreVidsCsd ********
- ;* entry: pvidsRestore = near pointer to VIDS structure
- ;* * restore video state with data in *pvidsRestore (not screen data)
- ;* exit: AX != 0 if ok, == 0 if error
- cProc FRestoreVidsCsd, <FAR, PUBLIC, ATOMIC>, <si, di>
- parmDP pvidsRestore
- cBegin FRestoreVidsCsd
- mov di,pvidsRestore
- mov al, [di].modeVids
- cmp al, 2
- je EgaFRS_Text
- cmp al, 3
- je EgaFRS_Text
- cmp al, 40H ;[==] Olivetti
- je EgaFRS_SimpleGraphics ;[==]
- cmp al, 8
- ja EgaFRs_HardGraphics
- cmp al, 7
- jae EgaFRS_Text
- EgaFRS_SimpleGraphics: ;mode 4,5 & 6
- cCall SetVideoMode
- jmp EgaFRS_Common
- EgaFRS_Text: ; mode 2,3 and 7
- mov bx,OFF_lpwDataCsd ;* Data in data segment
- cmp [bx].fBlinkEnable,0
- je @F ;trash ax,dx
- mov [bx].fBlinkEnable,0 ;disable Blink
- cCall DiddleBlinkbit
- jmp short RestoreBlink
- @@:
- mov [bx].fBlinkEnable,1 ;enable Blink
- cCall EnableBlinkbit
- RestoreBlink:
- mov bx,OFF_lpwDataCsd ;* Data in data segment
- test [bx].fvmCurAdap, fvmVGA ;VGA ?
- jz EgaFRs_SetScanLines_done
- mov al,2 ;default 400 lines
- cmp [di].ayMacVids,43 ; 43 line mode
- jne useDefaultLine
- dec al ;set 350 scan line
- useDefaultLine:
- mov ah,12h ;set vertical scan line
- mov bl,30h
- int 10h ;takes effect on next mode set
- EgaFRs_SetScanLines_done:
- cCall SetVideoMode
- or ax,ax ;mode set ?
- jz EgaFRS_Common
- cmp [di].ayPointsVids,8 ;8x8 font ?
- jne EgaFRS_Common
- mov ax,1112h
- mov bh,8
- xor bl,bl
- int 10h
- jmp EgaFRS_Common
- EgaFRS_HardGraphics:
- cCall ClearRegen
- cCall SetVideoMode
- cmp [di].ayPointsVids, 8
- jne EgaFRs_NoLoad8
- mov ax,1123h
- xor bh,bh
- mov bl,[di].modeVids
- sub bl,0dh
- mov dl,cs:[GraphicsModeRows+bx]
- xor bl,bl
- int 10h
- EgaFRs_NoLoad8:
- EgaFRs_Common:
- mov al,[di].pageVids
- mov ah,5
- int 10h ;* SetPage
- mov dx,di
- xor ax,ax
- mov es,ax
- lea si,[di].rgwCursorPosVids
- mov di,BIOS_cursor_posn
- mov cx,8
- rep movsw
- mov di,dx
- mov bl,[di].pageVids
- xor bh,bh
- shl bx,1
- mov dx,[di+bx].rgwCursorPosVids ;* get cursor pos for this page
- shr bx,1
- mov bh,bl
- mov ah,2
- int 10h ;* SetCursorPos
- mov cx,[di].vparmCursorVids
- mov ah,1
- int 10h ;* SetCursor
- cmp [di].modeVids,40H ;Don't EgaRestore palette for
- je @F ; Olivetti
- mov bx,OFF_lpwDataCsd ;* Data in data segment
- test [bx].fvmCurAdap, fvmEGA or fvmVGA or fvm64KEGA or fvmEGAM or fvmMCGA
- jz @F
- cCall EgaRestorePalette
- @@:
- public restoreCGAPal ;UNDONE - remove
- restoreCGAPal: ;UNDONE - remove
- push bx
- mov bl, [di].bCGAPalVids
- or bl,bl
- js @F ;* skip if negative
- mov bh,1
- mov ah,0BH
- int 10H ;* set color palette
- @@:
- mov bl, [di].bCGABgVids
- or bl,bl
- js @F ;* skip if negative
- xor bh,bh
- mov ah,0BH
- int 10H ;* set background color
- @@:
- pop bx
- test [bx].fvmCurAdap, fvmCGA ;CGA ?
- jz @F
- xor ax,ax
- mov es,ax
- mov al, [di].ayOverScanVids
- mov byte ptr es:[466H],al
- mov dx, 3d9H
- out dx, al
- @@:
- mov ax,sp ;* success
- cEnd FRestoreVidsCsd
- ;********** EgaRestorePalette ********
- ;*
- ;*
- cProc EgaRestorePalette,<NEAR,PUBLIC>,<SI,DI,ES>
- cBegin EgaRestorePalette
- mov bx,OFF_lpwDataCsd ;* Data in data segment
- mov ax,ds
- mov es,ax
- test [bx].fvmCurAdap, fvmMCGA or fvmVGA ;PS2 ?
- jz @F
- lea dx, [di].rgbPS2PaletteVids
- mov ax, 1012H ; write block of Palette regs
- xor bx,bx ; start at reg 0
- mov cx, 256 ; read 256 regs
- int 10H
- @@:
- mov bx,OFF_lpwDataCsd ;* Data in data segment
- test [bx].fvmCurAdap, fvmEGA or fvmVGA or fvm64KEGA or fvmEGAM
- jz @F
- cmp cs:[lpbBIOSINT10_Offset],0 ;save check
- je @F
- mov ax,1002h
- lea dx, [di].rgbEGAPaletteVids ;es:[dx] -> buffer
- int 10h
- @@:
- cEnd EgaRestorePalette
- ;***********************
- cProc EnableBlinkBit, <NEAR, ATOMIC, PUBLIC>, <DS>
- cBegin EnableBlinkBit
- ;* * Diddle blink bit via BIOS call (or diddle CGA bit)
- mov bx,OFF_lpwDataCsd ;* Data in data segment
- test [bx].fvmCurAdap, fvmCGA or fvmMDA
- jz EBB_NotCGA
- xor ax,ax
- mov ds,ax
- mov dx,ds:[BIOS_addr_6845]
- add dx,PORT_mode
- ;* * set the mode set flag
- or byte ptr ds:[BIOS_crt_mode_set],20H
- mov al,ds:[BIOS_crt_mode_set]
- out dx,al ;* send to port
- ;* * EGA etc has a BIOS call for this
- EBB_NotCGA:
- mov ax,1003H ;* set intensify/blink
- mov bx,1 ;* enable blink
- int 10h
- cEnd EnableBlinkBit
- ;********** SetVideoMode **********
- ;* entry: al = video mode
- ;* * Set specified video mode
- ;* exit: trash ax,cx,es
- ;* ax = 0 same mode,-1 mode set
- cProc SetVideoMode,<NEAR>,<es>
- cBegin SetVideoMode
- mov ah,0Fh
- int 10h ;* GetMode
- and al,7fh
- cmp al,[di].modeVids
- jne SVM_SetMode ;reset
- ;same mode, check rows
- mov bx,OFF_lpwDataCsd ;* Data in data segment
- test ss:[bx].fvmCurAdap, fvmCGA ;CGA only support 25 rows
- jnz @F ; jnz mode_already_set
- push bp
- mov ax,1130h ; get info
- xor bx,bx
- xor cx,cx
- int 10h
- pop bp
- inc dx ; dl = scan lines
- cmp dl,[di].ayMacVids ; rows
- jne SVM_SetMode
- @@:
- jmp mode_already_set
- SVM_SetMode:
- mov al,[di].modeVids
- or al,[di].fClearRegenVids
- mov bx,OFF_lpwDataCsd ;* Data in data segment
- test ss:[bx].fvmCurAdap, fvmEGA or fvmVGA or fvm64KEGA or fvmMCGA or fvmEGAM
- jz TrashRegen ;CGA doesn't support the function below
- cmp al, 40H ;Olivetti doesn't support it either.
- je TrashRegen
- or al,80h ;* don't clear RGEN
- ; The following section is to make switching between color and monochrome
- ; modes work on all VGA's. On Olivetti VGA's and PS/2 VGA's this works
- ; automatically, but on IBM AT-card VGA's and other CLONES, a hack is
- ; needed to make it work. If it's a VGA, we change the equipment flags
- ; to match the mode we're going into (mono or color). We also have to
- ; call INT 10, function 12, sub-function 33 to turn gray-scale summing on
- ; or off if a color display is attached.
- test ss:[bx].fvmCurAdap, fvmVGA ;[1]
- je TrashRegen ;[1]
- push ax ; save mode
- xor cx,cx ;
- mov es,cx ;
- mov ah,es:[410h] ; get equipment flags
- or ah,30h ;
- and al,07h ; check for mode 7 or f
- sub al,07h ; mono mode?
- jz @F ; brif -- go set equipment flags
- mov al,1 ; turn off summing if color monitor
- and ah,0EFh ; set equipment flags for Color80
- @@: ;
- mov es:[410h],ah ; uddate equipment flags
- cmp ss:[bx].fvmCurDisp, fvmMD ; monochrome analog monitor?
- je @F ; brif so -- leave summing on
- push bx ; save OFF_lpwDataCsd
- mov bl,33h ;
- mov ah,12h ; turn gray-scale summing on/off
- int 10h ;
- pop bx ; restore bx = OFF_lpwDataCsd
- @@: ;
- pop ax ; restore al = mode
- TrashRegen:
- xor ah,ah
- push ax ;save mode
- int 10h ;* set mode
- pop ax ;restore
- ;* * Delay so that we won't start writting to the display before it has
- ;* * settled down.
- mov cx,500
- delay_me:
- loop delay_me
- ;
- ; When the olivetti is in mode 40H the value at BIOS_info is a pointer to
- ; the character set (NOT flags as it is in EGA modes)
- ; So let's not trash the pointer by clearing the "don't clear regen" bit.
- ;
- cmp al, 40H
- je @F
- test ss:[bx].fvmCurAdap, fvmEGA or fvmVGA or fvm64KEGA or fvmMCGA or fvmEGAM
- jz @F
- ;* Clear the "don't clear regen" bit in the BIOS image
- xor ax,ax
- mov es,ax
- and byte ptr es:[BIOS_info],7fH ;487H
- mov al,[di].ayMacVids ;
- dec ax ; rows - 1
- mov byte ptr es:[0484H],al ; * update BIOS rows
- @@:
- ;
- ; The following is provided only to overcome a bug in the EGA BIOS
- ; routines which support the graphics "compatibility mode" (BIOS 4)
- ; so that the two calls related to PALETTE (INT10 AH = 0BH and
- ; INT10H AH = 10H) work correctly. If we use the first call once
- ; when user invokes SCREEN 1 to set the background color, then the
- ; BIOS will subsequently reference the correct (low-intensity)
- ; color values for the 4 palette attributes whenever the call using
- ; INT10H, AH = 0BH is used to toggle the palette, and whenever the
- ; call INT10H, AH = 10H is used to set an individual palette regis-
- ; ter. In the absence of this initialization, the high-intensity
- ; color values for both palettes are referenced.
- ;
- test ss:[bx].fvmCurAdap, fvmEGA or fvmVGA or fvm64KEGA or fvmEGAM
- jz SkipKludge
- mov al, [di].modeVids
- cmp al,4
- je @F
- cmp al,5
- jne SkipKludge
- @@:
- push bx
- xor bx,bx
- mov ah, 0BH
- int 10H ;set background color
- pop bx
- SkipKludge:
- mov ax,-1 ;mode set
- jmp short @F
- mode_already_set:
- xor ax,ax ;same mode
- @@:
- cEnd SetVideoMode
- ;********** SaveVidDataCsd ********
- ;* entry: pvidsSaveData = near pointer to VIDS structure
- ;* lpwBuffer = buffer to save data
- ;* * save screen data into buffer
- ;* exit: n/a
- cProc SaveVidDataCsd, <FAR, PUBLIC, ATOMIC>, <DS, SI, DI>
- parmDP pvidsSaveData
- parmD lpwBuffer
- cBegin SaveVidDataCsd
- mov di,pvidsSaveData
- mov si,di
- mov dl,[di].modeVids
- mov cx,0B800h
- cmp dl,7
- jb @F
- cmp dl,8
- ja @F
- mov cx,0B000h ;video segment for mono mode
- @@:
- mov ax,[di].cwSwapVids
- les di,lpwBuffer ;es:[di] -> buffer
- cmp dl,40h ;Olivetti ?
- je @F
- cmp dl,8
- ja save_graphics_text
- @@: ;Text modes or mode 6
- cCall SaveRegen
- mov di,si
- cCall ClearRegen
- jmp SaveVidsDataExit
- save_graphics_text:
- mov bx,OFF_lpwDataCsd ;* Data in data segment
- mov ax, 0a000H ; Address of bit planes
- mov ds, ax ;ds:[si] -> video buffer
- test ss:[bx].fvmCurAdap, fvmMCGA
- jz EgaSS_NotMCGA
- mov si, 8000H
- mov cx, 2*1024
- EgaSS_MCGA1:
- xor ax,ax
- xchg ax, [si]
- inc si
- inc si
- stosw
- loop EgaSS_MCGA1
- jmp short EgaSS_SaveBitPlane2
- EgaSS_NotMCGA:
- mov cl, 0 ;bit plane 0
- mov bx,pvidsSaveData
- mov ax, ss:[bx].cwSwapVids
- cCall SaveBitPlane
- mov cl, 1 ;bit plane 1
- mov bx,pvidsSaveData
- mov ax, ss:[bx].cwSwapVids
- cCall SaveBitPlane
- EgaSS_SaveBitPlane2:
- mov cl, 2 ;bit plane 2
- mov ax, 4*1024
- cCall SaveBitPlane
- ;
- ; The 8k bytes starting at 16k only gets trashed on 64k Ega cards
- ;
- mov bx,OFF_lpwDataCsd ;* Data in data segment
- test ss:[bx].fvmCurAdap, fvm64KEGA
- jz EgaSs_64plus
- mov cl, 2
- mov ax, 4*1024
- mov si, 16*1024
- cCall SaveBitPlane2
- EgaSs_64plus:
- push ss ; Restore ds
- pop ds
- mov bx,OFF_lpwDataCsd ;* Data in data segment
- test [bx].fvmCurAdap, fvmMCGA
- jnz EgaSS_NotMCGA2
- mov di,pvidsSaveData
- cCall ClearBitPlanes
- EgaSS_NotMCGA2:
- SaveVidsDataExit:
- cEnd SaveVidsDataCsd
- ;***
- ;
- ; SaveRegen - Saves the video regen buffer to global memory
- ;
- ; Inputs: [ax] - Number of words to save
- ; [di] - Points to a VideoState buffer where handle to
- ; global memory used to save the regen buffer is
- ; store (along with the size of the saved buffer)
- ; [es] - Segment of video regen buffer
- ;
- ;
- ; Outputs: none.
- ;
- ; Uses: es, si
- ;
- ;****
- cProc SaveRegen,<NEAR>,<DI,SI>
- cBegin SaveRegen
- push ds
- mov ds,cx
- mov cx,ax
- xor si,si
- ; cCall VideoOff ; (CGA) Only affects ax and dx
- rep movsw
- pop ds
- ; cCall VideoOn
- NoRegenSave:
- cEnd SaveRegen
- cProc VideoOff,<NEAR,PUBLIC>,<ES> ;trash ax,dx
- cBegin VideoOff
- mov dx,CGA_6845_STATUS
- WaitVerticalRetrace:
- in al,dx
- test al,08H
- jz WaitVerticalRetrace
- xor ax,ax
- mov es,ax
- mov ax,es:[0465H] ; Get Current CRT mode
- and ax, NOT 0008H ; turn off video signal bit
- mov dx,CGA_6845_MODE
- out dx,al
- cEnd VideoOff
- cProc VideoOn,<NEAR,PUBLIC>,<ES> ;trash ax,dx
- cBegin VideoOn
- xor ax,ax
- mov es,ax
- mov ax,es:[0465H] ; Get Current CRT mode
- or ax,0008H ; Turn on video signal bit
- mov dx,CGA_6845_MODE
- out dx,al
- cEnd VideoOn
- ;***
- ;
- ; ClearRegen - Clears the part of the regen buffer used by TWIN.
- ;
- ; Inputs: [di] - Points to a VideoState buffer containing the
- ; video state to be restored.
- ; [videoseg] - Segment of video regen buffer
- ;
- ; Outputs: The global memory used to save the regen buffer is freed.
- ; i.e. don't call RestoreRegen again with the save video state.
- ;
- ; Uses: es,di
- ;
- ;****
- cProc ClearRegen,<NEAR>,<di,es>
- cBegin ClearRegen
- mov ax, 0720H ; Assume text mode (clear to spaces)
- mov cx, 0B800h ; EGA
- mov bl, [di].modeVids
- cmp bl, 3
- jbe CR_1
- cmp bl,7
- jb @F
- cmp bl,8
- ja @F
- mov cx,0B000h
- jmp short CR_1
- @@:
- xor ax,ax ; Clear to Null for graphics modes.
- CR_1:
- mov es, cx ; Clear the part of the regen buffer
- mov cx, [di].cwSwapVids ; Save for later
- xor di,di ; that we used.
- rep stosw
- cEnd ClearRegen
- ;***
- ;
- ; RestoreRegen - Restores the video regen buffer from pVideoState
- ;
- ; Inputs: [di] - Points to a VideoState buffer containing the
- ; video state to be restored.
- ; [videoseg] - Segment of video regen buffer
- ; cx = video segment
- ;
- ; Outputs: NZ - if restore ok
- ; Z - if not restored
- ;
- ; The global memory used to save the regen buffer is freed.
- ; i.e. don't call RestoreRegen again with the save video state.
- ;
- ; Uses: es, si
- ;
- ;****
- cProc RestoreRegen,<NEAR>,<di>
- cBegin RestoreRegen
- mov es,cx
- mov cx,ax
- xor di,di
- rep movsw
- cEnd RestoreRegen
- ; SaveBitPlane - Saves a given number of words from a given bit plane.
- ;
- ; INPUT:
- ; ax - Number of words to save
- ; cl - Number of bit plane
- ; ds - is the segment address of the bit plane.
- ; es:di - where to save.
- ;
- ; OUTPUT:
- ; ES:DI - Points 1 word past the last saved word
- ;
- ; USES:
- ; SI
- ;
- cProc SaveBitPlane,<NEAR>
- cBegin SaveBitPlane
- xor si,si
- LabelNP <SaveBitPlane2>
- push ax ; Save count of words
- cCall MapBitPlane
- pop cx ; Restore
- rep movsw
- cEnd SaveBitPlane
- ;
- ; RestoreBitPlane - Restores a given number of words to a given bit plane.
- ;
- ; INPUT:
- ; ax - Number of words to restore
- ; cl - Number of bit plane
- ; es - is the segment address of the bit plane.
- ; ds:si - where to restore from.
- ;
- ; OUTPUT:
- ; ds:si - Points 1 word past the last restored word
- ;
- ; USES:
- ; DI
- ;
- cProc RestoreBitPlane,<NEAR>
- cBegin RestoreBitPlane
- xor di,di
- LabelNP <RestoreBitPlane2>
- push ax ; Save count of words
- cCall MapBitPlane
- pop cx ; Restore
- rep movsw
- cEnd RestoreBitPlane
- ;
- ; MapBitPlane - Maps the specified bit plane in for read/write
- ;
- ; INPUT:
- ; CL - the bit plane.
- ;
- cProc MapBitPlane,<NEAR>
- cBegin MapBitPlane
- mov al, 2 ; Set Map Mask register
- mov ah, 1
- shl ah, cl
- cCall SetEgaSequencer ; Only trashes DX,AX
- mov al, 4 ; Read Map Select
- mov ah,cl
- mov dx, 3ceH ; Graphics Controler Address Port
- cCall OutWord
- cEnd MapBitPlane
- cProc ClearBitPlanes,<NEAR>,<DI,SI>
- cBegin ClearBitPlanes
- mov si,di ; ds:si -> saved video state
- mov ax, 0a000H
- mov es,ax
- mov cl, 0 ; Map in bit plane 0
- cCall MapBitPlane
- xor di,di
- mov cx, [si].cwSwapVids
- xor ax,ax
- rep stosw
- mov cl, 1 ; Map in bit plane 1
- cCall MapBitPlane
- xor di,di
- mov cx, [si].cwSwapVids
- xor ax,ax
- rep stosw
- mov cl, 2 ; Map in bit plane 2
- cCall MapBitPlane
- xor di,di
- mov cx, 8*1024/2
- xor ax,ax
- rep stosw
- push ss
- pop ds ; Restore ds
- cEnd ClearBitPlanes
- ; SetEgaSequencer - Sends data to the Ega sequencer
- ;
- ; INPUT:
- ; AL - Sequencer register number
- ; 00 Reset
- ; 01 Clocking Mode
- ; 02 Map Mask
- ; 03 Character Map Select
- ; 04 Memory Mode
- ; AH - Data for the register
- ;
- cProc SetEgaSequencer,<NEAR>
- cBegin SetEgaSequencer
- mov dx, 3c4H ; Ega Sequencer Address Port
- cCall OutWord
- cEnd SetEgaSequencer
- ;
- ; This is just an `out dx,ax' kludge to ensure that it works on
- ; AT&T 6300
- ;
- cProc OutWord,<NEAR>
- cBegin OutWord
- out dx, al
- jmp short OUTWORD_1 ; I/O delay
- OUTWORD_1:
- inc dx
- mov al,ah
- out dx, al
- cEnd OutWord
- ;********** RestoreVidDataCsd ********
- ;* entry: pvidsRestoreData = near pointer to VIDS structure
- ;* lpwBuffer = buffer to save data (NULL => just clear screen)
- ;* * restore screen data from buffer
- ;* exit: n/a
- cProc RestoreVidDataCsd, <FAR, PUBLIC, ATOMIC>, <DS, SI, DI>
- parmDP pvidsRestoreData
- parmD lpwBuffer
- cBegin RestoreVidDataCsd
- mov di,pvidsRestoreData
- mov al, [di].modeVids
- cmp al, 3
- jb EgaRS_Text
- cmp al, 7
- je EgaRS_Text
- jb EgaRS_SimpleGraphics
- cmp al,8
- je EgaRs_Text
- cmp al,40h ;Olivetti ?
- je EgaRS_SimpleGraphics
- jmp short EgaRs_HardGraphics
- EgaRS_SimpleGraphics: ;mode 6
- push ax
- cCall ClearRegen
- pop ax
- EgaRS_Text: ; mode 2,3 and 7,8
- mov cx,0B800h
- cmp al, 7
- jb @F
- cmp al,8
- ja @F
- mov cx,0B000h
- @@:
- mov ax,[di].cwSwapVids
- lds si,lpwBuffer
- cCall RestoreRegen
- jmp RestoreVidsCsd_exit
- EgaRS_HardGraphics:
- cCall ClearRegen
- mov ax, 0a000H ; Address of bit planes
- mov es, ax
- lds si,lpwBuffer ;ds:[si] -> buffer
- mov bx,OFF_lpwDataCsd ;* Data in data segment
- test ss:[bx].fvmCurAdap, fvmMCGA
- jz EgaRs_NotMCGA
- mov di, 8000H
- mov cx, 2*1024
- rep movsw
- jmp short EgaRs_RestoreBitPlane2
- EgaRs_NotMCGA:
- mov cl, 0
- mov di,pvidsRestoreData
- mov ax, ss:[di].cwSwapVids
- cCall RestoreBitPlane
- mov cl, 1
- mov di,pvidsRestoreData
- mov ax, ss:[di].cwSwapVids
- cCall RestoreBitPlane
- EgaRs_RestoreBitPlane2:
- mov cl, 2
- mov ax, 4*1024
- cCall RestoreBitPlane
- ;
- ; The 8k bytes starting at 16k only gets trashed on 64k Ega cards
- ;
- mov bx,OFF_lpwDataCsd ;* Data in data segment
- test ss:[bx].fvmCurAdap, fvm64KEGA
- jz EgaRs_64plus
- mov cl, 2
- mov ax, 4*1024
- mov di, 16*1024
- cCall RestoreBitPlane2
- EgaRs_64Plus:
- mov ax,ss ; Restore ds
- mov ds,ax
- ;
- ; Set Map Mask register back to what BASIC expects
- ;
- mov ax, 0f02H ; Set map mask to 0fH
- cCall SetEgaSequencer
- jmp RestoreVidsCsd_exit
- EgaRs_HardNoRegen:
- cCall ClearBitPlanes
- RestoreVidsCsd_exit:
- cEnd RestoreVidDataCsd
- ;
- ; INT10Handler
- ; The BIOS INT10 (Video Sevices) is hooked to mirror the palette
- ; registers (so they can be restored).
- ;
- RegPtr cs_bx, cs, bx
- RegPtr es_bx, es, bx
- ;********** EnableVidsMonitorCsd ********
- ;* entry: fMonitorOn => monitor should be on
- ;* * enable/disable INT 10 monitor
- ;* exit: n/a
- cProc EnableVidsMonitorCsd, <FAR, PUBLIC, ATOMIC>,<di>
- parmW fMonitorOn
- cBegin EnableVidsMonitorCsd
- mov di,OFF_lpwDataCsd ;* Data in data segment
- cmp fMonitorOn,0
- je Unhook
- ; Hook int10 trap
- test ss:[di].fvmCurAdap, fvmEGA or fvmVGA or fvmMCGA
- jz @F
- mov [ColourPaletteYellow], 010100B ;brown
- @@:
- mov dx,drvOffset ColourPalette ; Default Enhanced colour
- test ss:[di].fvmCurAdap, fvmEGAM
- jz @F
- mov dx,drvOffset MonoPalette ; Default Monochrome palette
- @@:
- push cs
- pop ds ;now ds:dx points to source
- cCall CopyPalette ; Initialise the user palette
- push ss
- pop ds ;restore ds
- mov ax, 10H
- mov bx, drvOffset INT10Handler
- cCall HookVector,<ax, cs_bx>
- mov cs:[lpbBIOSINT10_Offset], ax
- mov cs:[lpbBIOSINT10_Segment], dx
- jmp EVM_Exit
- Unhook:
- ; Unhook int10 trap
- les bx, cs:[BIOSINT10]
- mov ax, 10H
- cCall HookVector,<ax,es_bx>
- xor ax,ax ; clear handler
- mov cs:[lpbBIOSINT10_Offset], ax
- mov cs:[lpbBIOSINT10_Segment], ax
- EVM_Exit:
- cEnd EnableVidsMonitorCsd
- ;***
- ;
- ; HookVector(vecNum, vector)
- ;
- ; Sets an interrupt vector and returns the old interrupt vector
- ;
- ; Inputs: vecNum - Which vector to set
- ; vector - address of the new vector
- ;
- ; Outputs: DX:AX == old interrupt vector
- ;
- ;****
- cProc HookVector,<NEAR,PUBLIC>,<DS>
- parmB vecNum
- parmD vector
- cBegin HookVector
- mov ah, 35H
- mov al, [vecNum]
- int 21H ; Get old vector
- push bx ; save for return
- push es ; save for return
- mov ah, 25H
- mov al, [vecNum]
- lds dx, [vector]
- int 21H ; Set new vector
- pop dx ; return the old vector
- pop ax ; return the old vector
- cEnd HookVector
- ;-------------------------------------------------------------------;
- INT10Handler:
- or ah,ah
- jz INT10SetMode
- cmp ah, 10h ;set palette regs ?
- je INT10SetPalette
- cmp ah, 0Bh
- je INT10SetCGABgPal
- INT10_Chain:
- jmp cs:[BIOSINT10]
- INT10SetMode:
- mov cs:[bCGABg],-1 ; bCGABg is now invalid.
- mov cs:[bCGAPal],-1 ; bCGAPal is now invalid.
- jmp short INT10_Chain
- public INT10SetCGABgPal ;UNDONE - Remove.
- INT10SetCGABgPal:
- or bh,bh ;Set Background colour?
- jnz @F ;brif no.
- ;* * assume BH == 1 for setting palette (if not CGA who cares anyway)
- mov cs:[bCGABg],bl
- jmp short INT10_Chain
- @@:
- mov cs:[bCGAPal],bl ;Must be setting CGA Palette
- jmp short INT10_Chain
- INT10SetPalette:
- push ax ; Save the regs we use
- or al,al
- jz INT10_SetIndividualPaletteReg ;ax = 1000h
- dec al
- jz INT10_SetOverscanReg ; 1001h
- dec al
- jz INT10_SetAllPaletteRegs ; 1002h
- INT10_Exit:
- pop ax
- jmp short INT10_Chain
- ;
- ; INT10_SetIndividualPaletteReg
- ; Sets the specified palette register
- ;
- ; BL - Is the register number (0-15)
- ; BH - Is the value
- ;
- INT10_SetIndividualPaletteReg:
- push bx
- xchg al, bh ; BH <-- 0, AL <-- value
- mov cs:[EgaPaletteMirror+bx], al
- pop bx
- jmp short INT10_SetPaletteCommon
- ;
- ; INT10_SetOverscanReg
- ; Sets the overscan register
- ;
- ; BH - Is the value.
- ;
- INT10_SetOverscanReg:
- mov cs:[OverScanMirror], bh
- jmp short INT10_Exit
- ;
- ; INT10_SetAllPaletteRegs
- ; Sets all the palette registers and the overscan register.
- ;
- ; ES:DX - points to table of values for the 16 palette registers and
- ; the overscan register
- ;
- INT10_SetAllPaletteRegs:
- push ds
- push es
- pop ds ; now ds:dx points to source
- call CopyPalette
- pop ds
- mov cs:[bCGAPal],-1 ; bCGAPal is now invalid.
- INT10_SetPaletteCommon:
- mov cs:[bCGABg],-1 ; bCGABg is now invalid.
- jmp short INT10_Exit
- ;
- ; Copy DS:DX to CS:EgaPaletteMirror
- ;
- cProc CopyPalette,<NEAR>,<SI,DI,CX,ES>
- cBegin CopyPalette
- push cs
- pop es
- mov si, dx
- mov di, DrvOffset EgaPaletteMirror
- mov cx, 17
- rep movsb
- cEnd CopyPalette
- ;***** UNDONE - HACK HACK HACK HACK HACK HACK HACK HACK HACK HACK
- ;***** UNDONE This piece of code is called directly by QB 4.5
- ;***** UNDONE It must not be called by QBJ
- ;***** UNDONE Remove this as soon as QB 4.5 ships.
- cProc SetBlinkBit,<FAR,PUBLIC>
- parmB fOn
- cBegin
- cmp [fOn],0
- je @F
- cCall EnableBlinkBit
- jmp short SBB_Exit
- @@:
- cCall DiddleBlinkBit
- SBB_Exit:
- cEnd