home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
QBasic & Borland Pascal & C
/
Delphi5.iso
/
C
/
Samples
/
C-ASM_VI.ARJ
/
PROGASM.ZIP
/
PROG047.ASM
< prev
next >
Wrap
Assembly Source File
|
1988-05-25
|
6KB
|
145 lines
;************************************************************************
; Scrolling text window in text modes *
; Entry: Up, Left - Upper left row and column *
; Down, Right - Lower right row and column *
; Count - Number of lines to scroll *
;************************************************************************
Up EQU WORD PTR [BP+4]
Left EQU WORD PTR [BP+6]
Down EQU WORD PTR [BP+8]
Right EQU WORD PTR [BP+10]
Count EQU WORD PTR [BP+12]
PUBLIC _Scroll_Text
_Scroll_Text PROC NEAR
PUSH BP
MOV BP,SP
PUSH DS ;Preserve DS
PUSH ES ;Preserve ES
PUSH SI
PUSH DI
;--- Determine and load segement of the display buffer
XOR AX,AX ;Point ES to segment zero
MOV ES,AX
MOV AX,0B000H ;Assume monochrome buffer address
TEST BYTE PTR ES:[BIOS_Equipment],2 ;Is mono attached?
JNZ Scroll_Addr_Ok ;...Yes, go load segment
MOV AX,0B800H ;...No, change address to color
Scroll_Addr_Ok:
MOV DS,AX ;Set segment of display buffer
;--- Compute pointers to source and destination
CMP Count,0 ;Are we scrolling up?
JL Setup_Down ;...No, setup for scrolling down
Setup_Up:
MOV BX,ES:[BIOS_Columns] ;Compute address of where to move from
MOV AX,Up ;Compute first byte to move as
ADD AX,Count ;(Upper row + count)*bytes per line
MUL BX ; + upper column
ADD AX,Left
MOV SI,AX ;Save source address in SI
SHL SI,1 ;Adjust for two bytes per char
MOV AX,Up ;Compute address of where to move to
MUL BX ;as Upper row * bytes line + upper
ADD AX,Left ; + column
MOV DI,AX ;Save destination
SHL DI,1 ;Adjust for two bytes per char
MOV DX,Right ;Words to move in each line
SUB DX,Left ;is (Right - Left + 1)
INC DX
SUB BX,DX ;Compute 'update'
SHL BX,1
MOV CX,Down ;Compute number of lines to move
SUB CX,Up
SUB CX,Count
INC CX
PUSH DS ;Copy DS into ES
POP ES
Loop_Up:
PUSH CX ;Save counter of lines
MOV CX,DX ;Set counter of bytes
REP MOVSW ;Move next line of bytes (word/char)
ADD DI,BX ;Set pointers to next line
ADD SI,BX
POP CX ;Restore line counter
LOOP Loop_Up ;If not done, go move next line
Clear_Up:
MOV CX,Count ;Number of lines to clear
MOV AX,0720H ;Value to use as 'clear'
Loop_Clear_Up:
PUSH CX
MOV CX,DX ;Fetch # bytes in each line
REP STOSW ;Clear next line
ADD DI,BX ;Set pointers to next line
POP CX
LOOP Loop_Clear_Up
JMP Scroll_Done
Setup_Down:
NEG Count
MOV BX,ES:[BIOS_Columns] ;Compute bytes/line
MOV AX,Down ;Compute first source byte
SUB AX,Count ;(Lower row - count)*bytes per line
MUL BX ; + upper column
ADD AX,Left
MOV SI,AX ;Save source address in SI
SHL SI,1 ;Adjust for two bytes per char
MOV AX,Down ;Compute address of where to move
MUL BX ;as Lower row * bytes line + left
ADD AX,Left ; + column
MOV DI,AX ;Save destination
SHL DI,1 ;Adjust for two bytes per char
MOV DX,Right ;Compute words to move in a line
SUB DX,Left ;as (Right - Left + 1)
INC DX
ADD BX,DX ;Compute 'update'
SHL BX,1
MOV CX,Down ;Compute number of lines to move
SUB CX,Up
SUB CX,Count
INC CX
PUSH DS ;Copy DS into ES
POP ES
Loop_Down:
PUSH CX ;Save counter of lines
MOV CX,DX ;Set counter of bytes
REP MOVSW ;Move next line of bytes
SUB DI,BX ;Set pointers to next line
SUB SI,BX
POP CX ;Restore line counter
LOOP Loop_Down ;If not done, go move next line
Clear_Down:
MOV CX,Count ;Number of lines to clear
MOV AX,0720H ;Value to use as 'clear'
Loop_Clear_Down:
PUSH CX
MOV CX,DX ;Fetch # bytes in each line
REP STOSW ;Clear next line
SUB DI,BX ;Set pointers to next line
POP CX
LOOP Loop_Clear_Down
Scroll_Done:
POP DI
POP SI
POP ES
POP DS
POP BP
RET
_Scroll_Text ENDP