149 lines
4.9 KiB
NASM
149 lines
4.9 KiB
NASM
|
||
; Copyright (c) 1985, 87 by Borland International, Inc.
|
||
|
||
TITLE MCMVSMEM
|
||
|
||
DATA SEGMENT WORD PUBLIC
|
||
|
||
ASSUME DS:DATA
|
||
|
||
EXTRN CheckSnow : BYTE
|
||
|
||
DATA ENDS
|
||
|
||
CODE SEGMENT BYTE PUBLIC
|
||
|
||
ASSUME CS:CODE
|
||
|
||
PUBLIC MoveToScreen, MoveFromScreen
|
||
|
||
; procedure MoveToScreen(var Source, Dest; Len : Word);
|
||
|
||
MoveToScreen PROC FAR
|
||
push bp
|
||
mov bp,sp
|
||
push bp ; Save Turbo's BP
|
||
push ds ; and DS
|
||
mov bh,ds:CheckSnow ; Load CheckSnow value
|
||
lds si,dword ptr [bp+12] ; Source pointer into DS:SI
|
||
les di,dword ptr [bp+8] ; Dest pointer into ES:DI
|
||
mov cx,[bp+6] ; Len value into CX
|
||
cmp cx,0 ; Quit if Len = 0
|
||
je x0
|
||
cmp si,di
|
||
jle x1
|
||
cld ; Set string direction to forward
|
||
jmp short x2
|
||
x1:
|
||
add si,cx
|
||
sub si,2
|
||
add di,cx
|
||
sub di,2
|
||
std
|
||
x2:
|
||
cmp bh,0
|
||
je x7
|
||
x3:
|
||
shr cx,1 ; Change bytes to words
|
||
mov dx,3DAh ; Point DX to CGA status port
|
||
mov bl,9 ; Move horiz. + vertical retrace mask to bl
|
||
x4:
|
||
lodsw ; Grab a video word
|
||
mov bp,ax ; Save it in BP
|
||
x5:
|
||
in al,dx ; Get 6845 status
|
||
rcr al,1 ; Check horizontal retrace
|
||
jb x5 ; Loop if in horizontal retrace: this prevents
|
||
; starting in mid-retrace, since there is
|
||
; exactly enough time for 1 and only 1 STOSW
|
||
; during horizontal retrace
|
||
cli ; No ints during critical section
|
||
x6:
|
||
in al,dx ; Get 6845 status
|
||
and al,bl ; Check for both kinds of retrace: IF the
|
||
; video board does not report horizontal
|
||
; retrace while in vertical retrace, this
|
||
; will allow several characters to be
|
||
; stuffed in during vertical retrace
|
||
jz x6 ; Loop if equal to zero
|
||
mov ax,bp ; Get the video word
|
||
stosw ; Store the video word
|
||
sti ; Allow interrupts
|
||
loop x4 ; Go do next word
|
||
jmp short x0
|
||
x7:
|
||
shr cx,1 ; Change bytes to words
|
||
rep movsw
|
||
x0:
|
||
pop ds ; Restore DS
|
||
pop bp ; and BP
|
||
mov sp,bp
|
||
pop bp
|
||
ret 10
|
||
MoveToScreen ENDP
|
||
|
||
; procedure MoveFromScreen(var Source, Dest; Len : Word);
|
||
|
||
MoveFromScreen PROC FAR
|
||
push bp
|
||
mov bp,sp
|
||
push bp ; Save Turbo's BP
|
||
push ds ; and DS
|
||
mov bh,ds:CheckSnow ; Load CheckSnow value
|
||
lds si,dword ptr [bp+12] ; Source pointer into DS:SI
|
||
les di,dword ptr [bp+8] ; Dest pointer into ES:DI
|
||
mov cx,[bp+6] ; Len value into CX
|
||
cmp cx,0 ; Quit if Len = 0
|
||
je y0
|
||
cmp si,di
|
||
jle y1
|
||
cld ; Set string direction to forward
|
||
jmp short y2
|
||
y1:
|
||
add si,cx
|
||
sub si,2
|
||
add di,cx
|
||
sub di,2
|
||
std
|
||
y2:
|
||
cmp bh,0
|
||
je y6
|
||
y3:
|
||
shr cx,1 ; Change bytes to words
|
||
mov dx,3DAh ; Point DX to CGA status port
|
||
y4:
|
||
in al,dx ; Get 6845 status
|
||
rcr al,1 ; Check horizontal retrace
|
||
jb y4 ; Loop if in horizontal retrace: this prevents
|
||
; starting in mid-retrace, since there is
|
||
; exactly enough time for 1 and only 1 LODSW
|
||
; during horizontal retrace
|
||
cli ; No ints during critical section
|
||
y5:
|
||
in al,dx ; Get 6845 status
|
||
rcr al,1 ; Check for horizontal retrace: LODSW is 1
|
||
; clock cycle slower than STOSW; because of
|
||
; this, the vertical retrace trick can't be
|
||
; used because it causes flicker! (RCR AL,1
|
||
; is 1 cycle faster than AND AL,AH)
|
||
jnb y5 ; Loop if not in retrace
|
||
lodsw ; Load the video word
|
||
sti ; Allow interrupts
|
||
stosw ; Store the video word
|
||
loop y4 ; Go do next word
|
||
jmp short y0
|
||
y6:
|
||
shr cx,1 ; Change bytes to words
|
||
rep movsw
|
||
y0:
|
||
pop ds ; Restore DS
|
||
pop bp ; and BP
|
||
mov sp,bp
|
||
pop bp
|
||
ret 10
|
||
MoveFromScreen ENDP
|
||
|
||
CODE ENDS
|
||
|
||
END
|
||
|