📄 csd_ibm.asm
字号:
;*
;* CW : Character Windows
;*
;* csd_ibm.asm : contains default routines "IBM and compatible" routines
;*
;*****************************************************************************
ifndef ModeGetCur_NonDefault
;********** ModeGetCur *********
;* entry: n/a
;* * get current machine mode
;* exit: al = mode, ah = ayMac (or 0 if unknown)
cProc ModeGetCur, <NEAR, PUBLIC, ATOMIC>, <ES>
cBegin ModeGetCur
AssertEQ di,OFF_lpwDataCsd
mov dl,25 ;default 25 rows for CGA
cmp [di].fvmCurAdap,fvmCGA ;single card case
je @F
mov ax,40H
mov es,ax
mov dl,es:[0084H] ;* read BIOS rows
inc dl ;* dl = screen height
@@:
push bx
mov ah,0fh
int 10h ;* get current state, return al = mode
pop bx
mov ah,dl
cEnd ModeGetCur
endif ;* ModeGetCur_NonDefault
ifndef FvmGetCur_NonDefault
;*****************************************************************************
;********** FvmGetCur **********
;* entry: DS:DI => driver data
;* * if first time called, identify the current screen and set fvmCur
;* * subsequent calls will return fvmCur
;* * After this call: fvmCur is initialized
;* exit: AL == adapter (0 => no supported screen found)
;* AH == monitor
cProc FvmGetCur, <NEAR, PUBLIC, ATOMIC>
cBegin FvmGetCur
AssertEQ di,OFF_lpwDataCsd
mov al,[di].fvmCurAdap
mov ah,[di].fvmCurDisp
or ax,ax
jz init_get
jmp end_fvm_get
init_get: ;* initial get
push bp ; Int10's on some machines crunch bp.
mov ax,1A00h ; Test for MCGA and VGA.
int 10h
cmp al,1Ah
jne notPS2 ; Jump if not PS/2 (MCGA or VGA)
mov ax,fvmVGA
cmp bl,7
; je @F
je found_EGA
cmp bl,8
je found_EGA
; je @F
mov ax,fvmMCGA
cmp bl,0Bh
je @F
cmp bl,0Ch
je @F
xor ax,ax ;it's PS2, but currently inactive
jmp found_EGA ;go check for MDA/CGA
@@:
jmp found_fvm
notPS2:
mov ah,12h ;Test for EGA
mov bl,10h
int 10h
xor dx,dx ; see below (CGA detection)
cmp bl,10h
je notEGA
;
; Now, figure out if the EGA is the active display.
;
int 11H ;Get the BIOS equipment flags
and al, 00110000B ;
add al, 11010000B ;Carry flag is set only if
; a mono monitor is active.
sbb bh,0 ;Result is zero only if the
; ega is the active adapter
jnz notEGA
mov ax,fvmEGAM ; Test for a monochrome EGA display
cmp cl,0BH
je found_EGA
cmp cl,0AH
je found_EGA
cmp cl,04H
je found_EGA
cmp cl,05H
je found_EGA
mov ax,fvmEGA ; It's got more than 64K of RAM
cmp cl,3 ; HiRes display for settings 9 & 3
je found_EGA
cmp cl,9
je found_EGA
mov ax,fvm64KEGA ;UNDONE - Is this correct
found_EGA:
or bl,bl ; Test for 64K of EGA RAM
jnz @F
or ax,fvm64KEGA
@@:
mov dx,ax ; allow co-exist of EGA and CGA/MDA
notEGA:
; Test for MDA
push bx
mov ah,0fh
int 10h
pop bx
cmp al,7 ; 7 == monochrome text mode
jne @F
or dx,fvmMDA ; assume it's an MDA
mov ax,dx
jmp found_fvm
@@:
; Test for CGA (Note that Hercules will pass the CGA 6845 test so
; it is put after the MDA test.)
test dx,fvmEGAM
jz @F
; this test used in dual card config
cmp al,2 ;al from previous int10 call
je jCGA
cmp al,3
je jCGA
cmp al,6
je jCGA
mov al,dl
jmp found_fvm
@@:
push dx
mov dx,3D4h ;CGA's 6845 CRTC port 3D4h
mov al,0Fh
out dx,al ;register 0Fh (Cursor Low)
inc dx
in al,dx
mov ah,al ;preserve Cursor Low value in AH
mov al,66h ;send aributrary value
out dx,al
mov cx,7FFFh
L102: loop L102 ;delay
in al,dx
xchg ah,al
out dx,al ;restore Cursor Low
pop dx
xor ah,al ;AH=AL if CGA present
jnz @F
jCGA:
or dx,fvmCGA
mov ax,dx
jmp found_fvm
@@:
mov ax,dx
or ax,ax ; ax!=0 == card identified
jnz found_fvm
; If no display card identified then use default CGA
mov ax,fvmCGA
found_fvm: ;* al = fvm
AssertEQ [di].fvmCurAdap,0
mov dl,al
mov ah,0FAh ; Find out if there is an EGA.SYS
xor bx,bx ; installed
int 10h
or bx,bx
jz @F ; Jump if there isn't.
or dl,fvmMouse ; EGA.SYS is there (mirror registers)
@@:
mov al,dl
mov [di].fvmCurAdap,al
mov ah,0FFh ; assume no monitor chk
test al,fvmEGAM or fvmVGA or fvmMCGA or fvm64KEGA or fvmEGA
jz NoDispCheck
push bx ;* check monochrome
test al,fvmMCGA
jz @F
push ax ;save al (adapter info)
mov ax,1A00h ;read display combination code
int 10h
cmp al,1Ah
pop ax
jne ColorMode
mov ah,fvmECD or fvmCD
cmp bl,0Ch ;analog color ?
je ColorMode
mov ah,fvmMD ;analog mono (0Bh)
jmp ColorMode
@@:
;* EGA/VGA
test al,fvmCGA or fvmMDA ;MDA/EGA or CGA/EGA co-exist ?
jnz ColorMode ;if dual-card then enble all monitors
push ax ;save al (adapter info)
mov ah,12h
mov bl,10h
int 10h
pop ax
mov ah,fvmMD
or bh,bh ;0 = color, 1 = mono
jnz ColorMode
mov ah,fvmCD
and cl,00000110b ;switches 2 and 3
jnz ColorMode ;off?
mov ah,fvmECD ;on.
ColorMode:
pop bx
NoDispCheck:
mov [di].fvmCurDisp,ah ;
pop bp
end_fvm_get: ;* ax = fvm
cEnd FvmGetCur
;*****************************************************************************
endif ;* FvmGetCur_NonDefault
ifndef CoiCovFromFvm_NonDefault
;*****************************************************************************
;********** CoiCovFromFvm **********
;* entry: AL = fvm
;* * Produce coiMac, covMac for fvm (AL)
;* exit: AL = fvm, AH = covMac, DX = coiMac
cProc CoiCovFromFvm, <NEAR, PUBLIC, ATOMIC>
cBegin CoiCovFromFvm
xor ah,ah
xor dx,dx
test al,fvmMDA ;* monochrome coiMac = 0, covMac = 0
jnz @F
test al,fvmCGA ;* CGA coiMac = 0, covMac = 0
jnz @F
mov ah,64
test al,fvmVGA ;* EGA coiMac = 0, covMac = 64
jz @F
push ax
mov ax,101ah ;* read color page state
int 10h
pop ax
mov dx,64 ;* VGA coiMac = 64, covMac = 64?
or bl,bl
jz @F
mov ah,16 ;* VGA coiMac = 64, covMac = 16
@@:
cEnd CoiCovFromFvm
;*****************************************************************************
endif ;* CoiCovFromFvm_NonDefault
ifndef GetPFonts_NonDefault
;*****************************************************************************
;********** GetPFonts **********
;* entry: AL = ifont
;* * get font information
;* exit: DX:AX = lpbFont for first 128 characters
;* CX:BX = lpbFont for last 128 characters
cProc GetPFonts, <NEAR, PUBLIC, ATOMIC>
cBegin GetPFonts
cEnd GetPFonts
;*****************************************************************************
endif ;* GetPFonts_NonDefault
ifndef FInitCsd_NonDefault
;*****************************************************************************
;********** FInitCsd **********
;* * CSD entry point (see documentation for interface)
;* * Initialize the screen to the given mode
;* exit: AX != 0 if ok
cProc FInitCsd, <FAR, PUBLIC, ATOMIC>, <DI>
parmDP pinst
parmDP pinch
cBegin FInitCsd
mov di,OFF_lpwDataCsd ;* Data in data segment
;* * set mode
mov bx,pinst
mov [di].pinstDrv,bx
mov bx,ds:[bx].pdmInst ;* CS:BX => DM info
;* * copy mode info into driver globals
mov ax,cs:[bx].vparmCursOnDm
mov [di].vparmCursOn,ax ;initialize underline cursor
mov [di].vparmCursSize,ax
mov ax,cs:[bx].wExtraDm
mov [di].wExtra,ax
mov ah,0fh
int 10h ;* return al = mode
and al,7Fh ;* mask off clr vid buff bit.
mov cl,al ;* current mode
xor ah,ah ;* set mode
mov al,cs:[bx].modeDm
cmp al,cl
je @F ;* don't reset
int 10h ;* set mode
@@:
mov ax,1111h ;default 8x14 font
push bx
cmp cs:[bx].ayMacDm,25 ;80x25 text ?
mov bx,0E00h
je InitFont
inc al ;load 8x8 char into RAM
mov bh,08
InitFont:
int 10h
pop bx
;* * the INCH array already contains the standard Code Page 437
;* * character set, so it usually can be left the same.
;* * Do other diddling
cCall DiddleBlinkBit
mov ax,sp ;* success
cEnd FInitCsd
;*****************************************************************************
endif ;* FInitCsd_NonDefault
ifndef DiddleBlinkBit_NonDefault
;*****************************************************************************
;********** DiddleBlinkBit **********
cProc DiddleBlinkBit, <NEAR, ATOMIC, PUBLIC>, <DS>
cBegin DiddleBlinkBit
;* * Diddle blink bit via BIOS call (or diddle CGA bit)
mov bx,OFF_lpwDataCsd ;* Data in data segment
test [bx].fvmCurAdap, fvmCGA or fvmMDA
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -