⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 misc.asm

📁 这是一些例程
💻 ASM
📖 第 1 页 / 共 3 页
字号:
        .modeL  small, pascal, os_dos
        INCLUDE demo.inc

        .DATA
_psp    PSEG    ?               ; Segment of PSP
_env    PSEG    ?               ; Segment of environment

        .CODE

;* WinOpen - Saves portion of screen to allocated memory, then opens a window
;* with specified fill attribute. See also the WinClose procedure.
;*
;* Shows:   DOS Function - 48h (Allocate Memory Block)
;*          Instructions - movsw      stosw     rep
;*
;* Uses:    vconfig - Video configuration structure (initialized
;*          by calling the GetVidConfig procedure)
;*
;* Params:  Row1 - Row at top of window
;*          Col1 - Column at left edge of window
;*          Row2 - Row at bottom of window
;*          Col2 - Column at right edge of window
;*          Attr - Fill attribute for window
;*
;* Return:  Short integer with segment address of allocated buffer, or
;*          0 if unable to allocate memory

WinOpen PROC USES ds di si,
        Row1:WORD, Col1:WORD, Row2:WORD, Col2:WORD, Attr:WORD

        GetVidOffset Row1, Col1         ; Get offset in video segment
        mov     si, ax                  ; SI = video offset for window
        mov     bx, Row2
        sub     bx, Row1
        inc     bx                      ; BX = number of window rows
        mov     cx, Col2
        sub     cx, Col1
        inc     cx                      ; CX = number of columns

        mov     ax, cx                  ; Compute number of video
        mul     bl                      ;   cells in window
        add     ax, 3                   ; Plus 3 additional entries
        shr     ax, 1                   ; Shift right 3 times to
        shr     ax, 1                   ;   multiply by 2 bytes/cell,
        shr     ax, 1                   ;   divide by 16 bytes/paragraph
        inc     ax                      ; Add a paragraph
        push    bx                      ; Save number of rows
        mov     bx, ax                  ; BX = number of paragraphs
        mov     ah, 48h                 ; Request DOS Function 48h
        int     21h                     ; Allocate Memory Block
        pop     bx

        .IF     carry?                  ; If unsuccessful,
        sub     ax, ax                  ;   return null pointer
        .ELSE
        mov     es, ax                  ; Point ES:DI to allocated
        sub     di, di                  ;   buffer
        mov     ax, si
        stosw                           ; Copy video offset to buffer
        mov     ax, bx
        stosw                           ; Number of rows to buffer
        mov     ax, cx
        stosw                           ; Number of cols to buffer
        mov     ax, 160                 ; Number of video cells/row
        mov     ds, vconfig.sgmnt       ; DS = video segment

        .REPEAT
        push    si                      ; Save ptr to start of line
        push    cx                      ;   and number of columns

; For CGA adapters, WinOpen avoids screen "snow" by disabling the video prior
; to block memory moves, then reenabling it. Although this technique can
; result in brief flickering, it demonstrates the fastest way to access a
; block in the CGA video buffer without causing display snow. See also the
; StrWrite procedure for another solution to the problem of CGA snow.

        .IF     vconfig.adapter == CGA  ; If not CGA adapter,
        INVOKE  DisableCga              ;   disable video
        .ENDIF

        rep     movsw                   ; Copy one row to buffer

        .IF     vconfig.adapter == CGA  ; If CGA adapter,
        INVOKE  EnableCga               ;   reenable CGA video
        .ENDIF
        pop     cx                      ; Recover number of columns
        pop     si                      ;   and start of line
        add     si, ax                  ; Point to start of next line
        dec     bx                      ; Decrement row counter
        .UNTIL  zero?                   ; Until no rows remain

; Screen contents (including display attributes) are now copied to buffer.
; Next open window, overwriting the screen portion just saved.

        mov     ax, 0600h               ; Scroll service
        mov     bh, BYTE PTR Attr       ; Fill attribute
        mov     cx, Col1                ; CX = row/col for upper left
        mov     ch, BYTE PTR Row1
        mov     dx, Col2                ; DX = row/col for lower right
        mov     dh, BYTE PTR Row2
        int     10h                     ; Blank window area on screen
        mov     ax, es                  ; Return address of allocated
        .ENDIF                          ;   segment
        ret

