home *** CD-ROM | disk | FTP | other *** search
-
- ; 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