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

📄 misc.asm

📁 这是一些例程
💻 ASM
📖 第 1 页 / 共 3 页
字号:
GetKeyClock ENDP


;* GetPSP - Gets address of Program Segment Prefix. For DOS 3.0 or higher.
;*
;* Shows:   DOS Function - 62h (Get PSP Address)
;*          Instruction - call
;*
;* Params:  None
;*
;* Return:  Short integer with PSP segment address
;*          or 0 if DOS version below 3.0

GetPSP  PROC

        INVOKE  GetVer                  ; Get DOS version number
        .IF     ax >= 300               ; If DOS 3.0 or higher:
        mov     ah, 62h                 ;   query DOS for PSP,
        int     21h                     ;   get PSP Address,
        mov     ax, bx                  ;   return in AX
        .ELSE                           ; Else 2.0:
        sub     ax, ax                  ; For version 2, return 0
        .ENDIF
        ret

GetPSP  ENDP


;* GetMem - Gets total size of memory and determines the largest amount of
;* unallocated memory available. GetMem invokes DOS Function 48h (Allocate
;* Memory) to request an impossibly large memory block. DOS denies the re-
;* quest, but returns instead the size of the largest block available. This
;* is the amount that GetMem returns to the calling program. See the WinOpen
;* procedure for an example of calling Function 48h to allocate unused memory.
;*
;* Shows:   BIOS Interrupt - 12h (Get Conventional Memory Size)
;*          Instructions - push     pop      ret
;*
;* Params:  None
;*
;* Return:  Long integer, high word = total memory in kilobytes (KB)
;*                        low word  = largest block of available memory (KB)

GetMem  PROC

        int     12h                     ; Get total memory in kilobytes
        push    ax                      ; Save size of memory
        mov     ah, 48h                 ; Request memory allocation
        mov     bx, 0FFFFh              ; Ensure request is denied for
                                        ;   impossibly large block
        int     21h                     ; Get largest available block in BX
        mov     ax, bx                  ; Copy to AX
        mov     cl, 6                   ; Convert paragraphs to kilobytes by
        shr     ax, cl                  ;   dividing by 64
        pop     dx                      ; Recover total in DX
        ret                             ; Return long integer DX:AX

GetMem  ENDP


;* VeriPrint - Checks if LPT1 (PRN) is available.
;*
;* Shows:   BIOS Interrupt - 17h (Parallel Port Printer Driver)
;*
;* Params:  None
;*
;* Return:  Short integer, 1 for yes or 0 for no

VeriPrint PROC

        mov     ah, 2                   ; Check printer status for
        sub     dx, dx                  ;   parallel printer (port 0)
        int     17h
        xchg    dx, ax                  ; Put 0 (for error) in AX

; If all error bits are off and both operation bits are on, return 1

        .IF     !(dh & 00101001y) && (dh & 10010000y)
        inc     ax                      ; Return 1
        .ENDIF
        ret

VeriPrint ENDP


;* IntToAsc - Converts integer to ASCII string. This procedure is useful
;* only for assembly language and is not intended to be callable by C.
;*
;* Shows:   Instructions - aam     xchg
;*
;* Entry:   AX = integer (9999 max)
;*
;* Return:  DX:AX = 4-digit ASCII number

IntToAsc PROC

        cwd                             ; Zero DX register
        mov     cx, 100                 ; Divide AX by 100, yields
        div     cx                      ;   AX=quotient, DX=remainder
        aam                             ; Make digits unpacked BCD
        or      ax, "00"                ; Convert to ASCII
        xchg    ax, dx                  ; Do same thing for DX
        aam
        or      ax, "00"
        ret                             ; Return DX:AX = ASCII number

IntToAsc ENDP


;* VeriAnsi - Checks for ANSI driver by writing ANSI sequence to report
;* cursor position. If report compares with position returned from
;* GetCurPos procedure, then ANSI driver is operating.
;*
;* Shows:   DOS Functions - 06h (Direct Console I/O)
;*                          0Ch (Flush Input Buffer and then Input)
;*
;* Params:  None
;*
;* Return:  Short integer, 1 for yes or 0 for no

        .DATA
        PUBLIC report
report  DB      ESCAPE, "[6n$"          ; ANSI Report Cursor sequence
        .CODE

VeriAnsi PROC

        ; Get cursor position from BIOS
        INVOKE  GetCurPos
        mov     cx, ax                  ; Save it in CX
        mov     dx, OFFSET report       ; ANSI string to get position
        mov     ah, 9                   ; Request DOS String Output
        int     21h                     ; Write ANSI escape sequence

        mov     ah, 6                   ; Skip Esc character in
        mov     dl, 0FFh                ;   keyboard buffer
        int     21h
        jz      e_exit                  ; If no key, ANSI not loaded
        mov     ah, 6                   ; Skip '[' character
        int     21h
        jz      e_exit                  ; If no key, ANSI not loaded
        mov     ah, 6                   ; Get 1st digit of cursor row
        int     21h
        jz      e_exit                  ; If no key, ANSI not loaded
        mov     bh, al                  ; Store in BH
        mov     ah, 6                   ; Get 2nd digit of cursor row
        int     21h
        jz      e_exit                  ; If no key, ANSI not loaded
        mov     bl, al                  ; Store in BL
        mov     al, ch                  ; Get original row # in AL
        cbw                             ; AX = row # from GetCurPos
        inc     ax                      ; Add 1 to it
        call    IntToAsc                ; Make ASCII digits
        cmp     ax, bx                  ; ANSI and BIOS reports match?
        jne     e_exit                  ; No?  Then ANSI not loaded

        mov     ax, 0C06h               ; Flush remaining ANSI keys
        mov     dl, 0FFh                ;   from buffer
        int     21h
        mov     ax, 1                   ; Set 1 for true
        jmp     exit                    ;   and exit
e_exit:
        sub     ax, ax                  ; Set 0 return code if no
exit:
        ret                             ;   ANSI driver installed

VeriAnsi ENDP


;* VeriCop - Checks for coprocessor.
;*
;* Shows:   BIOS Interrupt - 11h (Get Equipment Configuration)
;*
;* Params:  None
;*
;* Return:  Short integer, 1 for yes or 0 for no

VeriCop PROC

        int     11h                     ; Check peripherals
        test    al, 2                   ; Coprocessor?
        mov     ax, 0                   ; Assume no, don't alter flags
        .IF     !zero?
        inc     ax                      ; Set to 1
        .ENDIF
        ret

VeriCop ENDP


;* SetLineMode - Sets line mode for EGA or VGA.
;*
;* Shows:   BIOS Interrupt - 10h, Function 11h (Character Generator Interface)
;*                           10h, Function 12h (Video Subsystem Configuration)
;*
;* Uses:    vconfig - Video configuration structure (initialized
;*          by calling the GetVidConfig procedure)
;*
;* Params:  Line - Requested line mode (25, 43, or 50)
;*
;* Return:  Short integer with error code
;*          0 if successful
;*          1 if error

SetLineMode PROC,
        Line:WORD

        .IF     vconfig.adapter >= EGA  ; If EGA or VGA:
        mov     ax, Line                ; Check for valid parameter
        cmp     al, 25
        je      line25
        cmp     al, 43
        je      line43
        cmp     al, 50
        je      line50
        jmp     e_exit                  ; If not 25, 43, or 50, exit w/ error
line25:
        mov     al, 11h                 ; Set for EGA 25-line mode
        cmp     vconfig.adapter, EGA    ; EGA?
        je      linemode                ; Yes?  Continue
        mov     ax, 1202h               ; No?  Function 12h for VGA
        mov     bl, 30h                 ; AL = 2 for 400 scan lines
        int     10h                     ; Reset to 400 scan lines
        mov     ax, 0003                ; Reset mode (Function 0)
        int     10h                     ;   to mode 3 (80-col text)
        mov     al, 14h                 ; Request 8x16 char matrix
        jmp     linemode
line43:
        mov     al, 12h                 ; Set for EGA 43-line mode
        cmp     vconfig.adapter, EGA    ; EGA?
        je      linemode                ; Yes?  Continue
        mov     ax, 1201h               ; No?  Function 12h for VGA
        mov     bl, 30h                 ; AL = 1 for 350 scan lines
        int     10h                     ; Reset to 350 scan lines
        mov     ax, 0003                ; Reset mode (Function 0)
        int     10h                     ;   to mode 3 (80-col text)
        mov     al, 12h                 ; Request 8x8 character matrix
        jmp     linemode
line50:
        cmp     vconfig.adapter, VGA    ; VGA?
        jne     e_exit                  ; No?  Exit with error
        mov     ax, 1202h               ; Yes?  Function 12h
        mov     bl, 30h                 ; AL = 2 for 400 scan lines
        int     10h                     ; Reset to 400 scan lines
        mov     ax, 0003                ; Reset mode (Function 0)
        int     10h                     ;   to mode 3 (80-col text)
        mov     al, 12h                 ; Request 8x8 character matrix
linemode:
        sub     bl, bl                  ; Use table 0
        mov     ah, 11h                 ; Request Function 11h
        int     10h                     ; Set new line mode

        mov     ah, 12h                 ; Select alternate print
        mov     bl, 20h                 ;   screen for EGA and VGA
        int     10h

        cmp     vconfig.adapter, VGA    ; VGA?
        je      exit                    ; Yes?  Then exit
        cmp     Line, 12h               ; If EGA 43-line mode, set
        je      port                    ;   cursor through port to
                                        ;   avoid cursor emulation bug

        ; Set normal cursor size, pass top and bottom scan lines
        INVOKE  SetCurSize, 6, 7
        jmp     exit
port:
        mov     dx, 03D4h               ; Video controller address
        mov     ax, 060Ah               ; Set AH = 06h (cursor start)
                                        ;     AL = 0Ah (register #)
        out     dx, ax                  ; Update port
        mov     ax, 000Bh               ; Set AH = 00h (cursor end)
                                        ;     AL = 0Bh (register #)
        out     dx, ax                  ; Update port
        jmp     exit                    ; Normal exit
        .ENDIF  ; EGA or VGA
e_exit:
        mov     ax, 1                   ; Set error code
        jmp     exit2
exit:
        sub     ax, ax                  ; Clear error code
exit2:
        ret

SetLineMode ENDP


;* Pause - Waits for specified number of clocks to elapse, then returns.
;*
;* Shows:   BIOS Interrupt - 1Ah, Function 0 (Real-Time Clock Driver)
;*          Operators - LOCAL     []
;*
;* Params:  Duration - Desired duration in clocks, where
;*                     18 clocks = approx 1 second
;*
;* Return:  None

Pause   PROC,
        Duration:WORD

        LOCAL tick:DWORD

        sub     ah, ah
        int     1Ah                     ; Get Clock Count in CX:DX
        add     dx, Duration            ; Add pause time to it
        adc     cx, 0
        mov     WORD PTR tick[0], dx    ; Result is target time;
        mov     WORD PTR tick[2], cx    ;   keep in local variable

        .REPEAT
        int     1Ah                     ; Poll clock until target time
        .UNTIL  (dx >= WORD PTR tick[0]) || (cx >= WORD PTR fileinfo.time[2])
        ret

Pause   ENDP


;* Sound - Sounds speaker with specified frequency and duration.
;*
;* Shows:   Instructions - in           out
;*
;* Params:  Freq - Desired frequency of sound in hertz
;*          Duration - Desired duration in clocks, where
;*                     18 clocks = approx 1 second
;*
;* Return:  None

Sound   PROC,
        Freq:WORD, Duration:WORD

        mov     al, 0B6h                ; Initialize channel 2 of
        out     43h, al                 ;   timer chip
        mov     dx, 12h                 ; Divide 1,193,182 hertz
        mov     ax, 34DEh               ;   (clock frequency) by
        div     Freq                    ;   desired frequency

⌨️ 快捷键说明

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