Category : C Source Code
Archive   : WRAP.ZIP
Filename : ROLL.ASM
Output of file : ROLL.ASM contained in archive : WRAP.ZIP
;
; roll.asm - routine to roll a window up or down.
; This is a wrapping scroll.
;
; void roll (shiftwin *win, int num);
; where shiftwin is a structure:
; typedef struct {
; int x1, y1, x2, y2;
; char attr;
; } shiftwin;
;
; coordinates are 1-relative
; and num is a positive number to roll up,
; or negative to roll down.
;
dosseg
ifdef __COMPACT__
.model compact
endif
ifdef __HUGE__
.model huge
endif
ifdef __LARGE__
.model large
endif
ifdef __MEDIUM__
.model medium
endif
ifdef __SMALL__
.model small
endif
extrn _scrseg:word
extrn _getscr:proc
extrn _getofs:proc
.code
_roll proc
call _getscr ;get screen information
push si
push di
push bp
mov bp,sp
sub sp,180 ;make space for local variables
push es ;save cause we're gonna use it
mov ax,ds
mov es,ax
mov si,word ptr [bp+8] ;si points to shift window
;[si+0] = x1
;[si+2] = y1
;[si+4] = x2
;[si+6] = y2
;[si+8] = attr
;[bp+10] = num
cmp word ptr [bp+10],0
jnz roll1
jmp all_done ;if 0, don't scroll
roll1: jge roll_up
roll_down:
push word ptr [si+6] ;bottom
push word ptr [si+2] ;top
neg word ptr [bp+10]
mov ah,7
jmp short do_roll
roll_up:
push word ptr [si+2] ;top
push word ptr [si+6] ;bottom
mov ah,06
;
; AH is 06 for scroll up, 07 for scroll down.
;
do_roll:
mov word ptr [bp-174],ax ;save direction
mov bx,word ptr [si+0] ;left
pop ax
call _getofs
mov word ptr [bp-176],di ;save dest address
mov bx,word ptr [si+0] ;left
pop ax
call _getofs
xchg si,di
mov word ptr [bp-178],si ;save source address
mov bx,word ptr [bp+8] ;address of win spec
mov ax,word ptr [bx+4] ;AX = x2
sub ax,word ptr [bx+0]
inc ax ;AX is number of columns
mov word ptr [bp-180],ax ;save #cols
xchg ax,cx
cld
;
; The basic algorithm is:
; For each line to be rolled
; copy the line to the save area
; call BIOS to scroll the screen
; copy from save area to vacated line
;
; The routine could be made faster by saving the number of lines to be
; scrolled, calling BIOS only once, then writing the saved lines to the
; vacated areas. But, this would require (possibly) 4K of storage for
; the save area. Of course, I could cut that to 2K if I assume rolling
; a window of n lines up by n-1 lines is the same as rolling it down 1 line.
;
; Another thing to keep in mind if you want to do this: If _roll is called
; to roll more lines than are in the window, you can either reject the call
; as invalid, or divide the requested number of lines by window size and
; use the remainder (i.e. requested mod size). I may consider this in a
; future enhancement.
;
roll_loop:
lea ax,word ptr [bp-170]
mov di,ax ;dest is save area
push ds
mov ax,word ptr _scrseg
mov ds,ax
rep movsw ;copy text to save area
pop ds
mov ax,word ptr [bp-174] ;direction in AH
mov al,1 ;always scroll 1 line
mov si,word ptr [bp+8] ;si is address of win spec
mov bh,byte ptr [si+8] ;bh is attribute
mov ch,byte ptr [si+2] ;ch is y1
dec ch
mov cl,byte ptr [si+0] ;cl is x1
dec cl
mov dh,byte ptr [si+6] ;dh is y2
dec dh
mov dl,byte ptr [si+4] ;dl is x2
dec dl
int 10h ;have BIOS do the scroll
lea ax,word ptr [bp-170]
mov si,ax ;source is save area
mov di,word ptr [bp-176] ;dest is screen
mov cx,word ptr [bp-180] ;#columns
push es
mov ax,word ptr _scrseg
mov es,ax
rep movsw ;copy from save area to screen
pop es
dec word ptr [bp+10] ;decrease line count
jz all_done
mov si,word ptr [bp-178]
mov cx,word ptr [bp-180]
jmp short roll_loop
all_done:
pop es
mov sp,bp
pop bp
pop di
pop si
ret
_roll endp
public _roll
end
Very nice! Thank you for this wonderful archive. I wonder why I found it only now. Long live the BBS file archives!
This is so awesome! 😀 I’d be cool if you could download an entire archive of this at once, though.
But one thing that puzzles me is the “mtswslnkmcjklsdlsbdmMICROSOFT” string. There is an article about it here. It is definitely worth a read: http://www.os2museum.com/wp/mtswslnk/