mirror of
https://github.com/vxunderground/MalwareSourceCode.git
synced 2024-12-24 04:15:26 +00:00
251 lines
8.1 KiB
NASM
251 lines
8.1 KiB
NASM
|
TITLE scrn3.asm
|
|||
|
|
|||
|
; AUTHOR Tim Spencer - Compuserve [73657,1400]
|
|||
|
; DATE March 17, 1987
|
|||
|
|
|||
|
_TEXT SEGMENT BYTE PUBLIC 'CODE'
|
|||
|
_TEXT ENDS
|
|||
|
|
|||
|
_DATA SEGMENT WORD PUBLIC 'DATA'
|
|||
|
SCRN STRUC ; screen data structure - defined in video.h
|
|||
|
off dw 0 ; offset (cursor position)
|
|||
|
seg dw 0 ; screen buffer address
|
|||
|
port dw 0 ; status port address
|
|||
|
attrib dw 0 ; attribute to use
|
|||
|
cgacrd dw 0 ; enable retrace checking if not zero
|
|||
|
SCRN ENDS
|
|||
|
|
|||
|
_DATA ENDS
|
|||
|
|
|||
|
DGROUP GROUP _DATA
|
|||
|
ASSUME CS:_TEXT, DS:DGROUP, SS:DGROUP, ES:NOTHING
|
|||
|
|
|||
|
|
|||
|
_TEXT SEGMENT BYTE PUBLIC 'CODE'
|
|||
|
|
|||
|
;-----------------------------------------------------------------------;
|
|||
|
; scrn_restore - MSC callable function to restore a rectangular area ;
|
|||
|
; of the screen buffer. Checks for vertical retrace ;
|
|||
|
; only if the external structure member cga_card is ;
|
|||
|
; non-zero. &scrn is the address of that structure. ;
|
|||
|
; (see video.h). ;
|
|||
|
; ; ;
|
|||
|
; Note: This procedure uses stosb in retrace checking mode (instead of ;
|
|||
|
; movsb) because it stuffs the char/attrib into the screen buffer ;
|
|||
|
; slightly faster. ;
|
|||
|
; ;
|
|||
|
; Usage: scrn_restore(left, right, top, bottom, data_buff, &scrn) ;
|
|||
|
; ;
|
|||
|
;-----------------------------------------------------------------------;
|
|||
|
_DATA SEGMENT
|
|||
|
restore_args STRUC ; structure for easy argument reference
|
|||
|
dw 0 ; saved BP value
|
|||
|
dw 0 ; return address
|
|||
|
rleft dw 0 ; rectangular boundries...
|
|||
|
rright dw 0
|
|||
|
rtop dw 0
|
|||
|
rbottom dw 0
|
|||
|
mdata dw 0 ; address of data buffer to write to screen
|
|||
|
mstruct dw 0 ; pointer to SCRN structure(defined in video.h)
|
|||
|
restore_args ENDS
|
|||
|
|
|||
|
cga db 0 ; variable to hold cga_card value
|
|||
|
_DATA ENDS
|
|||
|
|
|||
|
PUBLIC _scrn_restore
|
|||
|
|
|||
|
_scrn_restore PROC NEAR
|
|||
|
push bp ; set up frame pointer
|
|||
|
mov bp,sp
|
|||
|
push si
|
|||
|
push di
|
|||
|
mov bx,[bp].mstruct ; get pointer to SCRN structure
|
|||
|
les di,dword ptr[bx].off ; get scrn seg in es, off in di
|
|||
|
mov dx,[bx].port ; get status port address
|
|||
|
mov ax,[bx].cgacrd ; hold cga status in variable cga
|
|||
|
mov cga,al
|
|||
|
mov si,[bp].mdata ; make si point to data buffer
|
|||
|
mov bh,byte ptr[bp].rtop ; top will be incremented until it
|
|||
|
mov bl,byte ptr[bp].rbottom ; is greater than bottom, then exit.
|
|||
|
xor cx,cx ; set initial logical cursor position
|
|||
|
mov cl,bh ; by getting top into cx,
|
|||
|
mov al,80 ; multiplying by 80,
|
|||
|
mul cl
|
|||
|
mov cx,ax
|
|||
|
add cx,[bp].rleft ; adding left.
|
|||
|
shl cx,1 ; and multiplying by 2
|
|||
|
mov di,cx ; put result into di
|
|||
|
mov cx,[bp].rright ; get the length of one line into
|
|||
|
sub cx,[bp].rleft ; cx by subtracting left from right
|
|||
|
add cx,1 ; adding 1
|
|||
|
push cx ; save it
|
|||
|
mov ax,79 ; calculate offset from end of line to
|
|||
|
sub ax,[bp].rright ; the start of the next line
|
|||
|
add ax,[bp].rleft
|
|||
|
shl ax,1
|
|||
|
push ax ; and save it
|
|||
|
write_line:
|
|||
|
cmp cga,0 ; cga card in use?
|
|||
|
jnz rwait1 ; yes, go wait
|
|||
|
rep movsw ; no, warp speed.
|
|||
|
jmp short rcheck_pos ; go check position
|
|||
|
rwait1:
|
|||
|
in al, dx ; wait for end of retrace
|
|||
|
shr al, 1 ; test horizontal trace bit
|
|||
|
jc rwait1 ; loop if still tracing
|
|||
|
cli ; disable writus interuptus
|
|||
|
rwait2:
|
|||
|
in al, dx ; now wait until the very moment
|
|||
|
shr al, 1 ; when the next retrace begins
|
|||
|
jnc rwait2 ; still waiting...
|
|||
|
mov al,[si] ; load the char into al for stosb
|
|||
|
stosb ; write it and update pointer
|
|||
|
sti ; enable interrupts again
|
|||
|
inc si ; point si at attribute
|
|||
|
rwait3:
|
|||
|
in al, dx ; repeat these steps for the attribute
|
|||
|
shr al, 1
|
|||
|
jc rwait3
|
|||
|
cli
|
|||
|
rwait4:
|
|||
|
in al, dx
|
|||
|
shr al, 1
|
|||
|
jnc rwait4
|
|||
|
mov al,[si] ; load the attribute
|
|||
|
stosb
|
|||
|
sti
|
|||
|
inc si ; point si at next char
|
|||
|
loop rwait1
|
|||
|
rcheck_pos:
|
|||
|
pop ax ; restore offset to next line start
|
|||
|
pop cx ; restore count
|
|||
|
inc bh ; is top greater than bottom yet?
|
|||
|
cmp bh,bl
|
|||
|
ja rexit ; yes.
|
|||
|
push cx ; no, save count again
|
|||
|
push ax ; save line start offset again
|
|||
|
add di,ax ; move di to start of next line
|
|||
|
jmp short write_line ; write another line
|
|||
|
rexit:
|
|||
|
pop di
|
|||
|
pop si
|
|||
|
pop bp
|
|||
|
ret
|
|||
|
_scrn_restore ENDP
|
|||
|
|
|||
|
|
|||
|
|
|||
|
;-----------------------------------------------------------------------;
|
|||
|
; scrn_save - MSC callable function to save a rectangular area of the ;
|
|||
|
; screen to a user defined buffer. ;
|
|||
|
; ;
|
|||
|
; Usage: scrn_save(left, right, top, bottom, data_buff, &scrn) ;
|
|||
|
;-----------------------------------------------------------------------;
|
|||
|
_DATA SEGMENT
|
|||
|
save_args STRUC ; structure for easy argument reference
|
|||
|
dw 0 ; saved bp value
|
|||
|
dw 0 ; return address
|
|||
|
sleft dw 0 ; rectangular boundries
|
|||
|
sright dw 0
|
|||
|
stop dw 0
|
|||
|
sbottom dw 0
|
|||
|
sbuff dw 0 ; user defined buffer to hold screen contents
|
|||
|
sstruct dw 0 ; pointer to SCRN structure (see video.h)
|
|||
|
save_args ENDS
|
|||
|
_DATA ENDS
|
|||
|
|
|||
|
scga db 0 ; store cga true/false value here - must be
|
|||
|
; declared outside data segment because es and
|
|||
|
; ds are swapped in this function.
|
|||
|
|
|||
|
PUBLIC _scrn_save
|
|||
|
|
|||
|
_scrn_save PROC NEAR
|
|||
|
push bp ; set up frame pointer
|
|||
|
mov bp,sp
|
|||
|
push si
|
|||
|
push di
|
|||
|
push ds
|
|||
|
mov bx,[bp].mstruct ; get pointer to SCRN structure
|
|||
|
mov dx,[bx].port ; get status port address
|
|||
|
mov ax,[bx].cgacrd ; hold cga status in variable scga
|
|||
|
mov scga,al
|
|||
|
mov ax,ds
|
|||
|
mov es,ax ; get data segment into es
|
|||
|
mov di,[bp].sbuff ; and offset of user buffer in di
|
|||
|
mov ax,[bx].seg ; get the screen segment and
|
|||
|
mov ds,ax ; put in ds
|
|||
|
mov bh,byte ptr[bp].stop ; top will be incremented until it
|
|||
|
mov bl,byte ptr[bp].sbottom ; is greater than bottom, then exit.
|
|||
|
xor cx,cx ; set initial logical cursor position
|
|||
|
mov cl,bh ; by getting top into cx,
|
|||
|
mov al,80 ; multiplying by 80,
|
|||
|
mul cl
|
|||
|
mov cx,ax
|
|||
|
add cx,[bp].sleft ; adding left.
|
|||
|
shl cx,1 ; and multiplying by 2
|
|||
|
mov si,cx ; put result into si
|
|||
|
mov cx,[bp].sright ; get the length of one line into
|
|||
|
sub cx,[bp].sleft ; cx by subtracting left from right
|
|||
|
add cx,1 ; adding 1
|
|||
|
push cx ; save it
|
|||
|
mov ax,79 ; calculate offset from end of line to
|
|||
|
sub ax,[bp].sright ; the start of the next line
|
|||
|
add ax,[bp].sleft
|
|||
|
shl ax,1
|
|||
|
push ax ; and save it
|
|||
|
read_line:
|
|||
|
cmp cga,0 ; cga card in use?
|
|||
|
jnz swait1 ; yes, go wait
|
|||
|
rep movsw ; no, warp speed.
|
|||
|
jmp short scheck_pos ; go check position
|
|||
|
swait1:
|
|||
|
in al, dx ; wait for end of retrace
|
|||
|
shr al, 1 ; test horizontal trace bit
|
|||
|
jc swait1 ; loop if still tracing
|
|||
|
cli ; disable writus interuptus
|
|||
|
swait2:
|
|||
|
in al, dx ; now wait until the very moment
|
|||
|
shr al, 1 ; when the next retrace begins
|
|||
|
jnc swait2 ; still waiting...
|
|||
|
mov al,[si] ; load the char into al for stosb
|
|||
|
stosb ; write it and update pointer
|
|||
|
sti ; enable interrupts again
|
|||
|
inc si ; point si at attribute
|
|||
|
swait3:
|
|||
|
in al, dx ; repeat these steps for the attribute
|
|||
|
shr al, 1
|
|||
|
jc swait3
|
|||
|
cli
|
|||
|
swait4:
|
|||
|
in al, dx
|
|||
|
shr al, 1
|
|||
|
jnc swait4
|
|||
|
mov al,[si] ; load the attribute
|
|||
|
stosb
|
|||
|
sti
|
|||
|
inc si ; point si at next char
|
|||
|
loop swait1
|
|||
|
scheck_pos:
|
|||
|
pop ax ; restore offset to next line start
|
|||
|
pop cx ; restore count
|
|||
|
inc bh ; is top greater than bottom yet?
|
|||
|
cmp bh,bl
|
|||
|
ja sexit ; yes.
|
|||
|
push cx ; no, save count again
|
|||
|
push ax ; save line start offset again
|
|||
|
add si,ax ; move di to start of next line
|
|||
|
jmp short read_line ; write another line
|
|||
|
sexit:
|
|||
|
pop ds
|
|||
|
pop di
|
|||
|
pop si
|
|||
|
pop bp
|
|||
|
ret
|
|||
|
_scrn_save ENDP
|
|||
|
|
|||
|
|
|||
|
_TEXT ENDS
|
|||
|
|
|||
|
END
|
|||
|
|