📄 common.asm
字号:
;* Return: Short integer with terminating char
StrInput PROC USES ds si,
Row:WORD,
Col:WORD,
Max:WORD,
Sptr:PBYTE
LoadPtr ds, si, Sptr ; DS:SI points to string
add Max, si
dec Max ; MAX now points to string limit
.WHILE 1 ; Get key until break or continue
loop1:
INVOKE StrWrite, ; Display input string
Row,
Col,
si
mov bx, si
mov dx, Col ; DL = cursor column
.WHILE (BYTE PTR [bx] != 0) ; Scan string for null terminator
inc bx ; Else try next character
inc dx ; and increment cursor column
.ENDW
; Set cursor position, pass row and column
INVOKE SetCurPos,
Row,
dx
call GetKey ; Poll for keypress
.BREAK .IF al == ESCAPE || \ ; Exit if ESC or
al == CR ; ENTER key
.IF al == BACKSP || \ ; If BACKSPACE or LEFT,
ah == LEFT ; handle it
cmp bx, si ; At first letter?
jbe loop1 ; Yes? Ignore BACKSPACE
dec bx ; No? Point to preceding char
dec dx ; Decrement column
mov BYTE PTR [bx], ' ' ; Blank char
push bx ; Preserve pointer
INVOKE StrWrite, ; Overwrite last char with blank
Row,
dx,
bx
pop bx
mov BYTE PTR [bx], 0 ; Make last char the new terminator
.CONTINUE ; Continue polling for keystrokes
.ENDIF
.CONTINUE .IF bx > Max ; Ignore key if too many letters
sub ah, ah
mov [bx], ax ; Store letter and null terminator
.ENDW
ret
StrInput ENDP
;* ClearBox - Clears portion of screen with specified fill attribute.
;*
;* Shows: BIOS Interrupt - 10h, Function 6 (Scroll Up)
;*
;* Params: Attr - Fill attribute
;* Row1 - Top screen row of cleared section
;* Col1 - Left column of cleared section
;* Row2 - Bottom screen row of cleared section
;* Col2 - Right column of cleared section
;*
;* Return: None
ClearBox PROC,
Attr:WORD,
Row1:WORD,
Col1:WORD,
Row2:WORD,
Col2:WORD
mov ax, 0600h ; Scroll service
mov bh, BYTE PTR Attr ; BH = fill attribute
mov ch, BYTE PTR Row1 ; CH = top row of clear area
mov cl, BYTE PTR Col1 ; CL = left column
mov dh, BYTE PTR Row2 ; DH = bottom row of clear area
mov dl, BYTE PTR Col2 ; DL = right column
int 10h ; Clear screen by scrolling up
ret
ClearBox ENDP
;* DisableCga - Disables CGA video by reprogramming the control register.
;*
;* Shows: Instructions - cli sti
;*
;* Params: None
;*
;* Return: None
DisableCga PROC USES ax cx dx ; Preserve registers
mov cx, -1 ; Set maximum loop count
mov dx, 03DAh ; Address of status register
.REPEAT
in al, dx ; Get video status
.UNTILCXZ !(al & 8) ; Until retrace end/timeout
cli ; Disallow interruptions
mov cx, -1 ; Reset loop count
.REPEAT
in al, dx ; Get video status
.UNTILCXZ al & 8 ; Until retrace start/timeout
sub dx, 2 ; DX = address of control reg
mov al, 1 ; Value to disable CGA video
out dx, al ; Disable video
sti ; Reenable interrupts
ret
DisableCga ENDP
;* EnableCga - Enables CGA video by reprogramming the control register.
;*
;* Params: None
;*
;* Return: None
EnableCga PROC USES ax dx es ; Preserve registers
sub ax, ax
mov es, ax ; Point ES to low memory
mov al, es:[0465h] ; Get former mode setting
mov dx, 03D8h ; Address of control register
out dx, al ; Enable video
ret
EnableCga ENDP
;* GetVer - Gets DOS version.
;*
;* Shows: DOS Function - 30h (Get MS-DOS Version Number)
;*
;* Params: None
;*
;* Return: Short integer of form (M*100)+m, where M is major
;* version number and m is minor version, or integer
;* is 0 if DOS version earlier than 2.0
GetVer PROC
mov ah, 30h ; DOS Function 30h
int 21h ; Get MS-DOS version number
.IF al == 0 ; If version, version 1
sub ax, ax ; Set AX to 0
.ELSE ; Version 2.0 or higher
sub ch, ch ; Zero CH and move minor
mov cl, ah ; version number into CX
mov bl, 100
mul bl ; Multiply major by 10
add ax, cx ; Add minor to major*10
.ENDIF
ret ; Return result in AX
GetVer ENDP
;* GetKey - Polls for keypress, calling Interrupt 28h while waiting. This
;* routine simulates Interrupt 16h, service 0, working directly with the
;* keyboard buffer. It should be used only by TSR programs.
;*
;* Bypassing BIOS to access the keyboard buffer is generally not recommended;
;* however, some applications incorrectly set up a handler for Interrupt 16h,
;* making them incompatible with TSRs that require keyboard input.
;*
;* Shows: BIOS keyboard data area
;*
;* Params: None
;*
;* Return: AH = scan code
;* AL = character
GetKey PROC USES ds bx
mov ax, 40h ; Point DS to data area (see
mov ds, ax ; "Keyboard Data Area" in Help)
mov ax, WORD PTR ds:[1Ah] ; AX = pointer to head of kb buffer
.REPEAT
int 28h ; Call Int 28h to signal idle state
cmp ax, WORD PTR ds:[1Ch] ; If head = tail, no key waiting,
.UNTIL !zero? ; so continue polling
mov bx, ax
mov ax, WORD PTR [bx] ; Get keypress from buffer head
inc bx ; Advance head position
inc bx
.IF bx >= WORD PTR ds:[82h] ; If advanced past end of buffer,
mov bx, WORD PTR ds:[80h] ; reset to beginning of buffer
.ENDIF
mov WORD PTR ds:[1Ah], bx ; Set new head pointer
ret
GetKey ENDP
END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -