home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Turbo Toolbox
/
Turbo_Toolbox.iso
/
turbo4
/
mcmvsmem.asm
< prev
next >
Wrap
Assembly Source File
|
1987-12-08
|
5KB
|
144 lines
; Copyright (c) 1985, 87 by Borland International, Inc.
TITLE MCMVSMEM
DATA SEGMENT WORD PUBLIC ; "MicroCalc MoVe Screen MEMory"
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 ; Schreiben in den Bildspeicher
push bp
mov bp,sp
push bp ; BP-Reg (= SP)
push ds ; und DS sichern
mov bh,ds:CheckSnow ; Variable CheckSnow -> BH
lds si,dword ptr [bp+12] ; Parm "Source" -> DS:SI
les di,dword ptr [bp+8] ; Parm "Dest" -> ES:DI
mov cx,[bp+6] ; Parm "Len" -> CX
cmp cx,0 ; Ende, wenn Länge = 0
je x0
cmp si,di
jle x1
cld ; aufsteigende Adressen
jmp short x2
x1:
add si,cx
sub si,2
add di,cx
sub di,2
std
x2:
cmp bh,0 ; Snow-Check notwendig?
je x7 ; nein -> 2 Bytes auf einmal
x3:
shr cx,1 ; zählt nicht Bytes, sondern Wörter
mov dx,3DAh ; Status-Register des CGA
mov bl,9 ; Maske für "Retrace" -> BL
x4:
lodsw ; ein Wort von "Source"
mov bp,ax ; in BP zwischenspeichern
x5:
in al,dx ; Status des Video-Controllers
rcr al,1 ; horizontaler Rücklauf?
jb x5 ; wenn ja: Wiederholung! (Wir müssen auf den
; Anfang des Rücklaufs warten, weil exakt
; ein einziger STOSW-Befehl zeitlich drin
; ist - nicht mehr)
cli ; keine Störungsversuche, bitte
x6:
in al,dx ; erneute Status-Abfrage
and al,bl ; nur vertikaler Rücklauf? Hier lassen
; sich mehrere Speicherzugriffe hinterein-
; ander ausführen
jz x6 ; nein... Wiederholung
mov ax,bp ; o.k. Ein Wort von "Source" lesen
stosw ; und in den Bildspeicher schreiben
sti ; Interrupts wieder erlaubt
loop x4 ; nächstes Wort von "Source" lesen
jmp short x0
x7:
shr cx,1 ; KEIN SNOW-CHECK: Hier werden einfach
rep movsw ; "Len" Bytes (= CX / 2 Wörter) kopiert
x0:
pop ds ; DS-Reg
pop bp ; und BP wieder vom Stack
mov sp,bp
pop bp
ret 10 ; Rücksprung, 10 Bytes Parameter vom Stack
MoveToScreen ENDP
; procedure MoveFromScreen(var Source, Dest; Len : Word);
MoveFromScreen PROC FAR ; Lesen vom Bildspeicher
push bp
mov bp,sp
push bp ; BP-Reg (= SP)
push ds ; und DS sichern
mov bh,ds:CheckSnow ; Variable CheckSnow -> H
lds si,dword ptr [bp+12] ; Parm "Source" -> DS:SI
les di,dword ptr [bp+8] ; Parm "Dest" -> ES:DI
mov cx,[bp+6] ; Parm "Len" -> CX
cmp cx,0 ; Ende, wenn Bytezahl = 0
je y0
cmp si,di
jle y1
cld ; aufsteigende Adressen
jmp short y2
y1:
add si,cx
sub si,2
add di,cx
sub di,2
std
y2:
cmp bh,0 ; Snow-Check notwendig?
je y6 ; nein, direktes Schreiben
y3:
shr cx,1 ; zählt nicht Bytes, sondern Wörter
mov dx,3DAh ; Status-Register des CGA
y4:
in al,dx ; Status lesen
rcr al,1 ; horizontaler Rücklauf?
jb y4 ; Wenn ja: Wiederholung! (siehe oben)
cli ; keine Interrupts, bitte
y5:
in al,dx ; Status erneut lesen
rcr al,1 ; Prüfung auf horizontalen Rücklauf: LODSW
; braucht einen Takt länger als STOSW -
; deshalb geht der Trick mit dem vertikalen
; Rücklauf hier nicht! (RCR AL,1 ist einen
; Takt schneller als AND AL,AH)
jnb y5 ; Wiederholung, falls nicht im Rücklauf
lodsw ; o.k. ein Wort vom Bildspeicher laden
sti ; Interrupts wieder erlaubt
stosw ; Speicherung in "Dest"
loop y4 ; nächstes Wort
jmp short y0
y6:
shr cx,1 ; KEIN SNOW-CHECK: Hier werden einfach
rep movsw ; "Len" Bytes (= CX/2 Wörter) kopiert
y0:
pop ds ; DS-Reg
pop bp ; und BP wieder vom Stack
mov sp,bp
pop bp ; Rücksprung, 10 Bytes vom Stack
ret 10 ; (Source, Dest jeweils 4, Len = 2 Bytes)
MoveFromScreen ENDP
CODE ENDS
END