WinOpen ENDP


;* WinClose - "Closes" a window previously opened by the WinOpen procedure.
;* See also the WinOpen procedure.
;*
;* Shows:   DOS Function - 49h (Release Memory Block)
;*          Instructions - lodsw
;*          Operators - : (segment override)     SEG
;*
;* Uses:    vconfig - Video configuration structure (initialized
;*          by calling the GetVidConfig procedure)
;*
;* Params:  Adr - Segment address of buffer that holds screen contents
;*                saved in WinOpen procedure
;*
;* Return:  None

WinClose PROC USES ds di si,
        Adr:WORD

        mov     ds, Adr                 ; DS:SI points to buffer
        sub     si, si
        lodsw
        mov     di, ax                  ; DI = video offset of window
        lodsw
        mov     bx, ax                  ; BX = number of window rows
        lodsw
        mov     cx, ax                  ; CX = number of columns

        mov     ax, SEG vconfig.sgmnt
        mov     es, ax                  ; Point ES to data segment
        push    es:vconfig.sgmnt
        pop     es                      ; ES = video segment
        mov     ax, 160                 ; Number of video cells/row

        .REPEAT
        push    di                      ; Save ptr to start of line
        push    cx                      ;   and number of columns

; Disable CGA video prior to memory move to avoid screen snow. (See the
; WinOpen and StrWrite procedures for further discussions on CGA snow.)

        .IF     vconfig.adapter == CGA  ; If CGA adapter,
        INVOKE  DisableCga              ;   disable video
        .ENDIF

        rep     movsw                   ; Copy one row to buffer

        .IF     vconfig.adapter == CGA  ; If CGA adapter,
        INVOKE  EnableCga               ;   reenable CGA video
        .ENDIF
        pop     cx                      ; Recover number of columns
        pop     di                      ;   and start of line
        add     di, ax                  ; Point to start of next line
        dec     bx                      ; Decrement row counter
        .UNTIL  zero?                   ;   until no rows remain

        mov     ah, 49h                 ; Request DOS Function 49h
        mov     es, Adr
        int     21h                     ; Release Memory Block
        ret

WinClose ENDP


;* SetCurSize - Sets cursor size.
;*
;* Shows:   BIOS Interrupt - 10h, Function 1 (Set Cursor Type)
;*
;* Params:  Scan1 - Starting scan line
;*          Scan2 - Ending scan line
;*
;* Return:  None

SetCurSize PROC,
        Scan1:WORD, Scan2:WORD

        mov     cx, Scan2               ; CL = ending scan line
        mov     ch, BYTE PTR Scan1      ; CH = starting scan line
        mov     ah, 1                   ; Function 1
        int     10h                     ; Set Cursor Type
        ret

SetCurSize ENDP


;* GetCurSize - Gets current cursor size.
;*
;* Shows:   BIOS Interrupt - 10h, Function 3 (Get Cursor Position)
;*
;* Uses:    vconfig - Video configuration structure (initialized
;*          by calling the GetVidConfig procedure)
;*
;* Params:  None
;*
;* Return:  Short integer with high byte = top scan line,
;*                             low byte  = bottom scan line

GetCurSize PROC

        mov     ah, 3                   ; Function 3
        mov     bh, vconfig.dpage
        int     10h                     ; Get Cursor Position
        mov     ax, cx                  ; Return cursor size
        ret

GetCurSize ENDP


;* GetShift - Gets current shift status. Checks for extended keyboard,
;* and, if available, returns additional shift information.
;*
;* Shows:   BIOS Interrupt - 16h, Functions 2 and 12h (Get Keyboard Flags)
;*
;* Params:  None
;*
;* Return:  Long integer
;*          high word = 0 for nonextended keyboard
;*                      1 for extended keyboard
;*          low word has following bits set when indicated keys are pressed:
;*          0 - Right SHIFT                   8 - Left CTRL
;*          1 - Left SHIFT                    9 - Left ALT
;*          2 - CTRL                         10 - Right CTRL
;*          3 - ALT                          11 - Right ALT
;*          4 - SCROLL LOCK active           12 - SCROLL LOCK pressed
;*          5 - NUM LOCK active              13 - NUM LOCK pressed
;*          6 - CAPS LOCK active             14 - CAPS LOCK pressed
;*          7 - INSERT toggled               15 - SYS REQ pressed

GetShift PROC

        sub     dx, dx                  ; Assume nonextended keyboard
        mov     ah, 2                   ;   and use Function 2
        mov     es, dx                  ; Point ES to low memory
        .IF     BYTE PTR es:[496h] & 16 ; If extended keyboard installed,
        inc     dx                      ;   set high word of return code
        mov     ah, 12h                 ;   and use Function 12h
        .ENDIF
        int     16h                     ; Get Keyboard Flags
        ret

GetShift ENDP


;* GetKeyClock - Waits for keystroke while updating time at specified location
;* on screen.
;*
;* Shows:   BIOS Interrupt - 16h, Functions 0 and 10h (Read Character)
;*                           16h, Functions 1 and 11h (Get Keyboard Status)
;*          DOS Functions - 2Ah (Get Date)
;*                          2Ch (Get Time)
;*
;* Uses:    vconfig - Video configuration structure (initialized
;*          by calling the GetVidConfig procedure)
;*
;* Params:  Row - Screen row for clock display
;*          Col - Screen column for clock display
;*
;* Return:  Short integer with key scan code in high byte and ASCII
;*          character code in low byte. Low byte is 0 for special
;*          keys (such as the "F" keys), which don't generate characters.

        .DATA
        PUBLIC  datestr
datestr BYTE    "  -  -     :  :  ", 0  ; Date/time string
        .CODE

GetKeyClock PROC,
        Row:WORD, Col:WORD

        LOCAL   service:BYTE

        INVOKE  GetShift                ; Check for extended keyboard
        mov     service, 11h            ; Assume Function 11h
        .IF     dx != 1                 ; If no extended keyboard,
        mov     service, 1              ;   use Function 1
        .ENDIF

        .WHILE  1
        mov     ah, service
        int     16h                     ; Get Keyboard Status
        .BREAK  .IF !zero?              ; If no key yet, update clock

; If not monochrome, color text, or black and white, skip clock update
; and poll keyboard again.

        .CONTINUE .IF (vconfig.mode != 7) \
                   && (vconfig.mode != 3) \
                   && (vconfig.mode != 2)

; If 80-column text, get date and time from DOS before again
; polling keyboard, and display at upper right corner of screen.

        mov     ah, 2Ch                 ; Request time
        int     21h                     ; Get Time
        mov     dl, dh
        push    dx                      ; Save seconds,
        push    cx                      ;   minutes,
        mov     cl, ch                  ;   and
        push    cx                      ;   hours
        mov     ah, 2Ah                 ; Request date
        int     21h                     ; Get Date
        sub     cx, 1900                ; Subtract century, CL = year
        push    cx                      ; Save year,
        push    dx                      ;   day,
        mov     dl, dh                  ;   and
        push    dx                      ;   month

        mov     cx, 6
        sub     bx, bx

        .REPEAT
        pop     ax                      ; Recover all 6 numbers in AL
        aam                             ; Convert to unpacked BCD
        xchg    al, ah                  ; Switch bytes for word move
        or      ax, "00"                ; Make ASCII numerals
        mov     WORD PTR datestr[bx], ax; Copy to string
        add     bx, 3                   ;   at every third byte
        .UNTILCXZ

        INVOKE  StrWrite, Row, Col, ADDR datestr
        .ENDW                           ; Loop again for keypress

        mov     ah, service             ; 1 or 11h, depending on keybd
        dec     ah                      ; Set AH to 0 or 10h
        int     16h                     ; Get key to remove it from
        ret                             ;   keyboard buffer

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -