📄 vswap.pas
字号:
unit VSwap;
{$O+,F+,S-}
interface
const
smFont8x8 = $100;
smGraphics = $200;
smNoClearScreen = $8000;
type
ScreenType = (scUser, scTurbo, scCheck);
const
InitMode: Byte = 0;
Ega43Lines: Boolean = False;
DualMonitor: Boolean = False;
EgaPaletteSave: Boolean = False;
GraphicsSwap: Boolean = False;
VUseEms: Boolean = True;
SnowCheck: Boolean = True;
ScreenSize: Word = 0;
CursorPos: Word = 0;
function GetMode: Word;
procedure SetMode(Mode: Word);
procedure SwapScreen(Screen: ScreenType; SaveMouse: Boolean);
procedure GetUserScreen(X, Y: Word; var Buf; Size: Word);
procedure ShowTurboScreen;
procedure CheckUserScreen;
procedure ShowUserScreen;
procedure InitVSwap;
procedure DoneVSwap;
implementation
uses Drivers, Mem, Memory;
const
Mda = $01;
Cga = $02;
Ega = $04;
MCga = $08;
Vga = $10;
type
TVideoState = record
Equipment: Word;
VideoMode: Byte;
NumCols: Word;
RegenSize: Word;
StartAddr: Word;
CursorPos: array[0..7] of Word;
CursorShape: Word;
ActivePage: Byte;
Addr6845: Word;
CrtMode: Byte;
CrtPalette: Byte;
EgaRows: Byte;
EgaBytesPerChar: Word;
EgaMisc: array[0..3] of Byte;
end;
TEgaPalette = array[0..17] of Byte;
TSavedScreen = record
Mode: Word;
VideoState: TVideoState;
Palette: TEgaPalette;
MouseState: Pointer;
end;
PEgaPtrs = ^TEgaPtrs;
TEgaPtrs = array[0..6] of Pointer;
const
CurrentScreen: ScreenType = scUser;
FirstOn: Boolean = True;
ModeChanged: Boolean = False;
CgaSwapAreaSize: Word = 0;
EgaSwapAreaSize: Word = 0;
SaveEgaPtrs: PEgaPtrs = nil;
var
MonitorTypes: Word;
MouseSaveSize: Word;
CgaSwapArea: Pointer;
EgaSwapArea: Pointer;
Screens: array[ScreenType] of TSavedScreen;
NewEgaPtrs: TEgaPtrs;
NewArea: array[0..255] of Byte;
Addr6845: Word absolute $40:$63;
EgaPtrs: PEgaPtrs absolute $40:$A8;
procedure Int10; near; assembler;
asm
PUSH ES
PUSH DI
PUSH SI
PUSH BP
INT 10H
POP BP
POP SI
POP DI
POP ES
end;
procedure Check6845; near; assembler;
asm
PUSH AX
MOV AL,0FH
OUT DX,AL
INC DX
IN AL,DX
PUSH AX
MOV AL,66H
OUT DX,AL
MOV CX,256
@@1: LOOP @@1
IN AL,DX
CMP AL,66H
POP AX
OUT DX,AL
POP AX
end;
procedure DetectMonitors; near; assembler;
const
MonitorCodes: array[0..13] of Byte=
(0, Mda, Cga, 0, Ega, Ega, 0, Vga, Vga, 0, MCga, MCga, MCga, 0);
asm
MOV AX,40H
MOV ES,AX
MOV AX,1A00H
CALL Int10
CMP AL,1AH
JNE @@1
XCHG AX,BX
MOV BX,OFFSET MonitorCodes
XLAT
XCHG AL,AH
XLAT
CMP ES:49H.Byte,smMono
JE @@4
XCHG AL,AH
JMP @@4
@@1: MOV BL,10H
MOV AH,12H
CALL Int10
XOR AX,AX
CMP BL,10H
JE @@2
MOV AL,Ega
OR BH,BH
JZ @@2
XCHG AL,AH
@@2: OR AL,AL
JNZ @@3
MOV DX,3D4H
CALL Check6845
JNZ @@3
MOV AL,Cga
@@3: OR AH,AH
JNZ @@4
MOV DX,3B4H
CALL Check6845
JNZ @@4
MOV AH,Mda
@@4: MOV MonitorTypes,AX
end;
function GetMonitorTypes: Word; assembler;
asm
MOV AX,40H
MOV ES,AX
MOV AX,MonitorTypes
CMP ES:49H.Byte,smMono
JNE @@1
XCHG AL,AH
@@1:
end;
function GetMode: Word; assembler;
asm
MOV AX,40H
MOV ES,AX
MOV AL,ES:49H
MOV AH,0
MOV DX,MonitorTypes
CMP AL,smCO80+1
JB @@1
CMP AL,smMono
JNE @@2
XCHG DL,DH
TEST DL,Mda
JZ @@1
TEST ES:65H.Byte,2
JZ @@2
MOV AH,smGraphics SHR 8
JMP @@2
@@1: TEST DL,Ega+Vga
JZ @@2
CMP ES:84H.Byte,24
JE @@2
MOV AH,smFont8x8 SHR 8
@@2:
end;
procedure DoSetMode; near; assembler;
const
CrtData: array[0..11] of Byte =
($35, $2D, $2E, $07, $5B, $02, $57, $57, $02, $03, $00, $00);
ModeSelect: array[0..8] of Byte =
($2C, $28, $2D, $29, $2A, $2E, $1E, $29, $0B);
ScrWidth: array[0..8] of Byte =
(40, 40, 80, 80, 40, 40, 80, 80, 80);
RegenSize: array[0..8] of Byte =
($08, $08, $10, $10, $40, $40, $40, $10, $80);
asm
TEST AH,smNoClearScreen SHR 8
JZ @@1
TEST DL,Ega+MCga+Vga
JZ @@2
OR AL,80H
@@1: MOV AH,0
CALL Int10
AND ES:87H.Byte,7FH
JMP @@9
@@2: OR ES:87H.Byte,8
MOV BL,AL
XOR BH,BH
MOV DI,49H
CLD
STOSB
MOV CX,1DH
XOR AL,AL
REP STOSB
PUSH DS
TEST AH,smGraphics SHR 8
JZ @@3
MOV DX,3BFH
MOV AL,1
OUT DX,AL
MOV BL,8
MOV SI,OFFSET CrtData
MOV CX,12
JMP @@4
@@3: XOR AL,AL
MOV DX,3D4H
XOR SI,SI
MOV DS,SI
LDS SI,DS:(1DH*4)
MOV CX,16
CMP BL,smBW80
JB @@5
ADD SI,CX
CMP BL,smCO80+1
JB @@5
ADD SI,CX
CMP BL,smMono
JB @@5
ADD SI,CX
@@4: MOV AL,1
MOV DX,3B4H
@@5: MOV ES:Addr6845,DX
ADD DL,4
OUT DX,AL
SUB DL,4
MOV AX,[SI+10]
XCHG AL,AH
MOV ES:60H,AX
PUSH BX
XOR BX,BX
@@6: MOV AL,BL
OUT DX,AL
JMP @@7
@@7: MOV AL,[BX+SI]
INC DX
OUT DX,AL
DEC DX
INC BX
LOOP @@6
POP BX
POP DS
MOV AL,ModeSelect.Byte[BX]
MOV ES:65H,AL
ADD DL,4
OUT DX,AL
MOV AL,30H
CMP BL,6
JNE @@8
MOV AL,3FH
@@8: MOV ES:66H,AL
INC DX
OUT DX,AL
MOV AL,ScrWidth.Byte[BX]
XOR AH,AH
MOV ES:4AH,AX
XOR AL,AL
MOV AH,RegenSize.Byte[BX]
MOV ES:4CH,AX
@@9:
end;
procedure SetMode(Mode: Word); assembler;
asm
MOV AX,40H
MOV ES,AX
MOV AX,Mode
MOV CL,20H
MOV DX,MonitorTypes
CMP AL,smMono
JNE @@1
MOV CL,30H
XCHG DL,DH
@@1: AND ES:10H.Byte,0CFH
OR ES:10H,CL
AND ES:87H.Byte,0FEH
PUSH AX
CALL DoSetMode
POP AX
TEST AH,smFont8x8 SHR 8
JZ @@2
MOV AX,1112H
MOV BL,0
CALL Int10
CMP ES:84H.Byte,42
JNE @@2
OR ES:87H.Byte,1
MOV AH,1
MOV CX,600H
CALL Int10
MOV AH,12H
MOV BL,20H
CALL Int10
@@2:
end;
procedure SaveVideoState(var VS: TVideoState); near; assembler;
asm
PUSH DS
LES DI,VS
MOV SI,40H
MOV DS,SI
CLD
MOV SI,10H
MOVSW
MOV SI,49H
MOV CX,1EH
REP MOVSB
MOV SI,84H
MOV CX,7
REP MOVSB
POP DS
end;
procedure RestoreVideoState(var VS: TVideoState); near; assembler;
asm
PUSH DS
LDS SI,VS
MOV DI,40H
MOV ES,DI
CLD
MOV DI,10H
MOVSW
MOV DI,49H
MOV CX,1EH
REP MOVSB
MOV DI,84H
MOV CX,7
REP MOVSB
POP DS
MOV DX,ES:Addr6845
ADD DL,4
MOV AL,ES:65H
OUT DX,AL
CMP ES:49H.Byte,4
JAE @@1
MOV AL,ES:62H
MOV AH,5
CALL Int10
@@1: MOV BL,ES:62H
XOR BH,BH
SHL BX,1
MOV DX,ES:50H[BX]
MOV BH,ES:62H
MOV AH,2
CALL Int10
MOV CX,ES:60H
MOV AH,1
CALL Int10
end;
procedure SaveEgaPalette(var Buf: TEgaPalette); near; assembler;
asm
PUSH DS
LES DI,Buf
CLD
CMP EgaPaletteSave,0
JE @@3
MOV AX,MonitorTypes
MOV DX,40H
MOV DS,DX
CMP DS:49H.Byte,smMono
JNE @@1
MOV AL,AH
@@1: TEST AL,Ega
JZ @@2
LDS SI,DS:EgaPtrs
LDS SI,[SI+4]
MOV AX,DS
OR AX,SI
JZ @@3
MOV AL,1
STOSB
MOV CX,17
REP MOVSB
JMP @@4
@@2: TEST AL,Vga
JZ @@3
MOV AL,1
STOSB
MOV DX,DI
MOV AX,1009H
CALL Int10
JMP @@4
@@3: MOV CX,18
XOR AL,AL
REP STOSB
@@4: POP DS
end;
procedure RestoreEgaPalette(var Buf: TEgaPalette); near; assembler;
asm
LES BX,Buf
CMP ES:[BX].Byte,0
JE @@1
MOV AX,1002H
LEA DX,[BX+1]
CALL Int10
@@1:
end;
procedure CalcStep; near; assembler;
asm
CMP GraphicsSwap,1
JB @@2
MOV AX,40H
MOV ES,AX
MOV AL,ES:49H
CMP AL,0DH
JB @@2
CMP AL,14H
CMC
JC @@2
XOR BX,BX
CMP AL,0FH
JB @@1
TEST MonitorTypes,Ega+Ega*256
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -