📄 common.asm
字号:
.MODEL small, pascal
INCLUDE demo.inc
.DATA
vconfig VIDCONFIG <> ; Global video configuration structure
.CODE
;* GetVidConfig - Determines current video configuration and initializes
;* the vconfig structure.
;*
;* Shows: BIOS Interrupt - 10h, Function 0 (Set Video Mode)
;* 10h, Function 0Fh (Get Current Video Mode)
;* 10h, Function 1Ah (Video Display Combination)
;*
;* Uses: vconfig - Video configuration structure, declared in the
;* DEMO.INC include file.
;*
;* Params: None
;*
;* Return: None
GetVidConfig PROC
mov ax, 1A00h ; Get video info for VGA
int 10h
chkVGA:
cmp al, 1Ah ; Is VGA or MCGA present?
jne chkEGA ; No? Then check for EGA
cmp bl, 2 ; If VGA exists as secondary adapter,
je isCGA ; check for CGA and mono as primary
jb isMONO
cmp bl, 5 ; If EGA is primary, do normal
jbe chkEGA ; EGA checking
chkMCGA:
mov vconfig.adapter, MCGA ; Yes? Assume MCGA
mov vconfig.display, COLOR
cmp bl, 8 ; Correct assumption?
ja gotmode ; Yes? Continue
isVGA:
mov vconfig.adapter, VGA ; Assume it's VGA color
je gotmode ; Yes? Continue
mov vconfig.display, MONO ; No? Must be VGA mono
jmp gotmode ; Finished with VGA, so jump
chkEGA:
mov ah, 12h ; Call EGA status function
mov bl, 10h
sub cx, cx ; Clear status bits
int 10h
jcxz chkCGA ; If CX is unchanged, not EGA
isEGA:
mov vconfig.adapter, EGA ; Set structure fields for EGA
mov vconfig.display, MONO ; Assume EGA mono
or bh, bh ; Correct assumption?
jnz gotmode ; Yes? Continue
mov vconfig.display, COLOR ; No? Must be EGA color
jmp gotmode ; Finished with EGA, so jump
chkCGA:
int 11h ; Get equipment list
and al, 30h ; If bits 4-5 set, monochrome
cmp al, 30h ; Monochrome text mode?
je isMONO ; Yes? Continue
isCGA:
mov vconfig.adapter, CGA ; No? Must be CGA
mov vconfig.display, COLOR
jmp gotmode
isMONO:
mov vconfig.adapter, MDA ; Set MONO
mov vconfig.display, MONO
gotmode:
mov ah, 0Fh
int 10h ; Get current mode
mov vconfig.mode, al ; Record mode
mov vconfig.dpage, bh ; and current page
mov al, vconfig.display ; Multiply display value
cbw ; (which is either 0 or 1)
mov bx, 800h ; by 800h, then add to 0B000h
mul bx ; for segment address of
add ax, 0B000h ; video buffer
add ah, vconfig.dpage ; Adding display page gives
mov vconfig.sgmnt, ax ; address of current page
sub ax, ax
mov es, ax
mov al, es:[44Ah] ; Get number of display cols
mov vconfig.cols, al ; Store in structure
mov vconfig.rows, 24 ; Assume bottom row # = 24
cmp vconfig.adapter, EGA ; EGA or VGA?
jl exit ; No? Exit
mov ax, 1130h ; Yes? Request character info
sub bh, bh ; Set BH to valid value
push bp ; BP will change, so save it
int 10h ; Get number of rows/screen
mov vconfig.rows, dl ; Keep in structure
pop bp ; Restore BP
exit:
ret
GetVidConfig ENDP
;* GetCurPos - Gets current cursor position.
;*
;* Uses: vconfig - Video configuration structure (initialized
;* by calling the GetVidConfig procedure)
;*
;* Params: None
;*
;* Return: Short integer with high byte = row, low byte = column
GetCurPos PROC USES bx dx
mov ah, 3 ; Function 3
mov bh, vconfig.dpage
int 10h ; Get cursor position
mov ax, dx
ret
GetCurPos ENDP
;* SetCurPos - Sets cursor position.
;*
;* Shows: BIOS Interrupt - 10h, Function 2 (Set Cursor Position)
;*
;* Uses: vconfig - Video configuration structure (initialized
;* by calling the GetVidConfig procedure)
;*
;* Params: Row - Target row
;* Col - Target column
;*
;* Return: None
SetCurPos PROC USES bx dx,
Row:WORD,
Col:WORD
mov dh, BYTE PTR Row ; DH = row
mov dl, BYTE ptr Col ; DL = column
mov ah, 2 ; Function 2
mov bh, vconfig.dpage ; Current page
int 10h ; Set cursor position
ret
SetCurPos ENDP
;* StrWrite - Writes ASCIIZ string to video memory at specified row/column.
;*
;* Shows: Instructions - lodsb stosb
;*
;* Uses: vconfig - Video configuration structure (initialized
;* by calling the GetVidConfig procedure)
;*
;* Params: Row - Row coordinate
;* Col - Column coordinate
;* Sptr - Pointer to string
;*
;* Return: None
StrWrite PROC USES ds si di,
Row:WORD,
Col:WORD,
Sptr:PTR BYTE
GetVidOffset Row, Col ; Get video offset for these coords
mov di, ax ; Copy to DI
LoadPtr ds, si, Sptr ; DS:SI points to string
mov es, vconfig.sgmnt ; ES:DI points to video RAM
.WHILE 1 ; Loop forever (or until break)
lodsb ; Get 1 character from string
.BREAK .IF al == 0 ; Quit if null terminator
; For CGA systems, StrWrite waits for the video to begin a horizontal
; retrace before writing a character to memory. This avoids the problem
; of video snow inherent with some (though not all) color/graphics adapters.
; It also demonstrates a somewhat different approach to the problem than the
; one taken in the WinOpen and WinClose procedures.
.IF vconfig.adapter != CGA ; If not CGA, skip this step
push ax ; Save character
mov dx, 3DAh ; Address of status register
cli ; Disallow interruptions
.REPEAT
in al, dx ; Read current video status
.UNTIL !(al & 1) ; Until horizontal retrace done
.REPEAT
in al, dx ; No? Read status again
.UNTIL al & 1 ; Until retrace starts
pop ax ; Recover character
.ENDIF ; CGA only
stosb ; Write char to video buffer
sti ; Reenable interrupts in case CGA
inc di ; Skip attribute byte
.ENDW
ret
StrWrite ENDP
;* StrInput - Gets input string from keyboard using BIOS. Signals idle
;* state by calling interrupt 28h while polling for keypress, making
;* the procedure useful in TSR programs. Terminates when ENTER or ESC
;* keys pressed.
;*
;* Shows: DOS interrupt - Interrupt 28h (DOS Idle Interrupt)
;*
;* Params: Row - Row coordinate
;* Col - Column coordinate
;* Max - Maximum allowable string length
;* Sptr - Pointer to string
;*
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -