📄 setmode.asm
字号:
; TITLE SETMODE - Mode oriented routines for MSHERC.
;***
;SETMODE
;
; Copyright <C> 1987, 1988, Microsoft Corporation
;
;Purpose:
; Set graphics mode, get video state and check hardware card
; status.
;
;******************************************************************************
include hgcdefs.inc
code segment para public 'code'
assume cs:code,ds:code
Public GetVideoState
Public SetGraphicsMode
Public ReturnHGCStatus
Public GetHGCStatus
Extrn ConfigMode:byte ;[1] either FULL or HALF mode
Extrn UnHookFlag:byte
Extrn DMC_Save:byte ;temp variable for the DMC_Port value
Extrn HardGraphVals:byte ;Start of Graphics Mode Hardware Reg data
Extrn Pause:near ;Procedure that counts vsync pulses, and
;in effect executes a pause...
;-------------------------------------------------------------------------------
; F CURRENT VIDEO STATE
; AL <= Current Mode (8)
; AH <= # Character Columns
; BH <= Active Display Page (currently always 0)
;-------------------------------------------------------------------------------
GetVideoState proc near
mov ah,es:BIOSCOLS
mov al,HGCGrMode
mov FunData.FunAX,ax
mov al,es:BIOSPAGE
mov byte ptr FunData.FunBX[1],al
ret
GetVideoState endp
;-------------------------------------------------------------------------------
; 0 SET MODE
; AL => mode #8, bit 7, when set, prevents regen buffer clear.
; Pass on all but request for Hercules graphics mode.
; Trap ALL functions (except EGAINT10) while in graphics mode.
; This function should be ignored if BIOS equipment variable not
; set for B/W.
;-------------------------------------------------------------------------------
SetGraphicsMode proc near
mov ah,es:BIOSEQUIP
and ah,00110000B ;is B/W mode
cmp ah,00110000B
je StrtGMode ;go if OK
ret ;no action if not B/W (mono)
StrtGMode:
mov DMC_Save,GraphicsOn+GraphicsPage0+ScreenOff
push ax ;save bit 7 (regen clear flag)
xor ax,ax
mov byte ptr es:BIOSMODE,8 ;set bios mode number
mov word ptr es:BIOSCOLS,80 ;set # text columns
mov byte ptr es:BIOSPAGE,al ;default page 0
mov word ptr es:BIOSCURS,ax ;clear page 0 cursor
cmp [ConfigMode],FULL ;[1] make sure FULL mode
jne SkipPage1 ;[1] brif not
mov word ptr es:BIOSCURS+2,ax ;clear page 1 cursor
SkipPage1: ;[1]
mov word ptr es:BIOSSTART,ax ;set buffer start
mov word ptr es:BIOSLEN,GraphBufferSize ; and length
mov UnHookFlag,al ;Clear the unhook flag
FinGraphicsEntry:
;------Program the 6845 for Graphics Mode-------
mov si,offset HardGraphVals ;6845 Graphics values
mov cx,CRTValsCnt ;# of data values to program
mov ah,Register0 ;Start with 6845 register 0
cli ;Disable interrupts
mov dx,DMC_Port ;Use Display Mode Control Port
mov al,DMC_Save ;Fetch the DMC value
out dx,al ;Disable video
Call ProgramRegisters ;Program the 6845 registers
mov dx,Config_Port ;Use the configuration port
mov al,[ConfigMode] ;[1] Fetch the config. value
out dx,al ;Set Configuration Port
;--------Wait for screen to settle-------
mov cx,delay
Call Pause
;-------Clear the screen------
pop ax ;restore bit 7 (regen clear flag)
test al,80H ;bit 7 set to preserve regen buffer?
jnz DontClear
mov ax,Scr0_Buf_Seg ;Assume Page 0
push es
mov es,ax ;Pnt es to graphics page
xor di,di ;Point di to beg. of buffer offset
xor ax,ax
mov cx,GraphBufferSize ;Size of both graphics pages in words
cmp [ConfigMode],FULL ;[1] make sure in FULL mode
je clearit ;[1] brif so
shr cx,1 ;[1] only clear one page if HALF mode
clearit: ;[1]
rep stosw ;Store blanking value in graphics buf
pop es
DontClear:
;------Set the font character height and width --------
mov dx,DMC_Port ;Use the Display Mode Control Port
mov al,DMC_Save ;Fetch the video-off value
or al,ScreenOn ;Set the video-on bit
mov DMC_Save,al ;Save it
out dx,al ;Set DMC Port and turn on screen
ret ;Finished Graphics Mode Set
SetGraphicsMode endp
ReturnHGCStatus proc near
;-------Adjust pointers--------
call GetHGCStatus
mov word ptr FunData.FunDX,dx ;[1] Return to user
ret
ReturnHGCStatus endp
GetHGCStatus proc near
mov dx,DS_Port
in al,dx
and al,IDMask
cmp al,HGC222ID ;Is this a 222?
jnz Chk112 ;No, check for a 112
mov dl,2 ;Return to user
jmp FiniStatReq ;Finished
Chk112:
cmp al,HGC112ID ;Is this a 112?
jnz Chk102 ;No, check for a 102
mov dl,1 ;Return to user
jmp FiniStatReq ;Finished
Chk102:
MOV DX,3BAH ; Bit 7 at port 3BA changes pretty often
MOV CX,0FFFFH ; on a Hercules so check it to see if
IN AL,DX ; it flips.
MOV BL,AL
tst102:
IN AL,DX ; Current value of Port 3BA
XOR AL,BL ; XOR to see if it changes
TEST AL,80H ; Did it?
JNZ got102 ; Yes, we must have a Hercules
LOOP tst102 ; No, try again
mov dx,-1 ;[2] Indicate non-Hercules
JMP SHORT FiniRetDef ;[2] If we didn't get it, give up
got102:
xor dl,dl ;Indicate 102
FiniStatReq:
mov dh,[ConfigMode] ;[1] return FULL = 1 or HALF = 0
shr dh,1 ;[1]
FiniRetDef: ;[2]
ret ;Finished HGC Status Request
GetHGCStatus endp
;-----------------------------------------------------------------------------;
; ProgramRegisters
;
; Loads a consecutive set of registers with the values from the
; specified table via the Index/Data Ports.
;
; Entry: ds:si = offset of data table
; ah = 1st register number
; cx = # registers to load
;
; Uses: ax,cx,dx,si
;
; **Notes: This routine is practical for programming 3 or more data
; values
;
;-----------------------------------------------------------------------------;
ProgramRegisters proc near
cli ;Disable interrupts
ProgRegs:
mov dx,IndexReg ;Use Index Register
mov al,ah ;Get Desired Register Number
out dx,al ;Point to Register
inc dx ;Use Data Port
lodsb ;Fetch data value from table
out dx,al ;Output data value
inc ah ;Increment to next register number
loop ProgRegs ;Loop to output next data value
sti ;Enable interrupts
ret ;Finished
ProgramRegisters endp
code ends
end
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -