mirror of
https://github.com/vxunderground/MalwareSourceCode.git
synced 2024-12-18 17:36:11 +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
|
||
|