📄 misc.asm
字号:
; Result is timer clock count
out 42h, al ; Low byte of count to timer
mov al, ah
out 42h, al ; High byte of count to timer
in al, 61h ; Read value from port 61h
or al, 3 ; Set first two bits
out 61h, al ; Turn speaker on
; Pause, pass duration of delay
INVOKE Pause, Duration
in al, 61h ; Get port value
xor al, 3 ; Kill bits 0-1 to turn
out 61h, al ; speaker off
ret
Sound ENDP
;* WriteTTY - Displays ASCIIZ string at cursor position, in either text
;* or graphics mode.
;*
;* Shows: BIOS Interrupt - 10h, Function 0Eh (Write Character in TTY Mode)
;*
;* Uses: vconfig - Video configuration structure (initialized
;* by calling the GetVidConfig procedure)
;*
;* Params: Sptr - Pointer to ASCIIZ string
;* icolor - Color index (for graphics mode only)
;*
;* Return: None
WriteTTY PROC USES ds si,
Sptr:PBYTE, icolor:WORD
mov bx, icolor ; BL = color index
mov bh, vconfig.dpage ; BH = current display page
LoadPtr ds, si, Sptr
mov cx, -1 ; Set loop counter to maximum
mov ah, 14 ; Function 14
.REPEAT
lodsb ; Get character from string
.BREAK .IF al == 0 ; Exit if NULL string terminator
int 10h ; No? Display, advance cursor
.UNTILCXZ
ret
WriteTTY ENDP
;* Colors - Alters screen colors within a specified area by using bit
;* or move operations on display attribute bytes in video memory.
;*
;* Shows: Instructions - not rol ror and xor or
;*
;* Params: Logic - Code number, 0 = NOT 2 = ROR 4 = XOR 6 = MOV
;* 1 = ROL 3 = AND 5 = OR
;* Attr - Attribute mask
;* 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
;*
;* Return: None
Colors PROC USES ds si,
Logic:WORD, Attr:WORD, Row1:WORD, Col1:WORD, Row2:WORD, Col2:WORD
GetVidOffset Row1, Col1 ; Get offset in video segment
inc ax
mov si, ax ; SI = offset for 1st attr byte
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 ds, vconfig.sgmnt ; DS = video segment
mov ax, Attr ; AL = mask for and, xor, and or
.REPEAT
push si ; Save ptr to start of line
push cx ; and number of columns
; Disable CGA video prior to memory access 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 ; Yes? Disable video
.ENDIF
cmp Logic, 1 ; Rotate left?
jl c_not ; If less, do NOT
je c_rol ; If equal, do ROL
cmp Logic, 3 ; And?
jl c_ror ; If less, do ROR
je c_and ; If equal, do AND
cmp Logic, 5 ; Or?
jl c_xor ; If less, do XOR
je c_or ; If equal, do OR
c_mov:
mov BYTE PTR [si], al ; MOV attr parameter
add si, 2 ; into attribute byte
loop c_mov
jmp c_done
c_or:
or BYTE PTR [si], al ; OR with attr parameter
add si, 2
loop c_or
jmp c_done
c_xor:
xor BYTE PTR [si], al ; XOR with attr parameter
add si, 2
loop c_xor
jmp c_done
c_and:
and BYTE PTR [si], al ; AND with attr parameter
add si, 2
loop c_and
jmp c_done
c_ror:
ror BYTE PTR [si], 1 ; Rotate right 1 bit
add si, 2
loop c_ror
jmp c_done
c_rol:
rol BYTE PTR [si], 1 ; Rotate left 1 bit
add si, 2
loop c_rol
jmp c_done
c_not:
not BYTE PTR [si] ; Flip bits
add si, 2
loop c_not
c_done:
.IF vconfig.adapter == CGA ; If CGA,
INVOKE EnableCga ; reenable CGA video
.ENDIF
pop cx ; Recover number of columns
pop si ; Recover offset for start of line
add si, 160 ; Point to start of next line
dec bx ; Decrement row counter
.UNTIL zero? ; Loop while rows remain
ret
Colors ENDP
;* Exec - Executes a child process. Exec handles the usual chores associated
;* with spawning a process: (1) parsing the command line tail and loading the
;* FCBs with the first two arguments; (2) setting and restoring the vectors
;* for Interrupts 1Bh, 23h, and 24h; and (3) querying DOS for the child's
;* return code.
;*
;* Shows: DOS Functions - 29h (Parse Filename)
;* 25h (Set Interrupt Vector)
;* 35h (Get Interrupt Vector)
;* 4Bh (Execute Program)
;* 4Dh (Get Return Code)
;*
;* Params: Spec - Pointer to ASCIIZ specification for program file
;* (must include .COM or .EXE extension)
;* Block - Pointer to parameter block structure
;* CtrBrk - Pointer to new CTRL+BREAK (Interrupt 1Bh) handler
;* CtrlC - Pointer to new CTRL+C (Interrupt 23h) handler
;* Criterr - Pointer to new Critical Error (Interrupt 24h) handler
;*
;* Return: Short integer with child return code, or -1 for EXEC error
Exec PROC USES ds si di,
Spec:PBYTE, Block:PPARMBLK, CtrBrk:PTR FAR,
CtrlC:PTR FAR, Criterr:PTR FAR
Vector 1Bh, Old1Bh, CtrBrk ; Save, replace Int 1Bh vector
Vector 23h, Old23h, CtrlC ; Save, replace Int 23h vector
Vector 24h, Old24h, Criterr ; Save, replace Int 24h vector
LoadPtr ds, bx, Block ; Point DS:BX to parameter block
push ds ; Save segment address
les di, (PARMBLK PTR [bx]).fcb1 ; Point ES:DI to first FCB
lds si, (PARMBLK PTR [bx]).taddr ; Point DS:SI to command-line
; tail
inc si ; Skip over count byte
mov ax, 2901h ; Set AH to request Function 29h
; AL = flag to skip leading blanks
int 21h ; Parse command-line into first FCB
pop es ; Recover seg addr of parameter block
les di, (PARMBLK PTR es:[bx]).fcb2 ; Point ES:DI to second FCB
mov ax, 2901h ; Request DOS Function #29h again
int 21h ; Parse command-line into second FCB
push bp ; Save only important register
mov WORD PTR cs:OldStk[0], sp
mov WORD PTR cs:OldStk[2], ss
LoadPtr es, bx, Block ; ES:BX points to param block
LoadPtr ds, dx, Spec ; DS:DX points to path spec
mov ax, 4B00h ; AH = DOS Function 4Bh
; AL = 0 for load and execute
int 21h ; Execute Program
mov sp, WORD PTR cs:OldStk[0] ; Reset stack pointers
mov ss, WORD PTR cs:OldStk[2]
pop bp ; Recover saved register
; Restore vectors for Interrupts 1Bh, 23h, and 24h.
mov ax, 251Bh ; AH = DOS Function 25h
; AL = interrupt number
lds dx, cs:Old1Bh ; DS:DX = original vector
int 21h ; Set Interrupt 1Bh Vector
mov al, 23h ; AL = interrupt number
lds dx, cs:Old23h ; DS:DX = original vector
int 21h ; Set Interrupt 23h Vector
mov al, 24h ; AL = interrupt number
lds dx, cs:Old24h ; DS:DX = original vector
int 21h ; Set Interrupt 24h Vector
mov ax, -1 ; Set error code
.IF !carry? ; If no EXEC error:
mov ah, 4Dh ; Request child's code
int 21h ; Get Return Code
sub ah, ah ; Make short integer
.ENDIF
ret
Old1Bh FPVOID ? ; Keep vectors for Interrupts
Old23h FPVOID ? ; 1Bh, 23h, and 24h in code
Old24h FPVOID ? ; segment, but nonexecutable
OldStk FPVOID ? ; Keep stack pointer
Exec ENDP
;* BinToHex - Converts binary word to 6-byte hexadecimal number in
;* ASCIIZ string. String is right justified and includes "h" radix.
;*
;* Shows: Instruction - xlat
;*
;* Params: Num - Number to convert to hex string
;* Sptr - Pointer to 6-byte string
;*
;* Return: None
.DATA
hex BYTE "0123456789ABCDEF" ; String of hex numbers
.CODE
BinToHex PROC USES di,
Num:WORD, Sptr:PBYTE
LoadPtr es, di, Sptr ; Point ES:DI to 6-byte string
mov bx, OFFSET hex ; Point DS:BX to hex numbers
mov ax, Num ; Number in AX
mov cx, 2 ; Loop twice for two bytes
.REPEAT
xchg ah, al ; Switch bytes
push ax ; Save number
shr al, 1 ; Shift high nibble to low
shr al, 1
shr al, 1
shr al, 1
xlat ; Get equivalent ASCII number in AL
stosb ; Copy to 6-byte string, increment DI
pop ax ; Recover number
push ax ; Save it again
and al, 00001111y ; Mask out high nibble
xlat ; Get equivalent ASCII number in AL
stosb ; Copy to 6-byte string, increment DI
pop ax ; Recover number
.UNTILCXZ ; Do next byte
mov ax, 'h' ; Put null, 'h' radix in AX
stosw ; Copy to last two bytes in string
ret
BinToHex ENDP
;* NewBlockSize - Adjusts size of allocated memory block.
;*
;* Shows: DOS Function - 4Ah (Resize Memory Block)
;*
;* Params: Adr - Segment address of block
;* Resize - Requested block size in paragraphs
;*
;* Return: Short integer error code
;* 0 if successful
;* 1 if error
NewBlockSize PROC,
Adr:WORD, Resize:WORD
mov ax, Adr ; Get block address
mov es, ax ; Point ES to block
mov bx, Resize ; New block size
mov ah, 4Ah ; Function number
int 21h ; Resize Memory Block
ret
NewBlockSize ENDP
;* Initialize - Initializes global variables _psp and _env, which are defined
;* in the DEMO.INC include file. If used with a DOS version less than 3.0,
;* this procedure will not produce valid results unless it is called before
;* changing the ES register. This is because at program entry ES points to
;* the Program Segment Prefix (PSP).
;*
;* Params: None
;*
;* Return: None
Initialize PROC
INVOKE GetPSP ; Get segment address of PSP
.IF ax == 0 ; If less than DOS 3.0,
mov es, ax ; reload ES with PSP address
.ENDIF
mov _psp, es ; Initialize variable with PSP address
mov ax, es:[2Ch] ; Get environment seg from PSP
mov _env, ax ; Store it
ret
Initialize ENDP
END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -