📄 saveega.asm
字号:
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
ifndef KANJI
;***** 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
endif ; !KANJI
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -