Files
lba1-classic/LIB386/LIB_SVGA/S_PHYS.ASM

930 lines
18 KiB
NASM

;----------------------------------------------------------------------------
; S_PHYS.ASM 386
; (c) Adeline 1993
;----------------------------------------------------------------------------
.386p
jumps
.model SMALL, SYSCALL
;----------------------------------------------------------------------------
.data
include svga.ash
extrn NoLanguage NewBank : DWORD
public NoLanguage ScanLine
public NoLanguage BankSize
public NoLanguage BankOver
public NoLanguage BankShift
public NoLanguage NonStdVESA
ALIGN 4
Diff dd ?
SaveEAX dd ?
SaveEBX dd ?
SaveEDX dd ?
DeltaLog dd ?
ScanLine dd 640
BankSize dd 00000FFFFh
BankOver dd 0FFFF0000h
NonStdVESA db 0
BankShift db 16
CptLine dw 0
;----------------------------------------------------------------------------
.code
public NoLanguage CopyBlockPhysClip
public NoLanguage CopyBlockPhys
public NoLanguage Flip
public NoLanguage Vsync
;----------------------------------------------------------------------------
; Vsync()
;
Vsync proc
mov dx, 03DAh
NotReady: in al, dx
jmp $+2
test al, 08h
jnz short NotReady
Ready: in al, dx
jmp $+2
test al, 08h
jz short Ready
ret
Vsync endp
;----------------------------------------------------------------------------
SuperMovsD macro
shr ecx, 2
rep movsd
mov ecx, ebx
and ecx, 11b
rep movsb
endm
SwitchBank macro
local noswitch
cmp eax, BankCurrent
je noswitch
mov BankCurrent, eax
call [NewBank]
noswitch:
endm
SwitchBankNoTest macro
mov BankCurrent, eax
call [NewBank]
endm
SwitchBankDirect macro
call [NewBank]
endm
ChangeVideoBank macro
mov [SaveEAX], eax
mov eax, BankCurrent
mov [SaveEDX], edx
inc eax
mov BankCurrent, eax
call [NewBank]
mov eax, [SaveEAX]
mov edx, [SaveEDX]
endm
;----------------------------------------------------------------------------
; CopyBlockClip( x0, y0, x1, y1 )
;
CopyBlockPhysClip proc uses esi edi ebx ebp,\
x0:DWORD, y0:DWORD, x1:DWORD, y1:DWORD
mov edx, x0
mov ecx, y0
mov ebx, x1
mov eax, y1
;---------------------- Clipping Source Part 1
cmp edx, ClipXmax
jg CopyBlockPhysClip_End
cmp ebx, ClipXmin
jl CopyBlockPhysClip_End
cmp ecx, ClipYmax
jg CopyBlockPhysClip_End
cmp eax, ClipYmin
jl CopyBlockPhysClip_End
;---------------------- Clipping Source Part 2
cmp edx, ClipXmin ; X0 < ClipXmin ?
jge Ok_X0_L ; A plus tart
mov edx, ClipXmin ; X0 = ClipXmin
Ok_X0_L: cmp ebx, ClipXmax ; X1 > ClipXmax
jle Ok_X1_R ; Goodbye
mov ebx, ClipXmax ; X1 = ClipXmax
Ok_X1_R: cmp ecx, ClipYmin ; Y0 < ClipYmin
jge Ok_Y0_U ; On se casse
mov ecx, ClipYmin ; Y0 = ClipYmin
Ok_Y0_U: cmp eax, ClipYmax ; Y1 > ClipYMax
jle Ok_Y1_D ; A priori non
mov eax, ClipYmax ; Y1 = ClipYmax
Ok_Y1_D:
;---------------------- Compute Delta X & Y
sub ebx, edx ; EBX Delta X
sub eax, ecx ; EAX Delta Y
inc ebx ; EBX = Delta X + 1
inc eax ; EAX = Delta Y + 1
mov esi, TabOffLine[ecx*4] ; y0
add esi, edx ; SI Offset Src
mov edi, esi
mov ebp, eax
mov eax, edi
shr eax, 16
SwitchBank ; Change Bank 64Kb
mov eax, ebp
xor ebp, ebp
add esi, Log
and edi, 0FFFFh ; 64Kb bank
or edi, 0A0000h ; EDI = Phys
mov bp, di ; BP For Bank
mov edx, Screen_X
sub edx, ebx ; DX Delta Screen
;----------------------
Again: add bp, bx
jc NewBankNear0c
mov ecx, ebx
SuperMovsD ; Macro
add esi, edx
add edi, edx
add bp, dx
jc NewBankNear1c
dec eax
jne short Again
;----------------------
CopyBlockPhysClip_End: ret
;-----------------------------------------------------------------------------
NewBankNear0c: mov ecx, ebx
sub ecx, ebp
push ebx ; Sauve EBX
mov ebx, ecx
SuperMovsD ; Macro
ChangeVideoBank : Macro
mov edi, 0A0000h ; Begin Phys
mov ecx, ebp
mov ebx, ebp
SuperMovsD ; Macro
pop ebx ; Restore EBX
add esi, edx
add edi, edx
add bp, dx
jc NewBankNear1c
dec eax
jne Again
ret
;----------------------
NewBankNear1c: ChangeVideoBank ; Macro
sub edi, 010000h ; Stay in Phys
dec eax
jne Again
ret
CopyBlockPhysClip endp
;----------------------------------------------------------------------------
; CopyBlockPhys( x0, y0, x1, y1 )
;
CopyBlockPhys proc uses esi edi ebx ebp,\
x0:DWORD, y0:DWORD, x1:DWORD, y1:DWORD
cmp [NonStdVESA], 0
jne CopyBlockPhys2
mov edx, x0
mov ecx, y0
mov ebx, x1
mov eax, y1
;---------------------- Compute Delta X & Y
sub ebx, edx ; EBX Delta X
sub eax, ecx ; EAX Delta Y
inc ebx ; EBX = Delta X + 1
inc eax ; EAX = Delta Y + 1
;---------------------- Compute Adresse
mov esi, TabOffLine[ecx*4]
add esi, edx
mov edi, esi
mov ebp, eax
mov eax, edi
shr eax, 16
SwitchBank ; Change Bank 64Kb
mov eax, ebp
add esi, Log
xor ebp, ebp
and edi, 0FFFFh ; 64Kb bank
or edi, 0A0000h ; EDI = Phys
mov bp, di ; BP For Bank
mov edx, Screen_X
sub edx, ebx ; DX Delta Screen
;----------------------
Again: add bp, bx
jc NewBankNear0p
mov ecx, ebx
SuperMovsD ; Macro
add esi, edx
add edi, edx
add bp, dx
jc NewBankNear1p
dec eax
jne short Again
;----------------------
ret
;-----------------------------------------------------------------------------
NewBankNear0p: mov ecx, ebx
sub ecx, ebp
mov [SaveEBX], ebx ; Sauve EBX
mov ebx, ecx
SuperMovsD ; Macro
ChangeVideoBank : Macro
mov edi, 0A0000h ; Begin Phys
mov ecx, ebp
mov ebx, ebp
SuperMovsD ; Macro
mov ebx, [SaveEBX] ; Restore EBX
add esi, edx
add edi, edx
add bp, dx
jc NewBankNear1p
dec eax
jne Again
ret
;----------------------
NewBankNear1p: ChangeVideoBank ; Macro
sub edi, 010000h ; Stay in Phys
dec eax
jne Again
ret
;----------------------------------------------------------------------------
; CopyBlockPhys( x0, y0, x1, y1 )
;
CopyBlockPhys2: mov edx, x0
mov ecx, y0
mov ebx, x1
mov eax, y1
;---------------------- Compute Delta X & Y
sub ebx, edx ; EBX Delta X
sub eax, ecx ; EAX Delta Y
inc ebx ; EBX = Delta X + 1
inc eax ; EAX = Delta Y + 1
;---------------------- Compute Adresse
mov edi, ecx
imul edi, [ScanLine]
add edi, edx
mov [SaveEDX], edx
mov ebp, eax
mov esi, ecx
mov eax, edi
mov cl, [BankShift]
shr eax, cl
SwitchBank ; Change Bank
mov ecx, esi
mov eax, ebp
mov edx, [SaveEDX]
mov esi, TabOffLine[ecx*4]
add esi, edx
add esi, Log
and edi, [BankSize] ; bank size
mov ebp, edi ; BP For Bank
or edi, 0A0000h ; EDI = Phys
mov edx, Screen_X
sub edx, ebx ; DX Delta Log
mov [DeltaLog], edx
mov edx, [ScanLine]
sub edx, ebx ; DX Delta Phys
;----------------------
Again2: add ebp, ebx
test ebp, [BankOver]
jnz NewBankNear0p2
mov ecx, ebx
SuperMovsD ; Macro
add esi, [DeltaLog]
add edi, edx
add ebp, edx
test ebp, [BankOver]
jnz NewBankNear1p2
dec eax
jne Again2
;----------------------
ret
;-----------------------------------------------------------------------------
NewBankNear0p2: and ebp, [BankSize]
mov ecx, ebx
sub ecx, ebp
mov [SaveEBX], ebx ; Sauve EBX
mov ebx, ecx
SuperMovsD ; Macro
ChangeVideoBank : Macro
mov edi, 0A0000h ; Begin Phys
mov ecx, ebp
mov ebx, ebp
SuperMovsD ; Macro
mov ebx, [SaveEBX] ; Restore EBX
add esi, [DeltaLog]
add edi, edx
add ebp, edx
test ebp, [BankOver]
jnz NewBankNear1p2
dec eax
jne Again2
ret
;----------------------
NewBankNear1p2: ChangeVideoBank ; Macro
sub edi, [BankSize] ; Stay in Phys
and ebp, [BankSize]
dec edi
dec eax
jne Again2
ret
CopyBlockPhys endp
;----------------------------------------------------------------------------
;----------------------------------------------------------------------------
; Flip()
;
; Attention: de Log (mémoire) vers Phys (vidéo ram) à modifier
;
Flip proc
cmp [NonStdVESA], 0
jne flip2
push esi
push edi
mov esi, Log
mov eax, 0
SwitchBank
mov edi, Phys
mov ecx, 04000h
rep movsd
mov eax, 1
SwitchBankDirect
mov edi, Phys
mov ecx, 04000h
rep movsd
mov eax, 2
SwitchBankDirect
mov edi, Phys
mov ecx, 04000h
rep movsd
mov eax, 3
SwitchBankDirect
mov edi, Phys
mov ecx, 04000h
rep movsd
mov eax, 4
SwitchBankNoTest
mov edi, Phys
mov ecx, 02C00h
rep movsd
pop edi
pop esi
ret
flip2: push 479
push 639
push 0
push 0
call CopyBlockPhys
add esp, 16
ret
Flip endp
;----------------------------------------------------------------------------
comment @
{' EN COMMENTAIRE
SuperIncrust MACRO
local Again, OkCopy, EndLine, UntilEnd
push ebx
xor eax, eax ; Je cherche != 0
Again:
xchg esi, edi
rep scasb ; Arret quand != 0
jne OkCopy ; Ok Data Rencontrée(s)
;-----------------------
add esi, ebx
xchg esi, edi
jmp EndLine ; c'est fini!
;-----------------------
OkCopy: dec edi ; EDI un peu trop loin
inc ecx ; ECX trop Petit
sub ebx, ecx ; EBX = Bytes Parcourus
add esi, ebx ; Maj ESI
mov ebx, ecx ; EBX = Bytes Restant
repne scasb ; Combien != 0 ?
jne UntilEnd ; Tous jusqu'a fin (Quick!
inc ecx ; Maj ECX
dec edi ; Maj EDI
sub ebx, ecx ; EBX = Nb Same Bytes
sub edi, ebx ; Recule EDI
xchg esi, edi ; Log <=> Phys
xchg ecx, ebx
rep movsb ; movsD Plus Tard!
mov ecx, ebx
jmp Again
UntilEnd:
sub edi, ebx
xchg esi, edi
mov ecx, ebx
rep movsb
EndLine:
pop ebx
endm
;----------------------------------------------------------------------------
; Log -> Phys
; CopyBlockIncrust( x0, y0, x1, y1 )
;
CopyBlockIncrust proc uses esi edi ebx ebp,\
x0:DWORD, y0:DWORD, x1:DWORD, y1:DWORD
mov edx, x0
mov ecx, y0
mov ebx, x1
mov eax, y1
;---------------------- Compute Delta X & Y
sub ebx, edx ; EBX Delta X
sub eax, ecx ; EAX Delta Y
inc ebx ; EBX = Delta X + 1
inc eax ; EAX = Delta Y + 1
mov word ptr [CptLine], ax
;---------------------- Compute Adresse
mov esi, TabOffLine[ecx*4]
add esi, edx
mov edi, esi
mov eax, edi
shr eax, 16
SwitchBank ; Change Bank 64Kb
add esi, Log
xor ebp, ebp
and edi, 0FFFFh ; 64Kb bank
or edi, 0A0000h ; EDI = Phys
mov bp, di ; BP For Bank
mov edx, Screen_X
sub edx, ebx ; DX Delta Screen
;----------------------
Again: add bp, bx
jc NewBankNear0i
mov ecx, ebx
SuperIncrust
add esi, edx
add edi, edx
add bp, dx
jc NewBankNear1i
dec word ptr [CptLine]
jne short Again
;----------------------
ret
;----------------------
NewBankNear0i: mov ecx, ebx
sub ecx, ebp
push ebx ; Sauve EBX
mov ebx, ecx
SuperIncrust ; Macro
ChangeVideoBank : Macro
mov edi, 0A0000h ; Begin Phys
mov ecx, ebp
mov ebx, ecx
SuperIncrust
pop ebx ; Restore EBX
add esi, edx
add edi, edx
add bp, dx
jc NewBankNear1i
dec word ptr [CptLine]
jne Again
ret
;----------------------
NewBankNear1i: ChangeVideoBank ; Macro
sub edi, 010000h ; Stay in Phys
dec word ptr [CptLine]
jne Again
ret
CopyBlockIncrust endp
;----------------------------------------------------------------------------
;----------------------------------------------------------------------------
FlipComp proc uses esi edi ebx ebp,\
log0:DWORD, log1:DWORD
mov esi, log0 ; ESI = log0
mov edi, log1 ; EDI = log1
call Vsync
;-------------------------------------------------------
Bank0: mov eax, 0 ; Bank 0
SwitchBank ; De l'ecran Phys
mov eax, esi ; EAX = log0
sub eax, 0A0000h ; EAX = log0-Phys
mov ecx, 04000h ; 64Kb
Cont0:
rep cmpsd ; Cherche Difference
jne Diff0 ; Il y a Difference
;----------------------
Bank1: mov eax, 1 ; Bank 1
SwitchBank ; De l'ecran Phys
mov eax, esi ; Maj offset Phys
sub eax, 0A0000h ; Car Nouvelle Bank
mov ecx, 04000h ; 64Kb
Cont1:
rep cmpsd ; Cherche Difference
jne Diff1 ; Il y a Difference
;----------------------
Bank2: mov eax, 2 ; Bank 1
SwitchBank ; De l'ecran Phys
mov eax, esi ; Maj offset Phys
sub eax, 0A0000h ; Car Nouvelle Bank
mov ecx, 04000h ; 64Kb
Cont2:
rep cmpsd ; Cherche Difference
jne Diff2 ; Il y a Difference
;----------------------
Bank3: mov eax, 3 ; Bank 1
SwitchBank ; De l'ecran
mov eax, esi ; Maj offset Phys
sub eax, 0A0000h ; Car Nouvelle Bank
mov ecx, 04000h ; 64Kb
Cont3:
rep cmpsd ; Cherche Difference
jne Diff3 ; Il y a Difference
;----------------------
Bank4: mov eax, 4 ; Bank 1
SwitchBank ; De l'ecran
mov eax, esi ; Maj offset Phys
sub eax, 0A0000h ; Car Nouvelle Bank
mov ecx, 02C00h ; 64Kb
Cont4:
rep cmpsd ; Cherche Difference
jne Diff4 ; Il y a Difference
;----------------------
ret
;-------------------------------------------------------
Diff0: sub esi, 4 ; Recule ESI
sub edi, 4 ; Recule EDI
inc ecx ; One More
mov edx, esi ; Sauve ESI
mov ebx, ecx ; Sauve ECX
repne cmpsd ; Combien ?
sub edi, 4 ; Recule EDI
mov esi, edx ; Restore ESI
mov edx, edi ; Sauve EDI
inc ecx ; One More
sub ebx, ecx ; Calcul Nb Diffs
xchg ecx, ebx ; Sauve ECX
mov edi, esi ; Calcul
sub edi, eax ; Adresse Phys
rep movsd ; Ecriture Diffs
mov edi, edx ; Restore EDI
add ecx, ebx ; Restore ECX
je Bank1 ; Fin De cette Bank
jmp Cont0 ; Again and Again...
;----------------------
Diff1: sub esi, 4 ; Recule ESI
sub edi, 4 ; Recule EDI
inc ecx ; One More
mov edx, esi ; Sauve ESI
mov ebx, ecx ; Sauve ECX
repne cmpsd ; Combien ?
sub edi, 4 ; Recule EDI
mov esi, edx ; Restore ESI
mov edx, edi ; Sauve EDI
inc ecx ; One More
sub ebx, ecx ; Calcul Nb Diffs
xchg ecx, ebx ; Sauve ECX
mov edi, esi ; Calcul
sub edi, eax ; Adresse Phys
rep movsd ; Ecriture Diffs
mov edi, edx ; Restore EDI
add ecx, ebx ; Restore ECX
je Bank2 ; Fin De cette Bank
jmp Cont1 ; Again and Again...
;----------------------
Diff2: sub esi, 4 ; Recule ESI
sub edi, 4 ; Recule EDI
inc ecx ; One More
mov edx, esi ; Sauve ESI
mov ebx, ecx ; Sauve ECX
repne cmpsd ; Combien ?
sub edi, 4 ; Recule EDI
mov esi, edx ; Restore ESI
mov edx, edi ; Sauve EDI
inc ecx ; One More
sub ebx, ecx ; Calcul Nb Diffs
xchg ecx, ebx ; Sauve ECX
mov edi, esi ; Calcul
sub edi, eax ; Adresse Phys
rep movsd ; Ecriture Diffs
mov edi, edx ; Restore EDI
add ecx, ebx ; Restore ECX
je Bank3 ; Fin De cette Bank
jmp Cont2 ; Again and Again...
;----------------------
Diff3: sub esi, 4 ; Recule ESI
sub edi, 4 ; Recule EDI
inc ecx ; One More
mov edx, esi ; Sauve ESI
mov ebx, ecx ; Sauve ECX
repne cmpsd ; Combien ?
sub edi, 4 ; Recule EDI
mov esi, edx ; Restore ESI
mov edx, edi ; Sauve EDI
inc ecx ; One More
sub ebx, ecx ; Calcul Nb Diffs
xchg ecx, ebx ; Sauve ECX
mov edi, esi ; Calcul
sub edi, eax ; Adresse Phys
rep movsd ; Ecriture Diffs
mov edi, edx ; Restore EDI
add ecx, ebx ; Restore ECX
je Bank4 ; Fin De cette Bank
jmp Cont3 ; Again and Again...
;----------------------
Diff4: sub esi, 4 ; Recule ESI
sub edi, 4 ; Recule EDI
inc ecx ; One More
mov edx, esi ; Sauve ESI
mov ebx, ecx ; Sauve ECX
repne cmpsd ; Combien ?
sub edi, 4 ; Recule EDI
mov esi, edx ; Restore ESI
mov edx, edi ; Sauve EDI
inc ecx ; One More
sub ebx, ecx ; Calcul Nb Diffs
xchg ecx, ebx ; Sauve ECX
mov edi, esi ; Calcul
sub edi, eax ; Adresse Phys
rep movsd ; Ecriture Diffs
mov edi, edx ; Restore EDI
add ecx, ebx ; Restore ECX
jne Cont4 ; Again and Again
ret
FlipComp endp
;----------------------------------------------------------------------------
.386
FlipComp386 proc uses ds es si di, \
scr0:DWORD, scr1:DWORD
mov dx, word ptr [scr0+2] ; dx = Log0
mov ds, word ptr [scr1+2] ; ds = Log1
mov ax, 0A000h ; Phys
xor si, si ; Maj Offset
mov di, si ; a zero
mov cx, 07D00h/2 ; 100 Lines * 4 (LONG)
Aqui:
mov es, dx ; es = Log0
rep cmpsd ; Comp Log0 & Log1
je TheEnd ; No difference, End
mov bp, si ; Save offset in BP
mov bx, cx ; Save Nb Left
repne cmpsd ; How many difference(s) ?
jne UntilEnd ; All left are different...
mov es, ax
sub bp, 4 ; Maj BP
mov si, bp ; Maj Offset SI
mov di, bp ; & DI
sub bx, cx ; How much in BX
xchg cx, bx ; Now in CX
rep movsd ; Copy CX Bytes Log1->Phys
mov cx, bx ; Restore Bytes Left
inc cx
inc cx
jmp short Aqui ; Twist again
UntilEnd:
mov es, ax ; ES = Phys
sub bp, 4 ; Maj BP
mov si, bp ; Maj offset SI
mov di, bp ; & DI
sub bx, cx ; How much left in BX
mov cx, bx ; Now in CX ( ex: XCHG CX,BX )
inc cx
inc cx
rep movsd
TheEnd: .8086
ret
FlipComp386 endp
;----------------------------------------------------------------------------
opt_stos_line macro
mov eax, ecx
shr ecx, 2
rep movsd
and eax, 3
mov ecx, eax
rep movsb
endm
;----------------------------------------------------------------------------
; Flip de Log vers Phys
BlockLogPhys proc uses es ds si di,\
sox:DWORD,soy:DWORD,sol:DWORD,soh:DWORD,\
dex:DWORD,dey:DWORD
mov esi, soy
mov esi, TabOffLine[esi*4]
add esi, soy
mov edi, esi
mov eax, edi
shr eax, 16
SwitchBank
add esi, Log
add edi, Phys
mov di,bx
xor ebx,ebx
mov ax,0A000h
mov es,ax
mov ax, sol
mov cs:word ptr[patch_larg1],ax
mov cs:word ptr[patch_larg2],ax
mov cs:word ptr[patch_larg3],ax
neg ax
add ax,640
mov cs:word ptr[patch_deoff],ax
mov ax,320
sub ax, sol
mov cs:word ptr[patch_sooff],ax
jmp $+2
mov dx, soh
Aqui: mov ebx, edi
add ebx, sol
jnc ok1
mov ecx, sol
sub ecx, ebx
opt_stos_line
mov eax, BankCurrent
inc eax
SwitchBank
mov ecx, ebx
opt_stos_line
jmp Next
ok1: xor ecx, ecx
mov ecx, sol
opt_stos_line
Next: mov edi, ebx
patch_deoff equ $+2
add edi, 1234h
jnc ok2
mov eax, BankCurrent
inc eax
push eax
SwitchBank
ok2:
patch_sooff equ $+2
add esi,1234h
dec edx
jnz Aqui
ret
BlockLogPhys endp
}
@
;----------------------------------------------------------------------------
; The
End