{****************************************************************************}
{Modul VENOMBNK.INC - it is a part of the VenomGFX unit and adds some support}
{for routines which use the banking access into videomemory                  }
{      written by Laaca                                                      }
{****************************************************************************}

const bank_KB64:longint=65536; {udelat to jako konstantu prostou nejde}
                               {protoze instrukce DIV neumi zpracovat primo}
                               {specifikovanou hodnotu. Umi jen registr nebo}
                               {promennou}

      bank_zapis:longint = 1;  {defaultni chovani je rutina, ktera na}
                               {obrazovku zapisuje a necte ji}

var bank_xxx,bank_zzz,bank_bank2,bank_zbytek2,bank_lines,bank_ecx,
    bank_edi:longint;
    bank_hc:word;

Procedure NavysBank;assembler;{$IFDEF EnableInline}inline;{$ENDIF}
{Input:    bank_wr or bank_rd (longint) - actual bank

 Output:   none
 Destroys: EAX, EDX, high word of EBX}
asm
shl ebx,16
cmp bank_zapis,0
jz @probiha_cteci_rutina
   mov edx,bank_wr
   add edx,grann     {granularita muze byt<>64}
   mov bank_wr,edx
   Call SetBank_wr
   jmp @Konec


@probiha_cteci_rutina:
   mov edx,bank_rd
   add edx,grann     {granularita muze byt<>64}
   mov bank_rd,edx
   Call SetBank_rd
@konec:
shr ebx,16
end;


Procedure BankShowTestScreen;assembler;
var clr,mg:longint;
asm
push es
mov es,vga.segment
xor edx,edx
mov mg,0

@znovu:
mov edi,seg_wr   {start, odkud zapisovat}
mov ecx,edx
call SetBank_wr    {Nastavi bank}
mov edx,ecx
mov ecx,16384
mov eax,clr

mov clr,$2f2f2f2f
test mg,1
jz @hop
mov clr,$aa44aa44
@hop:
inc mg
mov eax,clr
rep stosd

add edx,grann
cmp edx,bisgm
jbe @znovu
pop es
end;


Procedure BankFlip_SVGA_and_clrscr(var source:virtualwindow;c:word);assembler;
var po:array[0..1] of longint;
asm
   push es
   mov es,vga.segment
   mov esi,source
   mov esi,ds:[esi+2]   { ziskani offsetu }
   xor edx,edx
   mov bx,c
   shl ebx,16
   mov bx,c

cmp cpu_info_mmx,0
je @NoMMX_so_Jump

MovD mm0,ebx
MovD mm1,ebx
Psllq mm0,32
Paddusw mm0,mm1
MovQ po,mm0

Cmp cpu_info_emmx,0
je @go_mmx

  @Dalsi_Bank_EMMX:
   mov ecx,edx     { EDX je volanim znicen, je treba ho uschovat }
   call SetBank_wr    {Nastavi bank}
   mov edx,ecx
   mov edi,seg_wr   {start, odkud zapisovat}
  mov ecx,1024
  @SCHLEIFE_EMMX:   {Kdyz je podporovano EMMX}
     MovQ mm0,[esi    ];MovQ mm1,[esi+  8];
     MovQ mm2,[esi+ 16];MovQ mm3,[esi+ 24];
     MovQ mm4,[esi+ 32];MovQ mm5,[esi+ 40];
     MovQ mm6,[esi+ 48];MovQ mm7,[esi+ 56];
     MovntQ es:[edi    ],mm0;MovntQ es:[edi+  8],mm1;
     MovntQ es:[edi+ 16],mm2;MovntQ es:[edi+ 24],mm3;
     MovntQ es:[edi+ 32],mm4;MovntQ es:[edi+ 40],mm5;
     MovntQ es:[edi+ 48],mm6;MovntQ es:[edi+ 56],mm7
     movq mm0,po
     MovntQ [esi    ],mm0;MovntQ [esi+  8],mm0;
     MovntQ [esi+ 16],mm0;MovntQ [esi+ 24],mm0;
     MovntQ [esi+ 32],mm0;MovntQ [esi+ 40],mm0;
     MovntQ [esi+ 48],mm0;MovntQ [esi+ 56],mm0
  Add esi,64
  Add edi,64
  Dec ecx
  JNZ @SCHLEIFE_EMMX

  add edx,grann
  cmp edx,bisgm
  jbe @Dalsi_Bank_EMMX
  emms
  jmp @spojeni

@go_mmx: {vstupne EDX=0}
   @Dalsi_Bank_MMX:
   mov ecx,edx     { EDX je volanim znicen, je treba ho uschovat }
   call SetBank_wr    {Nastavi bank}
   mov edx,ecx
   mov edi,seg_wr   {start, odkud zapisovat}

  mov ecx,1024
  @SCHLEIFE_MMX:   {Kdyz je podporovano MMX, ale ne EMMX}
     MovQ mm0,[esi    ];MovQ mm1,[esi+  8];
     MovQ mm2,[esi+ 16];MovQ mm3,[esi+ 24];
     MovQ mm4,[esi+ 32];MovQ mm5,[esi+ 40];
     MovQ mm6,[esi+ 48];MovQ mm7,[esi+ 56];
     MovQ es:[edi    ],mm0;MovQ es:[edi+  8],mm1;
     MovQ es:[edi+ 16],mm2;MovQ es:[edi+ 24],mm3;
     MovQ es:[edi+ 32],mm4;MovQ es:[edi+ 40],mm5;
     MovQ es:[edi+ 48],mm6;MovQ es:[edi+ 56],mm7
     movq mm0,po
     MovQ [esi    ],mm0;MovQ [esi+  8],mm0;
     MovQ [esi+ 16],mm0;MovQ [esi+ 24],mm0;
     MovQ [esi+ 32],mm0;MovQ [esi+ 40],mm0;
     MovQ [esi+ 48],mm0;MovQ [esi+ 56],mm0
  Add esi,64
  Add edi,64
  Dec ecx
  JNZ @SCHLEIFE_MMX

  add edx,grann
  cmp edx,bisgm
  jbe @Dalsi_Bank_MMX
  emms
  jmp @spojeni

@NoMMX_so_Jump:
push ebx
   @Dalsi_Bank:
   mov ecx,edx     { EDX je volanim znicen, je treba ho uschovat }
   call SetBank_wr    {Nastavi bank}
   mov edx,ecx
   mov edi,seg_wr   {start, odkud zapisovat}
   mov ecx,16384
pop ebx
@smycka:
   mov eax,ebx
   xchg eax,[esi]
   mov es:[edi],eax
   add edi,4
   add esi,4
   dec ecx
   jnz @smycka

   add edx,grann
   cmp edx,bisgm
   jbe @Dalsi_Bank

@spojeni:
mov eax,numm
mov bank_wr,eax
pop es
end;


Procedure BankFlip_SVGA(var source:virtualwindow);assembler;
asm
push es
mov es,VGA.segment
mov esi,source
mov esi,ds:[esi+2]   { ziskani offsetu }
xor edx,edx

cmp cpu_info_mmx,0
je @NoMMX_so_Jump
Cmp cpu_info_emmx,0
je @go_mmx

  @Dalsi_Bank_EMMX:
   mov ecx,edx     { EDX je volanim znicen, je treba ho uschovat }
   call SetBank_wr    {Nastavi bank}
   mov edx,ecx
   mov edi,seg_wr
  mov ecx,1024
  @SCHLEIFE_EMMX:   {Kdyz je podporovano EMMX}
     MovQ mm0,[esi    ];MovQ mm1,[esi+  8];
     MovQ mm2,[esi+ 16];MovQ mm3,[esi+ 24];
     MovQ mm4,[esi+ 32];MovQ mm5,[esi+ 40];
     MovQ mm6,[esi+ 48];MovQ mm7,[esi+ 56];
     MovntQ es:[edi    ],mm0;MovntQ es:[edi+  8],mm1;
     MovntQ es:[edi+ 16],mm2;MovntQ es:[edi+ 24],mm3;
     MovntQ es:[edi+ 32],mm4;MovntQ es:[edi+ 40],mm5;
     MovntQ es:[edi+ 48],mm6;MovntQ es:[edi+ 56],mm7
  Add esi,64
  Add edi,64
  Dec ecx
  JNZ @SCHLEIFE_EMMX

  add edx,grann
  cmp edx,bisgm
  jbe @Dalsi_Bank_EMMX
  emms
  jmp @spojeni

@go_mmx:
   @Dalsi_Bank_MMX:
   mov ecx,edx     {EDX je volanim znicen, je treba ho uschovat}
   call SetBank_wr    {Nastavi bank}
   mov edx,ecx
   mov edi,seg_wr
  mov ecx,1024
  @SCHLEIFE_MMX:   {Kdyz je podporovano MMX, ale ne EMMX}
     MovQ mm0,[esi    ];MovQ mm1,[esi+  8];
     MovQ mm2,[esi+ 16];MovQ mm3,[esi+ 24];
     MovQ mm4,[esi+ 32];MovQ mm5,[esi+ 40];
     MovQ mm6,[esi+ 48];MovQ mm7,[esi+ 56];
     MovQ es:[edi    ],mm0;MovQ es:[edi+  8],mm1;
     MovQ es:[edi+ 16],mm2;MovQ es:[edi+ 24],mm3;
     MovQ es:[edi+ 32],mm4;MovQ es:[edi+ 40],mm5;
     MovQ es:[edi+ 48],mm6;MovQ es:[edi+ 56],mm7
  Add esi,64
  Add edi,64
  Dec ecx
  JNZ @SCHLEIFE_MMX

  add edx,grann
  cmp edx,bisgm
  jbe @Dalsi_Bank_MMX
  emms
  jmp @spojeni


@NoMMX_so_Jump:
   @Dalsi_Bank:
   mov ecx,edx     { EDX je volanim znicen, je treba ho uschovat }
   call SetBank_wr    {Nastavi bank}
   mov edx,ecx
   mov edi,seg_wr

   mov ecx,16384
   rep movsd

   add edx,grann
   cmp edx,bisgm
   jbe @Dalsi_Bank

@spojeni:
mov eax,numm
mov bank_wr,eax
pop es
end;



Procedure StartPosition_into_EDI;assembler;{$IFDEF EnableInline}inline;{$ENDIF}
{INPUT:   EBX = start position (upper left corner)
          ECX = line length in bytes (usually set by clipping procedure)
          EDX = number of processed lines (usually set by clipping procedure)
          EDI = VGA variable in VirtualWindow type
          DS musn't be changed!


 OUTPUT:  EDI = final adress of starting position
          Bank_lines = number of processsed lines (copied EDX value)

Does't change other registers}
asm
mov edi,[edi+26]       {ByteBreite}
mov bank_xxx,edi
mov bank_lines,edx     {pocet radku zkopirujeme do bank_lines}
mov bank_ecx,ecx
mov edi,ebx
end;


Procedure StartPosition_into_ESI;assembler;{$IFDEF EnableInline}inline;{$ENDIF}
{INPUT:  EAX - start position in sprite (usually set by clipping proc)
         ESI - sprite of VirtualWindow format

 OUTPUT: ESI - final starting position in sprite
         EAX,Bank_ZZZ - ByteBreite of sprite}
asm
add eax,[esi+2]
mov esi,[esi+26]
xchg esi,eax
mov bank_zzz,eax
end;



Procedure PrepareLine;assembler;{$IFDEF EnableInline}inline;{$ENDIF}
{INPUT:   EDI = actual position on screen

 OUTPUT:   ECX = number of bytes to be copied in line before bank switch
           Bank_Zbytek2 = number of lines to be copied in line after bank
                          switch

           Bank_EDI = copy of all 32 bits of EDI
           EDI = clears the high word of EDI

 DESTROYS: EDX
           high word in EBX}
asm
{napred zjistim bank na konci radky}
mov ecx,bank_ecx
add ecx,edi;sub ecx,2   {v ECX ted bude koncova pozice radky}
xor edx,edx
xchg eax,ecx            {v ECX je ulozeno EAX, ktere naopak prepsano z ECX}
div bank_kb64
mov bank_bank2,eax
mov bank_zbytek2,edx
add bank_zbytek2,2

{a ted na zacatku radky}
xor edx,edx
mov eax,edi
div bank_kb64              {bank na zacatku radky bude v EAX}

cmp bank_zapis,0
jz @cteci_operace     {pro rutiny ktere na obrazovku zapisuji}
   cmp eax,bank_wr            {je to jiny bank nez prave pouzivany?}
   jz @nemenbank1
      mov bank_wr,eax         {jestli ano, tak musime prepnout}
      mov edx,eax
      shl ebx,16
      Call SetBank_wr
      shr ebx,16
   @nemenbank1:
   mov edx,bank_wr
   jmp @zapis_i_cteni

@cteci_operace:       {pro rutiny, ktere z obrazovky ctou}
   cmp eax,bank_rd            {je to jiny bank nez prave pouzivany?}
   jz @nemenbank2
      mov bank_rd,eax         {jestli ano, tak musime prepnout}
      mov edx,eax
      shl ebx,16
      Call SetBank_rd
      shr ebx,16
   @nemenbank2:
   mov edx,bank_rd

@zapis_i_cteni:  {ted uz zase spolecne pro zapis i cteni}
mov eax,ecx                {ted uz muzu obnovit EAX}
mov ecx,bank_ecx

cmp edx,bank_bank2         {Je bank na konci radky jiny nez na zacatku?}

jz @NebudePrepnutiBanku
   sub ecx,bank_zbytek2
   jmp @spoj

@NebudePrepnutiBanku:
   mov bank_zbytek2,0
@spoj:

mov bank_edi,edi           {ulozim 32-bitove EDI}
and edi,0000ffffh          {a udelam z nej 16-bitove}

cmp bank_zapis,0
jz @cteci_segment
    add edi,seg_wr
    jmp @konec

@cteci_segment:
    add edi,seg_rd

@konec:
end;


Procedure PrepareLine2;assembler;{$IFDEF EnableInline}inline;{$ENDIF}
{INPUT:    nothing in registers

 OUTPUT:   ZF: 0 = we are not finished, we have to switch bank and continue
               1 = we are finished, let's do next line

           ECX = number of bytes to copy
           EDI = set to new position after second part of line

 DESTROYS: EDX, high word of EBX}
asm
cmp bank_zbytek2,0      {je treba prepnout bank?}
jz @Radka_hotova
    push eax
    Call NavysBank
    pop eax
    mov ecx,bank_zbytek2
    cmp bank_zapis,0
    jz @cteci_rutina
       mov edi,seg_wr
       jmp @spoj

    @cteci_rutina:
       mov edi,seg_rd

    @spoj:
    cmp ecx,0                {zajistime, aby bylo vynulovane ZF}
@Radka_hotova:
end;


Procedure FinishLine;assembler;{$IFDEF EnableInline}inline;{$ENDIF}
{INPUT:   nothing in registers
 OUTPUT:  EDI = points on first pixel in next line
          ZF: 0 = we are not finished, let's go on next line
              1 = we are on last line, so we are done}
asm
mov edi,bank_edi
add edi,bank_xxx
dec bank_lines
end;


Procedure Process_HC_copy;assembler;{$IFDEF EnableInline}inline;{$ENDIF}
{INPUT:   DS:ESI   position in sprite bitmap
          ES:EDI   position in screen (EDI has cleared higher word)
          ECX      how many bytes to copy

 OUTPUT:  DS:ESI and ES:EDI moved into new position
          ECX = 0

 DESTROYS:AX
}
asm
@cykl:
mov ax,ds:[esi]
cmp ax,bank_hc
jz @preskoc
mov es:[edi],ax
@preskoc:
add edi,2
add esi,2
sub ecx,2
jnz @cykl
end;


Procedure Process_FN_copy;assembler;{$IFDEF EnableInline}inline;{$ENDIF}
{INPUT:   DS:ESI   position in sprite bitmap
          ES:EDI   position in screen (EDI has cleared higher word)
          AX       color which to paint
          ECX      how many bytes to copy

 OUTPUT:  DS:ESI and ES:EDI moved into new position
          ECX = 0
}
asm
@cykl:
cmp word ptr [esi],0
jz @preskoc
mov es:[edi],ax
@preskoc:
add edi,2
add esi,2
sub ecx,2
jnz @cykl
end;



Procedure Open_read_mode;assembler;{$IFDEF EnableInline}inline;{$ENDIF}
asm
mov bank_zapis,0   {znak pro volane procedury, ze probiha nikoliv zapisova,}
                   {ale cteci operace}

mov al,win_rd        {pokud karta pouziva jen jedno prostupove okno spolecne}
cmp al,win_wr        {pro cteni a zapis, tak musime synchronizovat zmeny}
jnz @nic
mov eax,bank_wr
mov bank_rd,eax
@nic:
end;


Procedure Close_read_mode;assembler;{$IFDEF EnableInline}inline;{$ENDIF}
asm
mov bank_zapis,1   {prepinac zapisu a cteni vratime do puvodniho stavu}
mov al,win_rd        {pokud karta pouziva jen jedno prostupove okno spolecne}
cmp al,win_wr        {pro cteni a zapis, tak musime synchronizovat zmeny}
jnz @nic
mov eax,bank_rd
mov bank_wr,eax
@nic:
end;


Procedure RLE_Copy;assembler;{$IFDEF EnableInline}inline;{$ENDIF}
{INPUT:   DS:ESI   position in sprite bitmap
          DS:EBX   position in RLE map
          ES:EDI   position in screen (EDI has cleared higher word)

          ECX      starting value of ECX
                   (if ECX=0 read new ECX value)
          EDX      how many pixels can be copied if ENDLINE is not reached

 OUTPUT:  DS:ESI and DS:EBX and ES:EDI moved into new position
          EAX      number of not drawn pixels due a bank switch
          ZF       ZF=1 ENDLINE was reached
                   ZF=0 stopped because all EDX pixels was processed

 DESTROYS: ECX,EDX
}

asm
cmp ecx,0                {mam prednactenou hodnotu ECX?}
jnz @RLE_clip_now_ok    {jestli ano, tak nenacitej novou a hned analyzuj}

@Pokracuj_v_RLE_radce:
movsx ecx,byte ds:[ebx]
    inc ebx

    @RLE_CLIP_NOW_OK:
    cmp ecx,0
    jz @TOTAL_END        {ECX=0? Skoc na konec radku}
    jg @RLE_CLIP_MOVE           {ECX>0? Skoc na presun}

    @RLE_CLIP_SKIP:             {ECX<0, tzn. preskocime -ECX pixelu}
    neg ecx
    sub edx,ecx
    sbb eax,eax
    and eax,edx
    add ecx,eax

    add esi,ecx
    add edi,ecx
    add esi,ecx
    add edi,ecx


    neg eax
    cmp edx,0
    jle @Temporary_END
    jmp @Pokracuj_v_RLE_radce

    @RLE_CLIP_MOVE:
    sub edx,ecx
    sbb eax,eax
    and eax,edx
    add ecx,eax

    shr ecx,1;rep movsd;adc ecx,ecx;rep movsw  {fast 32bit write}

    cmp edx,0
    jle @Temporary_END
    jmp @Pokracuj_v_RLE_radce

@Temporary_END:
neg eax     {v EAX bude pocet nezpracovanych pixelu z duvodu zalomeni banku}
cmp ebx,0   {EBX nemuze byt 0, takze zarucene dosahnu vynulovani ZF}
@Total_END: {pokud smeroval skok primo sem, tak plati ze ZF=1}
end;



Procedure BankClippedBar(x1,y1,x2,y2:longint;c:word);assembler;
asm
mov eax,x1
mov ebx,y1
mov ecx,x2
mov edx,y2
lea edi,vga
Call BarClipping
jc @Konec

push es
mov ax,[edi+0]
mov es,ax

mov ax,c
shl eax,16
mov ax,c

Call StartPosition_into_EDI

@SCANLINES_LOOP:

Call PrepareLine

sar ecx,2;rep stosd;adc ecx,ecx;rep stosw  {Zacnu radek}

Call PrepareLine2                          {mozna prepnu bank}
jz @preskoc

sar ecx,2;rep stosd;adc ecx,ecx;rep stosw  {a dodelam ho}

@preskoc:

Call FinishLine
JNZ @SCANLINES_LOOP

pop es
@Konec:
end;



Procedure BankPutClippedPixel(x,y:longint;c:word);assembler;
asm
  lea edi,vga
  Mov eax,ds:[edi+10]
  Cmp x,eax
  Jae @Ende
  Mov eax,ds:[edi+30]
  Cmp y,eax
  Jae @Ende

Push es
  mov es,[edi+0]
  mov eax,[edi+26]
  mul y
  add eax,x
  add eax,x
  mov edi,eax
  div bank_kb64

  cmp eax,bank_wr
  je @nemenbank

  mov edx,eax
  mov bank_wr,eax
  imul edx,grann
  Call SetBank_wr            {zmeni bank}

@nemenbank:
  and edi,0000ffffh
  add edi,seg_wr
  mov ax,c
  mov es:[edi],ax
pop es
@Ende:
end;


Function BankGetClippedPixel(x,y:longint):word;assembler;
asm
xor eax,eax
  lea edi,vga
  Mov ebx,[edi+10]
  Cmp x,ebx
  Jae @Ende
  Mov ebx,[edi+30]
  Cmp y,ebx
  Jae @Ende

Call Open_read_mode

Push es
mov es,[edi+0]

  mov eax,[edi+26]
  mul y
  add eax,x
  add eax,x
  mov edi,eax
  div bank_kb64

  cmp eax,bank_rd
  je @nemenbank

  mov edx,eax
  mov bank_rd,eax
  imul edx,grann
  Call SetBank_rd            {zmeni bank}

@nemenbank:
  and edi,0000ffffh
  add edi,seg_rd
  mov ax,es:[edi]

pop es
Call Close_read_mode
@Ende:
end;


Procedure BankClippedLineVert(x,y1,y2:LongInt;color:word);
begin
BankClippedBar(x,y1,x,y2,color);
end;


PROCEDURE BankClippedLineHorz(x1,x2,y:LongInt;Color:Word);
begin
BankClippedBar(x1,y,x2,y,color);
end;


PROCEDURE BankClr(Color:Word); Assembler;
Asm
 Mov ax,Color
 Shl eax,16
 Mov ax,Color

 Push es

  lea edi,vga

  Mov ecx,ds:[edi+6]   {VGA.SIZE}
  Mov es ,ds:[edi+0]
  Mov edi,seg_wr
  xor edx,edx

  cmp cpu_info_mmx,0
  Je @NoMMX_so_Jump

   MovD mm1,eax       { Wenn MMX untersttzt wird }
   MovD mm2,eax
   Psllq mm1,32
   Paddusw mm1,mm2

   Shr ecx,6

  cmp cpu_info_emmx,0
  je @go_mmx

@Dalsi_Bank_EMMX:
   mov ecx,edx     { EDX je volanim znicen, je treba ho uschovat }

   Call SetBank_wr            {zmeni bank}

   mov edx,ecx
   mov edi,seg_wr

   mov ecx,1024

  @SCHLEIFE_EMMX:
    prefetch es:[edi+32]     {chtelo by nastudovat, jak presne prefetch pracuje}
    MovntQ es:[edi    ],mm1
    MovntQ es:[edi+  8],mm1
    MovntQ es:[edi+ 16],mm1
    MovntQ es:[edi+ 24],mm1
    MovntQ es:[edi+ 32],mm1
    MovntQ es:[edi+ 40],mm1
    MovntQ es:[edi+ 48],mm1
    MovntQ es:[edi+ 56],mm1
    Add edi,64
   Dec ecx
   JNZ @SCHLEIFE_EMMX
  add edx,grann
  cmp edx,bisgm
  jbe @Dalsi_Bank_EMMX
  Emms
  Jmp @Ende

@go_mmx:
@Dalsi_Bank_MMX:
   mov ecx,edx     { EDX je volanim znicen, je treba ho uschovat }
   Call SetBank_wr         {zmeni bank}
   mov edx,ecx
   mov edi,seg_wr
   mov ecx,1024

   @SCHLEIFE_MMX:
    MovQ es:[edi    ],mm1
    MovQ es:[edi+  8],mm1
    MovQ es:[edi+ 16],mm1
    MovQ es:[edi+ 24],mm1
    MovQ es:[edi+ 32],mm1
    MovQ es:[edi+ 40],mm1
    MovQ es:[edi+ 48],mm1
    MovQ es:[edi+ 56],mm1
    Add edi,64
   Dec ecx
   JNZ @SCHLEIFE_MMX
  add edx,grann
  cmp edx,bisgm
  jbe @Dalsi_Bank_MMX
  Emms
  Jmp @Ende

@NoMMX_so_Jump:
@Dalsi_bank:
  push eax
  mov ecx,edx     { EDX je volanim znicen, je treba ho uschovat }
  Call SetBank_wr         {zmeni bank}
  mov edx,ecx
  mov edi,seg_wr
  mov ecx,1024
  pop eax

  mov ecx,16384
  Rep StosD

  add edx,grann
  cmp edx,bisgm
  jbe @Dalsi_Bank
 @Ende:
 Pop es
mov eax,numm
mov bank_wr,eax
End;


PROCEDURE BankPutClippedHCSprite(var Sprite:VirtualWindow;x,y:LongInt;HideColor:Word);assembler;
var sprtstrt:longint;
asm
lea edi,vga
mov esi,sprite
mov eax,x
mov ebx,y
call SpriteClipping
jc @Konec

push es
pushf      {uklidim priznak ZF ze SpriteClipping}
mov es,[edi+0]
test byte [esi+20],2    {je pripravena RLE mapa?}
jnz @RLE_mapa

Call StartPosition_into_EDI
Call StartPosition_into_ESI

mov ax,Hidecolor
mov bank_hc,ax

@SCANLINES_LOOP:

Call PrepareLine
push esi
Call Process_HC_copy
Call PrepareLine2
jz @preskoc
   Call Process_HC_copy
@preskoc:

pop esi
add esi,bank_zzz
Call FinishLine

JNZ @SCANLINES_LOOP
jmp @Obnov_ES

{============================ Prubeh s RLE mapou ============================}
@RLE_mapa:
push dword [esi+34] {ulozime si odkaz na RLE mapu}
mov sprtstrt,eax    {uschovam si hodnotu posunu od zacatku spritu do EAX}
Call StartPosition_into_EDI
Call StartPosition_into_ESI
pop ebx             {obnovim odkaz na RLE mapu}

popf
jnz @RLE_clipping
{----------------------------------------------------------------------------}
@RLE_nonclip:   {Varianta bez clippingu}

  @RLE_SCANLINES_LOOP:
    push esi
    push ebx               {ulozim seznam na radky}
    mov ebx,ds:[ebx]       {odkaz na n-ty radek RLE mapy}


    push ebx               {uschovam, protoze bude zniceno v PrepareLine}
    Call PrepareLine     {nastavim banky}
    mov edx,ecx          {do EDX dam pocet bajtu ke zprac. pred zmenou banku}
    shr edx,1            {zmenim to na pocet pixelu}
    pop ebx                {obnova ebx}


{-----------------------------------------------------}
    xor ecx,ecx           {vynuluju ECX, tzn. nactu z RLE novou hodnotu}
    Call RLE_copy
    jz @RLE_TOTALEND_LINE {Pokud bylo dosazeno znacky ENDLINE tak dal nepokr.}

    push ebx
    Call PrepareLine2
    pop ebx
    jz @RLE_TOTALEND_LINE
    mov edx,ecx          {do EDX dam pocet bajtu ke zprac. po zmene banku}
    shr edx,1            {zmenim to na pocet pixelu}
    mov ecx,eax          {do ECX vlozim minule nezpracovane pixely kvuli}
    Call RLE_copy            {zalomeni banku}

   @RLE_TOTALEND_LINE:

    pop ebx
    add ebx,4
    pop esi
    add esi,bank_zzz

  Call FinishLine
  JNZ @RLE_SCANLINES_LOOP



jmp @Obnov_ES

{----------------------------------------------------------------------------}
@RLE_clipping: {Varianta, kdy je nutne provest clipping}



{----------------------------------------------------------------------------}
{----------------------------------------------------------------------------}
@Obnov_ES:
pop es
@Konec:
End;


PROCEDURE _BankPutClippedHCSprite(var Dest,Sprite:VirtualWindow;x,y:LongInt;HideColor:Word);
begin
BankPutClippedHCSprite(Sprite,x,y,HideColor);
end;


PROCEDURE BankPutClippedSprite(var Sprite:VirtualWindow;x,y:LongInt);assembler;
asm
lea edi,vga
mov esi,sprite
mov eax,x
mov ebx,y
call SpriteClipping
jc @Konec

push es
mov es,[edi+0]

Call StartPosition_into_EDI
Call StartPosition_into_ESI

@SCANLINES_LOOP:

Call PrepareLine
push esi
sar ecx,2;rep movsd;adc ecx,ecx;rep movsw  {fast 32bit write}


Call PrepareLine2
jz @preskoc
sar ecx,2;rep movsd;adc ecx,ecx;rep movsw  {fast 32bit write}
@preskoc:

pop esi
add esi,bank_zzz
Call FinishLine

JNZ @SCANLINES_LOOP

pop es
@Konec:

End;

PROCEDURE _BankPutClippedSprite(var Dest,Sprite:VirtualWindow;x,y:LongInt);
begin
BankPutClippedSprite(Sprite,x,y);
end;

Procedure Process_read_copy;assembler;
{copies from ES:EDI into DS:ESI}
asm
@znovu:
cmp ecx,4
jl @zbytek

mov eax,ES:[edi]
mov DS:[esi],eax
add edi,4
add esi,4
sub ecx,4
jnz @znovu
jmp @konec

@zbytek:
mov ax,ES:[edi]
mov DS:[esi],ax
add edi,2
add esi,2
sub ecx,2

@konec:
end;


PROCEDURE BankGetClippedSprite(var sprite:virtualwindow;x,y:LongInt);assembler;
asm
lea edi,vga
mov esi,sprite
mov eax,x
mov ebx,y
call SpriteClipping
jc @Konec

push es
mov es,[edi+0]

Call StartPosition_into_EDI
Call StartPosition_into_ESI

Call Open_read_mode

@SCANLINES_LOOP:

Call PrepareLine
push esi
Call Process_read_copy
Call PrepareLine2
jz @preskoc
   Call Process_read_copy
@preskoc:

pop esi
add esi,bank_zzz
Call FinishLine

JNZ @SCANLINES_LOOP


Call Close_read_mode
pop es
@Konec:
End;

PROCEDURE _BankGetClippedSprite(var Source,Sprite:VirtualWindow;x,y:LongInt);
begin
BankGetClippedSprite(Sprite,x,y);
end;


{*********************************************************************}

Function BankPutChar_FN(p:pointer;x,y,xd,xxd,yd:longint;charbytes:byte;c:word):longint;assembler;
{ For unit FNfont2 }
asm
lea esi,fontvw        {nacetl jsem si renderovaci policko pro znaky}

mov eax,xd
mov ebx,yd
mov ecx,eax
shl ecx,1

mov [esi+10],eax  {breite}
mov [esi+30],ebx  {hoehe}
mov [esi+26],ecx  {bytebreite}

lea edi,vga
mov eax,x
mov ebx,y
call SpriteClipping
jc @Konec

{--cmp neco;jz @rozpakovano}

push edi          {schovam EDI, protoze ji prepisu}
push esi
push ecx
push edx
mov edi,[esi+2]   {bitmapu rozepisu do 16-bitove pixmapy}
mov esi,p         {vezmu bitmapu}
movzx ecx,charbytes

call BitmapaNaPixmapu

pop edx
pop ecx
pop esi
pop edi


@rozpakovano:


push es
mov es,[edi+0]

Call StartPosition_into_EDI
Call StartPosition_into_ESI

mov ax,c

@SCANLINES_LOOP:

Call PrepareLine
push esi
Call Process_FN_copy
Call PrepareLine2
jz @preskoc
   Call Process_FN_copy
@preskoc:

pop esi
add esi,bank_zzz
Call FinishLine

JNZ @SCANLINES_LOOP

pop es
@Konec:
mov eax,0
end;


