;Copyright (C) 1997-2004 ZSNES Team ( zsknight@zsnes.com / _demo_@zsnes.com )
;
;This program is free software; you can redistribute it and/or
;modify it under the terms of the GNU General Public License
;as published by the Free Software Foundation; either
;version 2 of the License, or (at your option) any later
;version.
;
;This program is distributed in the hope that it will be useful,
;but WITHOUT ANY WARRANTY; without even the implied warranty of
;MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
;GNU General Public License for more details.
;
;You should have received a copy of the GNU General Public License
;along with this program; if not, write to the Free Software
;Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.


EXTSYM mode7B, mode7D
EXTSYM drawmode7ngextbg,drawmode7ngextbg2







%macro Procbgpr0 5
    ; Draw BG 2
    ; Start line by line drawing/check
    mov esi,[vidbuffer]
    add esi,16
;    add esi,16+288
    xor ebx,ebx
%%nextline
    cmp byte[BGFB+ebx],0
    jne %%nogo
    test dword[BGMS1+ebx*2],%4
    jz %%nogo
    test dword[BGMS1+ebx*2],%5
    jnz %%nogo
    ; Check if at a tile alignment
    mov ecx,[BG1SYl+ebx*2+%1*512]
    and ecx,0FFFFh
    add ecx,ebx
    test ecx,07h
    jz %%tilecheck
%%proclinebyline
    ; process line by line
    call %2
%%nogo
    inc ebx
    add esi,288
    cmp [resolutn],bx
    ja %%nextline
    jmp %%donextbg
%%tilecheck
    test dword[bgwinchange+ebx],0FFFFFF00h
    jnz %%linebyline
    test dword[bgwinchange+ebx+4],0FFFFFFFFh
    jz %%tilebytile
%%linebyline
    test dword[winbg1enval+ebx+%1*256],0A0A0A0Ah
    jnz %%proclinebyline
    test dword[winbg1enval+ebx+%1*256+4],0A0A0A0Ah
    jnz %%proclinebyline
%%tilebytile
    test dword[BGMS1+ebx*2+14],%4
    jz %%proclinebyline
    test dword[BGMS1+ebx*2+14],%5
    jnz %%proclinebyline
    cmp ebx,[reslbyl]
    jae %%proclinebyline
    test dword[bgallchange+ebx],0FFFFFF00h
    jnz %%proclinebyline
    test dword[bgallchange+ebx+4],0FFFFFFFFh
    jnz near %%proclinebyline
    test dword[bg1change+ebx+%1*256],0FFFFFF00h
    jnz near %%proclinebyline
    test dword[bg1change+ebx+%1*256+4],0FFFFFFFFh
    jnz near %%proclinebyline
    cmp byte[BGMA+ebx],5
    jae near %%proclinebyline
    cmp byte[BGMA+ebx],2
    je near %%proclinebyline
    test dword[intrlng+ebx],01010101h
    jnz near %%proclinebyline
    test dword[intrlng+ebx+4],01010101h
    jnz near %%proclinebyline
    test byte[mosenng+ebx],1 << %1
    jnz %%mosaic
%%nomosaic
    call %3
    add ebx,8
    add esi,288*8
    cmp [resolutn],bx
    ja near %%nextline
    jmp %%donextbg
%%mosaic
    cmp byte[mosszng+ebx],0
    je %%nomosaic
    jmp %%proclinebyline
%%donextbg
%endmacro

%macro Procbg3pr0 5
    ; Draw BG 2
    ; Start line by line drawing/check
    mov esi,[vidbuffer]
    add esi,16
;    add esi,16+288
    xor ebx,ebx
%%nextline
    cmp byte[BGFB+ebx],0
    jne %%nogo
    test dword[BGMS1+ebx*2],%4
    jz %%nogo
    test dword[BGMS1+ebx*2],%5
    jnz %%nogo
    ; Check if at a tile alignment
    mov ecx,[BG1SYl+ebx*2+%1*512]
    and ecx,0FFFFh
    add ecx,ebx
    test ecx,07h
    jz %%tilecheck
%%proclinebyline
    ; process line by line
    call %2
%%nogo
    inc ebx
    add esi,288
    cmp [resolutn],bx
    ja %%nextline
    jmp %%donextbg
%%tilecheck
    test dword[bgwinchange+ebx],0FFFFFF00h
    jnz %%linebyline
    test dword[bgwinchange+ebx+4],0FFFFFFFFh
    jz %%tilebytile
%%linebyline
    test dword[winbg1enval+ebx+%1*256],0A0A0A0Ah
    jnz %%proclinebyline
    test dword[winbg1enval+ebx+%1*256+4],0A0A0A0Ah
    jnz %%proclinebyline
%%tilebytile
    test dword[BGMS1+ebx*2+14],%4
    jz %%proclinebyline
    test dword[BGMS1+ebx*2+14],%5
    jnz %%proclinebyline
    cmp ebx,[reslbyl]
    jae %%proclinebyline
    test dword[bgallchange+ebx],0FFFFFF00h
    jnz %%proclinebyline
    test dword[bgallchange+ebx+4],0FFFFFFFFh
    jnz near %%proclinebyline
    test dword[bg1change+ebx+%1*256],0FFFFFF00h
    jnz near %%proclinebyline
    test dword[bg1change+ebx+%1*256+4],0FFFFFFFFh
    jnz near %%proclinebyline
    mov eax,[BG3PRI+ebx]
    cmp eax,[BG3PRI+ebx+4]
    jne near %%proclinebyline
    test dword[intrlng+ebx],01010101h
    jnz near %%proclinebyline
    test dword[intrlng+ebx+4],01010101h
    jnz near %%proclinebyline
    test byte[mosenng+ebx],1 << %1
    jnz %%mosaic
%%nomosaic
    call %3
    add ebx,8
    add esi,288*8
    cmp [resolutn],bx
    ja near %%nextline
    jmp %%donextbg
%%mosaic
    cmp byte[mosszng+ebx],0
    je %%nomosaic
    jmp %%proclinebyline
%%donextbg
%endmacro

%macro Procbgpr1 6
    ; Draw BG
    ; Start line by line drawing/check
    mov esi,[vidbuffer]
    add esi,16
;    add esi,16+288
    xor ebx,ebx
%%nextline
    cmp byte[BGFB+ebx],0
    jne %%nogo
    test dword[BGMS1+ebx*2],%5
    jz %%nogo
    test dword[BGMS1+ebx*2],%6
    jnz %%nogo
    ; Check if at a tile alignment
    cmp byte[%4+ebx],1
    je %%tile
%%proclinebyline
    ; process line by line
    call %2
%%nogo
    inc ebx
    add esi,288
    cmp [resolutn],bx
    jne %%nextline
    jmp %%donextbg
%%tile
    call %3
    add ebx,8
    add esi,288*8
    cmp [resolutn],bx
    ja %%nextline
%%donextbg
%endmacro

%macro Procbg3pr1 6
    ; Draw BG 2
    ; Start line by line drawing/check
    mov esi,[vidbuffer]
    add esi,16
    xor ebx,ebx
%%nextline
    cmp byte[BGFB+ebx],0
    jne %%nogo
    test dword[BGMS1+ebx*2],%5
    jz %%nogo
    test dword[BGMS1+ebx*2],%6
    jnz %%nogo
    cmp byte[BGMA+ebx],1
    jne %%nomode1
    cmp byte[BG3PRI+ebx],0
    jne %%nogo
%%nomode1
    ; Check if at a tile alignment
    cmp byte[%4+ebx],1
    je %%tile
%%proclinebyline
    ; process line by line
    call %2
%%nogo
    inc ebx
    add esi,288
    cmp [resolutn],bx
    ja %%nextline
    jmp %%donextbg
%%tile
    call %3
    add ebx,8
    add esi,288*8
    cmp [resolutn],bx
    ja %%nextline
%%donextbg
%endmacro

%macro Procbg3pr1b 6
    ; Draw BG 2
    ; Start line by line drawing/check
    mov esi,[vidbuffer]
    add esi,16
    xor ebx,ebx
%%nextline
    cmp byte[BGFB+ebx],0
    jne %%nogo
    test dword[BGMS1+ebx*2],%5
    jz %%nogo
    test dword[BGMS1+ebx*2],%6
    jnz %%nogo
    cmp byte[BGMA+ebx],1
    jne %%nogo
    cmp byte[BG3PRI+ebx],0
    je %%nogo
    ; Check if at a tile alignment
    cmp byte[%4+ebx],1
    je %%tile
%%proclinebyline
    ; process line by line
    call %2
%%nogo
    inc ebx
    add esi,288
    cmp [resolutn],bx
    ja %%nextline
    jmp %%donextbg
%%tile
    call %3
    add ebx,8
    add esi,288*8
    cmp [resolutn],bx
    ja %%nextline
%%donextbg
%endmacro

%macro Procsprng 2
    ; Draw BG 2
    ; Start line by line drawing/check
    mov esi,[vidbuffer]
    add esi,16+288
    mov ebx,1
%%nextline
    cmp byte[BGFB+ebx],0
    jne %%nogo
    test dword[BGMS1+ebx*2],%1
    jz %%nogo
    test dword[BGMS1+ebx*2],%2
    jnz %%nogo
    xor eax,eax
    mov al,[sprtlng+ebx]
    mov cl,byte[sprlefttot+ebx]
    mov [csprival],eax
    inc byte[sprtlng+ebx]
    test byte[sprleftpr+ebx*4+eax],1
    jz %%nogo
    or cl,cl
    jz %%nogo
    call drawsprng
    cmp byte[BGMA+ebx],5
    jb %%nogo
    cmp byte[hiresstuff],0
    je %%nogo
    add esi,75036
    mov cl,byte[sprlefttot+ebx]
    call drawsprng
    sub esi,75036
%%nogo
    inc ebx
    add esi,288
    cmp [resolutn],bx
    ja near %%nextline
%endmacro

%macro Procsprng01 2
    ; Draw BG 2
    ; Start line by line drawing/check
    mov esi,[vidbuffer]
    add esi,16+288
    mov ebx,1
%%nextline
    cmp byte[BGFB+ebx],0
    jne %%nogo
    test dword[BGMS1+ebx*2],%1
    jz %%nogo
    test dword[BGMS1+ebx*2],%2
    jnz %%nogo
    cmp byte[BGMA+ebx],1
    ja %%nogo
    xor eax,eax
    mov al,[sprtlng+ebx]
    mov cl,byte[sprlefttot+ebx]
    mov [csprival],eax
    inc byte[sprtlng+ebx]
    test byte[sprleftpr+ebx*4+eax],1
    jz %%nogo
    or cl,cl
    jz %%nogo
    call drawsprng
    cmp byte[BGMA+ebx],5
    jb %%nogo
    cmp byte[hiresstuff],0
    je %%nogo
    add esi,75036
    mov cl,byte[sprlefttot+ebx]
    call drawsprng
    sub esi,75036
%%nogo
    inc ebx
    add esi,288
    cmp [resolutn],bx
    ja near %%nextline
%endmacro

%macro Procsprng234567 2
    ; Draw BG 2
    ; Start line by line drawing/check
    mov esi,[vidbuffer]
    add esi,16+288
    mov ebx,1
%%nextline
    cmp byte[BGFB+ebx],0
    jne %%nogo
    test dword[BGMS1+ebx*2],%1
    jz %%nogo
    test dword[BGMS1+ebx*2],%2
    jnz %%nogo
    cmp byte[BGMA+ebx],1
    jbe %%nogo
    xor eax,eax
    mov al,[sprtlng+ebx]
    mov cl,byte[sprlefttot+ebx]
    mov [csprival],eax
    inc byte[sprtlng+ebx]
    test byte[sprleftpr+ebx*4+eax],1
    jz %%nogo
    or cl,cl
    jz %%nogo
    call drawsprng
    cmp byte[BGMA+ebx],5
    jb %%nogo
    cmp byte[hiresstuff],0
    je %%nogo
    add esi,75036
    mov cl,byte[sprlefttot+ebx]
    call drawsprng
    sub esi,75036
%%nogo
    inc ebx
    add esi,288
    cmp [resolutn],bx
    ja near %%nextline
%endmacro

%macro ProcMode7ng 2
    mov byte[winon],0
    ; Draw BG
    ; Start line by line drawing/check
    mov esi,[vidbuffer]
    add esi,16+288
    mov ebx,[mode7A]
    mov [Mode7BackA],ebx
    mov ebx,[mode7C]
    mov [Mode7BackC],ebx
    mov ebx,[mode7X0]
    mov [Mode7BackX0],ebx
    mov bl,[mode7set]
    mov [Mode7BackSet],ebx
    mov ebx,1
%%nextline
    cmp byte[BGFB+ebx],0
    jne near %%nogo
    cmp byte[BGMA+ebx],7
    jne near %%nogo
    test byte[intrlng+ebx],40h
    jnz near %%nogo
    test dword[BGMS1+ebx*2],%1
    jz near %%nogo
    test dword[BGMS1+ebx*2],%2
    jnz near %%nogo
    push ebx
    ; Process mosaic
    mov byte[curmosaicsz],1
    xor ecx,ecx
    test byte[mosenng+ebx],1
    jz %%nomosaic
    mov cl,[mosszng+ebx]
    or cl,cl
    jz %%nomosaic
    inc cl
    mov byte[curmosaicsz],cl
    xor edx,edx
    mov eax,ebx
    div cl
    xor edx,edx
    mul cl
    mov ebx,eax
%%nomosaic
    ; process line by line
    mov edx,[mode7ab+ebx*4]
    mov [mode7A],edx
    mov edx,[mode7cd+ebx*4]
    mov [mode7C],edx

    mov edx,[mode7xy+ebx*4]
    mov [mode7X0],edx
    mov edx,[mode7st+ebx]
    mov [mode7set],dl
    xor edx,edx
    mov eax,ebx
    test byte[mode7set],02h
    jz %%noflip
    mov eax,261
    sub eax,ebx
%%noflip
    mov dx,[BG1SXl+ebx*2]
    add ax,[BG1SYl+ebx*2]
    mov [curvidoffset],esi
    pop ebx
    push eax
    push edx
    push esi
    push ebx
    call drawmode7win
    pop ebx
    pop esi
    pop edx
    pop eax
    cmp byte[Mode7HiRes],0
    je %%nogo
    call processmode7hires
%%nogo
    inc ebx
    add esi,288
    cmp [resolutn],bx
    ja near %%nextline
    mov ebx,[Mode7BackA]
    mov [mode7A],ebx
    mov ebx,[Mode7BackC]
    mov [mode7C],ebx
    mov ebx,[Mode7BackX0]
    mov [mode7X0],ebx
    mov ebx,[Mode7BackSet]
    mov [mode7set],bl
%endmacro


%macro ProcMode7ngextbg 2
    mov byte[winon],0
    ; Draw BG
    ; Start line by line drawing/check
    mov esi,[vidbuffer]
    add esi,16+288
    mov ebx,[mode7A]
    mov [Mode7BackA],ebx
    mov ebx,[mode7C]
    mov [Mode7BackC],ebx
    mov ebx,[mode7X0]
    mov [Mode7BackX0],ebx
    mov bl,[mode7set]
    mov [Mode7BackSet],ebx
    mov ebx,1
%%nextline
    mov byte[esi-1],0
    cmp byte[BGFB+ebx],0
    jne near %%nogo
    cmp byte[BGMA+ebx],7
    jne near %%nogo
    test dword[BGMS1+ebx*2],%1
    jz near %%nogo
    test dword[BGMS1+ebx*2],%2
    jnz near %%nogo
    test byte[intrlng+ebx],40h
    jz near %%nogo
    mov byte[esi-1],1
    push ebx
    ; Process mosaic
    mov byte[curmosaicsz],1
    xor ecx,ecx
    test byte[mosenng+ebx],1
    jz %%nomosaic
    mov cl,[mosszng+ebx]
    or cl,cl
    jz %%nomosaic
    inc cl
    mov byte[curmosaicsz],cl
    xor edx,edx
    mov eax,ebx
    div cl
    xor edx,edx
    mul cl
    mov ebx,eax
%%nomosaic
    ; process line by line
    mov edx,[mode7ab+ebx*4]
    mov [mode7A],edx
    mov edx,[mode7cd+ebx*4]
    mov [mode7C],edx
    mov edx,[mode7xy+ebx*4]
    mov [mode7X0],edx
    mov edx,[mode7st+ebx]
    mov [mode7set],dl
    xor edx,edx
    mov eax,ebx
    test byte[mode7set],02h
    jz %%noflip
    mov eax,261
    sub eax,ebx
%%noflip
    mov dx,[BG1SXl+ebx*2]
    add ax,[BG1SYl+ebx*2]
    mov [curvidoffset],esi
    push esi
    call drawmode7ngextbg
    pop esi
    pop ebx
%%nogo
    inc ebx
    add esi,288
    cmp [resolutn],bx
    ja near %%nextline
    mov ebx,[Mode7BackA]
    mov [mode7A],ebx
    mov ebx,[Mode7BackC]
    mov [mode7C],ebx
    mov ebx,[Mode7BackX0]
    mov [mode7X0],ebx
    mov ebx,[Mode7BackSet]
    mov [mode7set],bl
%endmacro

%macro ProcMode7ngextbg2 2
    mov byte[winon],0
    ; Draw BG
    ; Start line by line drawing/check
    mov esi,[vidbuffer]
    add esi,16+288
    mov ebx,[mode7A]
    mov [Mode7BackA],ebx
    mov ebx,[mode7C]
    mov [Mode7BackC],ebx
    mov ebx,[mode7X0]
    mov [Mode7BackX0],ebx
    mov bl,[mode7set]
    mov [Mode7BackSet],ebx
    mov ebx,1
%%nextline
    cmp byte[BGFB+ebx],0
    jne near %%nogo
    cmp byte[BGMA+ebx],7
    jne near %%nogo
    test dword[BGMS1+ebx*2],%1
    jz near %%nogo
    test dword[BGMS1+ebx*2],%2
    jnz near %%nogo
    test byte[intrlng+ebx],40h
    jz near %%nogo
    push ebx
    ; Process mosaic
    mov byte[curmosaicsz],1
    xor ecx,ecx
    test byte[mosenng+ebx],1
    jz %%nomosaic
    mov cl,[mosszng+ebx]
    or cl,cl
    jz %%nomosaic
    inc cl
    mov byte[curmosaicsz],cl
    xor edx,edx
    mov eax,ebx
    div cl
    xor edx,edx
    mul cl
    mov ebx,eax
%%nomosaic
    ; process line by line
    mov edx,[mode7ab+ebx*4]
    mov [mode7A],edx
    mov edx,[mode7cd+ebx*4]
    mov [mode7C],edx
    mov edx,[mode7xy+ebx*4]
    mov [mode7X0],edx
    mov edx,[mode7st+ebx]
    mov [mode7set],dl
    xor edx,edx
    mov eax,ebx
    test byte[mode7set],02h
    jz %%noflip
    mov eax,261
    sub eax,ebx
%%noflip
    mov dx,[BG1SXl+ebx*2]
    add ax,[BG1SYl+ebx*2]
    mov [curvidoffset],esi
    push esi
    jmp %%drawb
    cmp byte[esi-1],1
    je %%drawb
    call drawmode7ngextbg
    jmp %%drawa
%%drawb
    call drawmode7ngextbg2
%%drawa
    pop esi
    pop ebx
%%nogo
    inc ebx
    add esi,288
    cmp [resolutn],bx
    ja near %%nextline
    mov ebx,[Mode7BackA]
    mov [mode7A],ebx
    mov ebx,[Mode7BackC]
    mov [mode7C],ebx
    mov ebx,[Mode7BackX0]
    mov [mode7X0],ebx
    mov ebx,[Mode7BackSet]
    mov [mode7set],bl
%endmacro

%macro preparet4ba 0
    shl cx,5
    add ecx,ecx
    add ecx,[vcache4b]
%endmacro

%macro preparet2ba 0
    shl cx,4
    shl ecx,2
    add ecx,[vcache2b]
%endmacro

%macro preparet8ba 0
    shl cx,6
    add ecx,[vcache8b]
%endmacro

%macro test4ba 0
    and ecx,2047
    test dword[vidmemch4+ecx*2],0FFFFh
%endmacro

%macro test2ba 0
    and ecx,4095
    add edx,dword[mode0add]
    test dword[vidmemch2+ecx],0FFh
%endmacro

%macro test8ba 0
    and ecx,1023
    test dword[vidmemch8+ecx*4],0FFFFFFFFh
%endmacro

%macro drawtileng 8
    ; tile value : bit 15 = flipy, bit 14 = flipx, bit 13 = priority value
    ;              bit 10-12 = palette, 0-9=tile#
    mov ebx,[ng16bbgval]
    mov dl,ch
    inc dword[bg1drwng+ebx*4]
    and ecx,3FFh
    and edx,1Fh
    add ecx,[ngptrdat2]
    mov edx,[%6+edx*4]
    %7
    jnz near %%docache
%%returnfromcache
    cmp byte[%1+ecx],2
    je near %5
    cmp byte[%1+ecx],0
    je near %%parttile
    %2
    ; start drawing from ecx
    test dword[vrama+eax],8000h
    jnz near %%flipyfull
    test dword[vrama+eax],4000h
    jnz near %%flipxfull
    mov ebx,[ecx]
    add ebx,edx
    mov [edi],ebx
    mov ebx,[ecx+4]
    add ebx,edx
    mov [edi+4],ebx
    mov ebx,[ecx+8]
    add ebx,edx
    mov [edi+288],ebx
    mov ebx,[ecx+12]
    add ebx,edx
    mov [edi+288+4],ebx
    mov ebx,[ecx+16]
    add ebx,edx
    mov [edi+288*2],ebx
    mov ebx,[ecx+20]
    add ebx,edx
    mov [edi+288*2+4],ebx
    mov ebx,[ecx+24]
    add ebx,edx
    mov [edi+288*3],ebx
    mov ebx,[ecx+28]
    add ebx,edx
    mov [edi+288*3+4],ebx
    mov ebx,[ecx+32]
    add ebx,edx
    mov [edi+288*4],ebx
    mov ebx,[ecx+36]
    add ebx,edx
    mov [edi+288*4+4],ebx
    mov ebx,[ecx+40]
    add ebx,edx
    mov [edi+288*5],ebx
    mov ebx,[ecx+44]
    add ebx,edx
    mov [edi+288*5+4],ebx
    mov ebx,[ecx+48]
    add ebx,edx
    mov [edi+288*6],ebx
    mov ebx,[ecx+52]
    add ebx,edx
    mov [edi+288*6+4],ebx
    mov ebx,[ecx+56]
    add ebx,edx
    mov [edi+288*7],ebx
    mov ebx,[ecx+60]
    add ebx,edx
    mov [edi+288*7+4],ebx
    jmp %5
%%flipxfull
    mov ebx,[ecx+4]
    bswap ebx
    add ebx,edx
    mov [edi],ebx
    mov ebx,[ecx]
    bswap ebx
    add ebx,edx
    mov [edi+4],ebx
    mov ebx,[ecx+12]
    bswap ebx
    add ebx,edx
    mov [edi+288],ebx
    mov ebx,[ecx+8]
    bswap ebx
    add ebx,edx
    mov [edi+288+4],ebx
    mov ebx,[ecx+20]
    bswap ebx
    add ebx,edx
    mov [edi+288*2],ebx
    mov ebx,[ecx+16]
    bswap ebx
    add ebx,edx
    mov [edi+288*2+4],ebx
    mov ebx,[ecx+28]
    bswap ebx
    add ebx,edx
    mov [edi+288*3],ebx
    mov ebx,[ecx+24]
    bswap ebx
    add ebx,edx
    mov [edi+288*3+4],ebx
    mov ebx,[ecx+36]
    bswap ebx
    add ebx,edx
    mov [edi+288*4],ebx
    mov ebx,[ecx+32]
    bswap ebx
    add ebx,edx
    mov [edi+288*4+4],ebx
    mov ebx,[ecx+44]
    bswap ebx
    add ebx,edx
    mov [edi+288*5],ebx
    mov ebx,[ecx+40]
    bswap ebx
    add ebx,edx
    mov [edi+288*5+4],ebx
    mov ebx,[ecx+52]
    bswap ebx
    add ebx,edx
    mov [edi+288*6],ebx
    mov ebx,[ecx+48]
    bswap ebx
    add ebx,edx
    mov [edi+288*6+4],ebx
    mov ebx,[ecx+60]
    bswap ebx
    add ebx,edx
    mov [edi+288*7],ebx
    mov ebx,[ecx+56]
    bswap ebx
    add ebx,edx
    mov [edi+288*7+4],ebx
    jmp %5
%%flipyfull
    test word[vrama+eax],4000h
    jnz near %%flipxyfull
    mov ebx,[ecx]
    add ebx,edx
    mov [edi+288*7],ebx
    mov ebx,[ecx+4]
    add ebx,edx
    mov [edi+288*7+4],ebx
    mov ebx,[ecx+8]
    add ebx,edx
    mov [edi+288*6],ebx
    mov ebx,[ecx+12]
    add ebx,edx
    mov [edi+288*6+4],ebx
    mov ebx,[ecx+16]
    add ebx,edx
    mov [edi+288*5],ebx
    mov ebx,[ecx+20]
    add ebx,edx
    mov [edi+288*5+4],ebx
    mov ebx,[ecx+24]
    add ebx,edx
    mov [edi+288*4],ebx
    mov ebx,[ecx+28]
    add ebx,edx
    mov [edi+288*4+4],ebx
    mov ebx,[ecx+32]
    add ebx,edx
    mov [edi+288*3],ebx
    mov ebx,[ecx+36]
    add ebx,edx
    mov [edi+288*3+4],ebx
    mov ebx,[ecx+40]
    add ebx,edx
    mov [edi+288*2],ebx
    mov ebx,[ecx+44]
    add ebx,edx
    mov [edi+288*2+4],ebx
    mov ebx,[ecx+48]
    add ebx,edx
    mov [edi+288],ebx
    mov ebx,[ecx+52]
    add ebx,edx
    mov [edi+288+4],ebx
    mov ebx,[ecx+56]
    add ebx,edx
    mov [edi],ebx
    mov ebx,[ecx+60]
    add ebx,edx
    mov [edi+4],ebx
    jmp %5
%%flipxyfull
    mov ebx,[ecx+4]
    bswap ebx
    add ebx,edx
    mov [edi+288*7],ebx
    mov ebx,[ecx]
    bswap ebx
    add ebx,edx
    mov [edi+288*7+4],ebx
    mov ebx,[ecx+12]
    bswap ebx
    add ebx,edx
    mov [edi+288*6],ebx
    mov ebx,[ecx+8]
    bswap ebx
    add ebx,edx
    mov [edi+288*6+4],ebx
    mov ebx,[ecx+20]
    bswap ebx
    add ebx,edx
    mov [edi+288*5],ebx
    mov ebx,[ecx+16]
    bswap ebx
    add ebx,edx
    mov [edi+288*5+4],ebx
    mov ebx,[ecx+28]
    bswap ebx
    add ebx,edx
    mov [edi+288*4],ebx
    mov ebx,[ecx+24]
    bswap ebx
    add ebx,edx
    mov [edi+288*4+4],ebx
    mov ebx,[ecx+36]
    bswap ebx
    add ebx,edx
    mov [edi+288*3],ebx
    mov ebx,[ecx+32]
    bswap ebx
    add ebx,edx
    mov [edi+288*3+4],ebx
    mov ebx,[ecx+44]
    bswap ebx
    add ebx,edx
    mov [edi+288*2],ebx
    mov ebx,[ecx+40]
    bswap ebx
    add ebx,edx
    mov [edi+288*2+4],ebx
    mov ebx,[ecx+52]
    bswap ebx
    add ebx,edx
    mov [edi+288],ebx
    mov ebx,[ecx+48]
    bswap ebx
    add ebx,edx
    mov [edi+288+4],ebx
    mov ebx,[ecx+60]
    bswap ebx
    add ebx,edx
    mov [edi],ebx
    mov ebx,[ecx+56]
    bswap ebx
    add ebx,edx
    mov [edi+4],ebx
    jmp %5
%%parttile
    %2
    ; start drawing from ecx to edi
    test word[vrama+eax],8000h
    jnz near %%flipypart
    test word[vrama+eax],4000h
    jnz near %%flipxpart
    mov dword[tleftnb],8
%%nextb
    mov ebx,[ecx]
    or ebx,ebx
    jz %%drawd
    add ebx,edx
    test bl,%8
    jz %%drawa
    mov [edi],bl
%%drawa
    test bh,%8
    jz %%drawb
    mov [edi+1],bh
%%drawb
    shr ebx,16
    test bl,%8
    jz %%drawc
    mov [edi+2],bl
%%drawc
    test bh,%8
    jz %%drawd
    mov [edi+3],bh
%%drawd
    mov ebx,[ecx+4]
    or ebx,ebx
    jz %%drawd2
    add ebx,edx
    test bl,%8
    jz %%drawa2
    mov [edi+4],bl
%%drawa2
    test bh,%8
    jz %%drawb2
    mov [edi+5],bh
%%drawb2
    shr ebx,16
    test bl,%8
    jz %%drawc2
    mov [edi+6],bl
%%drawc2
    test bh,%8
    jz %%drawd2
    mov [edi+7],bh
%%drawd2
    add ecx,8
    add edi,288
    dec dword[tleftnb]
    jnz %%nextb
    sub edi,288*8
    jmp %5
%%flipxpart
    mov dword[tleftnb],8
%%nextbf
    mov ebx,[ecx]
    or ebx,ebx
    jz %%drawdf
    add ebx,edx
    test bl,%8
    jz %%drawaf
    mov [edi+7],bl
%%drawaf
    test bh,%8
    jz %%drawbf
    mov [edi+6],bh
%%drawbf
    shr ebx,16
    test bl,%8
    jz %%drawcf
    mov [edi+5],bl
%%drawcf
    test bh,%8
    jz %%drawdf
    mov [edi+4],bh
%%drawdf
    mov ebx,[ecx+4]
    or ebx,ebx
    jz %%drawd2f
    add ebx,edx
    test bl,%8
    jz %%drawa2f
    mov [edi+3],bl
%%drawa2f
    test bh,%8
    jz %%drawb2f
    mov [edi+2],bh
%%drawb2f
    shr ebx,16
    test bl,%8
    jz %%drawc2f
    mov [edi+1],bl
%%drawc2f
    test bh,%8
    jz %%drawd2f
    mov [edi],bh
%%drawd2f
    add ecx,8
    add edi,288
    dec dword[tleftnb]
    jnz %%nextbf
    sub edi,288*8
    jmp %5
%%flipypart
    add edi,288*7
    test word[vrama+eax],4000h
    jnz near %%flipxypart
    mov dword[tleftnb],8
%%nextbm
    mov ebx,[ecx]
    or ebx,ebx
    jz %%drawdm
    add ebx,edx
    test bl,%8
    jz %%drawam
    mov [edi],bl
%%drawam
    test bh,%8
    jz %%drawbm
    mov [edi+1],bh
%%drawbm
    shr ebx,16
    test bl,%8
    jz %%drawcm
    mov [edi+2],bl
%%drawcm
    test bh,%8
    jz %%drawdm
    mov [edi+3],bh
%%drawdm
    mov ebx,[ecx+4]
    or ebx,ebx
    jz %%drawd2m
    add ebx,edx
    test bl,%8
    jz %%drawa2m
    mov [edi+4],bl
%%drawa2m
    test bh,%8
    jz %%drawb2m
    mov [edi+5],bh
%%drawb2m
    shr ebx,16
    test bl,%8
    jz %%drawc2m
    mov [edi+6],bl
%%drawc2m
    test bh,%8
    jz %%drawd2m
    mov [edi+7],bh
%%drawd2m
    add ecx,8
    sub edi,288
    dec dword[tleftnb]
    jnz %%nextbm
    add edi,288
    jmp %5
%%flipxypart
    mov dword[tleftnb],8
%%nextbfm
    mov ebx,[ecx]
    or ebx,ebx
    jz %%drawdfm
    add ebx,edx
    test bl,%8
    jz %%drawafm
    mov [edi+7],bl
%%drawafm
    test bh,%8
    jz %%drawbfm
    mov [edi+6],bh
%%drawbfm
    shr ebx,16
    test bl,%8
    jz %%drawcfm
    mov [edi+5],bl
%%drawcfm
    test bh,%8
    jz %%drawdfm
    mov [edi+4],bh
%%drawdfm
    mov ebx,[ecx+4]
    or ebx,ebx
    jz %%drawd2fm
    add ebx,edx
    test bl,%8
    jz %%drawa2fm
    mov [edi+3],bl
%%drawa2fm
    test bh,%8
    jz %%drawb2fm
    mov [edi+2],bh
%%drawb2fm
    shr ebx,16
    test bl,%8
    jz %%drawc2fm
    mov [edi+1],bl
%%drawc2fm
    test bh,%8
    jz %%drawd2fm
    mov [edi],bh
%%drawd2fm
    add ecx,8
    sub edi,288
    dec dword[tleftnb]
    jnz %%nextbfm
    add edi,288
%5
    mov ebx,[ng16bbgval]
    add ax,2
    inc dword[bg1totng+ebx*4]
    add edi,8
    test eax,03Fh
    jz %%tileadd
%%next
    dec byte[tleftn]
    jnz near %4
    pop ebx
    ret
%%docache
    call %3
    jmp %%returnfromcache
%%tileadd
    add ax,[bgtxadd]
    jmp %%next
%endmacro

%macro drawtileng16x16 8
    ; tile value : bit 15 = flipy, bit 14 = flipx, bit 13 = priority value
    ;              bit 10-12 = palette, 0-9=tile#
    mov ebx,[ng16bbgval]
    mov dl,ch
    inc dword[bg1drwng+ebx*4]
    and ecx,3FFh
    and edx,1Fh
    add ecx,[ngptrdat2]
    add cx,[taddnfy16x16]
    test dword[vrama+eax],8000h
    jz %%noflipy
    add cx,[taddfy16x16]
%%noflipy
    test dword[vrama+eax],4000h
    jz %%noflipx
    inc cx
%%noflipx
%%nexttile
    push ecx
    push edx
    mov edx,[%6+edx*4]
    %7
    jnz near %%docache
%%returnfromcache
    cmp byte[%1+ecx],2
    je near %%done
    cmp byte[%1+ecx],0
    je near %%parttile
    %2
    ; start drawing from ecx
    test dword[vrama+eax],8000h
    jnz near %%flipyfull
    test dword[vrama+eax],4000h
    jnz near %%flipxfull
    push eax
    mov ebx,[ecx]
    mov eax,[ecx+4]
    add ebx,edx
    add eax,edx
    mov [edi],ebx
    mov [edi+4],eax
    mov ebx,[ecx+8]
    mov eax,[ecx+12]
    add ebx,edx
    add eax,edx
    mov [edi+288],ebx
    mov [edi+288+4],eax
    mov ebx,[ecx+16]
    mov eax,[ecx+20]
    add ebx,edx
    add eax,edx
    mov [edi+288*2],ebx
    mov [edi+288*2+4],eax
    mov ebx,[ecx+24]
    mov eax,[ecx+28]
    add ebx,edx
    add eax,edx
    mov [edi+288*3],ebx
    mov [edi+288*3+4],eax
    mov ebx,[ecx+32]
    mov eax,[ecx+36]
    add ebx,edx
    add eax,edx
    mov [edi+288*4],ebx
    mov [edi+288*4+4],eax
    mov ebx,[ecx+40]
    mov eax,[ecx+44]
    add ebx,edx
    add eax,edx
    mov [edi+288*5],ebx
    mov [edi+288*5+4],eax
    mov ebx,[ecx+48]
    mov eax,[ecx+52]
    add ebx,edx
    add eax,edx
    mov [edi+288*6],ebx
    mov [edi+288*6+4],eax
    mov ebx,[ecx+56]
    mov eax,[ecx+60]
    add ebx,edx
    add eax,edx
    mov [edi+288*7],ebx
    mov [edi+288*7+4],eax
    pop eax
    jmp %%done
%%flipxfull
    push eax
    mov ebx,[ecx+4]
    mov eax,[ecx]
    bswap ebx
    bswap eax
    add ebx,edx
    add eax,edx
    mov [edi],ebx
    mov [edi+4],eax
    mov ebx,[ecx+12]
    mov eax,[ecx+8]
    bswap ebx
    bswap eax
    add ebx,edx
    add eax,edx
    mov [edi+288],ebx
    mov [edi+288+4],eax
    mov ebx,[ecx+20]
    mov eax,[ecx+16]
    bswap ebx
    bswap eax
    add ebx,edx
    add eax,edx
    mov [edi+288*2],ebx
    mov [edi+288*2+4],eax
    mov ebx,[ecx+28]
    mov eax,[ecx+24]
    bswap ebx
    bswap eax
    add ebx,edx
    add eax,edx
    mov [edi+288*3],ebx
    mov [edi+288*3+4],eax
    mov ebx,[ecx+36]
    mov eax,[ecx+32]
    bswap ebx
    bswap eax
    add ebx,edx
    add eax,edx
    mov [edi+288*4],ebx
    mov [edi+288*4+4],eax
    mov ebx,[ecx+44]
    mov eax,[ecx+40]
    bswap ebx
    bswap eax
    add ebx,edx
    add eax,edx
    mov [edi+288*5],ebx
    mov [edi+288*5+4],eax
    mov ebx,[ecx+52]
    mov eax,[ecx+48]
    bswap ebx
    bswap eax
    add ebx,edx
    add eax,edx
    mov [edi+288*6],ebx
    mov [edi+288*6+4],eax
    mov ebx,[ecx+60]
    mov eax,[ecx+56]
    bswap ebx
    bswap eax
    add ebx,edx
    add eax,edx
    mov [edi+288*7],ebx
    mov [edi+288*7+4],eax
    pop eax
    jmp %%done
%%flipyfull
    test word[vrama+eax],4000h
    jnz near %%flipxyfull
    push eax
    mov ebx,[ecx]
    mov eax,[ecx+4]
    add ebx,edx
    add eax,edx
    mov [edi+288*7],ebx
    mov [edi+288*7+4],eax
    mov ebx,[ecx+8]
    mov eax,[ecx+12]
    add ebx,edx
    add eax,edx
    mov [edi+288*6],ebx
    mov [edi+288*6+4],eax
    mov ebx,[ecx+16]
    mov eax,[ecx+20]
    add ebx,edx
    add eax,edx
    mov [edi+288*5],ebx
    mov [edi+288*5+4],eax
    mov ebx,[ecx+24]
    mov eax,[ecx+28]
    add ebx,edx
    add eax,edx
    mov [edi+288*4],ebx
    mov [edi+288*4+4],eax
    mov ebx,[ecx+32]
    mov eax,[ecx+36]
    add ebx,edx
    add eax,edx
    mov [edi+288*3],ebx
    mov [edi+288*3+4],eax
    mov ebx,[ecx+40]
    mov eax,[ecx+44]
    add ebx,edx
    add eax,edx
    mov [edi+288*2],ebx
    mov [edi+288*2+4],eax
    mov ebx,[ecx+48]
    mov eax,[ecx+52]
    add ebx,edx
    add eax,edx
    mov [edi+288],ebx
    mov [edi+288+4],eax
    mov ebx,[ecx+56]
    mov eax,[ecx+60]
    add ebx,edx
    add eax,edx
    mov [edi],ebx
    mov [edi+4],eax
    pop eax
    jmp %%done
%%flipxyfull
    push eax
    mov ebx,[ecx+4]
    mov eax,[ecx]
    bswap ebx
    bswap eax
    add ebx,edx
    add eax,edx
    mov [edi+288*7],ebx
    mov [edi+288*7+4],eax
    mov ebx,[ecx+12]
    mov eax,[ecx+8]
    bswap ebx
    bswap eax
    add ebx,edx
    add eax,edx
    mov [edi+288*6],ebx
    mov [edi+288*6+4],eax
    mov ebx,[ecx+20]
    mov eax,[ecx+16]
    bswap ebx
    bswap eax
    add ebx,edx
    add eax,edx
    mov [edi+288*5],ebx
    mov [edi+288*5+4],eax
    mov ebx,[ecx+28]
    mov eax,[ecx+24]
    bswap ebx
    bswap eax
    add ebx,edx
    add eax,edx
    mov [edi+288*4],ebx
    mov [edi+288*4+4],eax
    mov ebx,[ecx+36]
    mov eax,[ecx+32]
    bswap ebx
    bswap eax
    add ebx,edx
    add eax,edx
    mov [edi+288*3],ebx
    mov [edi+288*3+4],eax
    mov ebx,[ecx+44]
    mov eax,[ecx+40]
    bswap ebx
    bswap eax
    add ebx,edx
    add eax,edx
    mov [edi+288*2],ebx
    mov [edi+288*2+4],eax
    mov ebx,[ecx+52]
    mov eax,[ecx+48]
    bswap ebx
    bswap eax
    add ebx,edx
    add eax,edx
    mov [edi+288],ebx
    mov [edi+288+4],eax
    mov ebx,[ecx+60]
    mov eax,[ecx+56]
    bswap ebx
    bswap eax
    add ebx,edx
    add eax,edx
    mov [edi],ebx
    mov [edi+4],eax
    pop eax
    jmp %%done
%%parttile
    %2
    ; start drawing from ecx to edi
    test word[vrama+eax],8000h
    jnz near %%flipypart
    test word[vrama+eax],4000h
    jnz near %%flipxpart
    mov dword[tleftnb],8
%%nextb
    mov ebx,[ecx]
    or ebx,ebx
    jz %%drawd
    add ebx,edx
    test bl,%8
    jz %%drawa
    mov [edi],bl
%%drawa
    test bh,%8
    jz %%drawb
    mov [edi+1],bh
%%drawb
    shr ebx,16
    test bl,%8
    jz %%drawc
    mov [edi+2],bl
%%drawc
    test bh,%8
    jz %%drawd
    mov [edi+3],bh
%%drawd
    mov ebx,[ecx+4]
    or ebx,ebx
    jz %%drawd2
    add ebx,edx
    test bl,%8
    jz %%drawa2
    mov [edi+4],bl
%%drawa2
    test bh,%8
    jz %%drawb2
    mov [edi+5],bh
%%drawb2
    shr ebx,16
    test bl,%8
    jz %%drawc2
    mov [edi+6],bl
%%drawc2
    test bh,%8
    jz %%drawd2
    mov [edi+7],bh
%%drawd2
    add ecx,8
    add edi,288
    dec dword[tleftnb]
    jnz %%nextb
    sub edi,288*8
    jmp %%done
%%flipxpart
    mov dword[tleftnb],8
%%nextbf
    mov ebx,[ecx]
    or ebx,ebx
    jz %%drawdf
    add ebx,edx
    test bl,%8
    jz %%drawaf
    mov [edi+7],bl
%%drawaf
    test bh,%8
    jz %%drawbf
    mov [edi+6],bh
%%drawbf
    shr ebx,16
    test bl,%8
    jz %%drawcf
    mov [edi+5],bl
%%drawcf
    test bh,%8
    jz %%drawdf
    mov [edi+4],bh
%%drawdf
    mov ebx,[ecx+4]
    or ebx,ebx
    jz %%drawd2f
    add ebx,edx
    test bl,%8
    jz %%drawa2f
    mov [edi+3],bl
%%drawa2f
    test bh,%8
    jz %%drawb2f
    mov [edi+2],bh
%%drawb2f
    shr ebx,16
    test bl,%8
    jz %%drawc2f
    mov [edi+1],bl
%%drawc2f
    test bh,%8
    jz %%drawd2f
    mov [edi],bh
%%drawd2f
    add ecx,8
    add edi,288
    dec dword[tleftnb]
    jnz %%nextbf
    sub edi,288*8
    jmp %%done
%%flipypart
    add edi,288*7
    test word[vrama+eax],4000h
    jnz near %%flipxypart
    mov dword[tleftnb],8
%%nextbm
    mov ebx,[ecx]
    or ebx,ebx
    jz %%drawdm
    add ebx,edx
    test bl,%8
    jz %%drawam
    mov [edi],bl
%%drawam
    test bh,%8
    jz %%drawbm
    mov [edi+1],bh
%%drawbm
    shr ebx,16
    test bl,%8
    jz %%drawcm
    mov [edi+2],bl
%%drawcm
    test bh,%8
    jz %%drawdm
    mov [edi+3],bh
%%drawdm
    mov ebx,[ecx+4]
    or ebx,ebx
    jz %%drawd2m
    add ebx,edx
    test bl,%8
    jz %%drawa2m
    mov [edi+4],bl
%%drawa2m
    test bh,%8
    jz %%drawb2m
    mov [edi+5],bh
%%drawb2m
    shr ebx,16
    test bl,%8
    jz %%drawc2m
    mov [edi+6],bl
%%drawc2m
    test bh,%8
    jz %%drawd2m
    mov [edi+7],bh
%%drawd2m
    add ecx,8
    sub edi,288
    dec dword[tleftnb]
    jnz %%nextbm
    add edi,288
    jmp %%done
%%flipxypart
    mov dword[tleftnb],8
%%nextbfm
    mov ebx,[ecx]
    or ebx,ebx
    jz %%drawdfm
    add ebx,edx
    test bl,%8
    jz %%drawafm
    mov [edi+7],bl
%%drawafm
    test bh,%8
    jz %%drawbfm
    mov [edi+6],bh
%%drawbfm
    shr ebx,16
    test bl,%8
    jz %%drawcfm
    mov [edi+5],bl
%%drawcfm
    test bh,%8
    jz %%drawdfm
    mov [edi+4],bh
%%drawdfm
    mov ebx,[ecx+4]
    or ebx,ebx
    jz %%drawd2fm
    add ebx,edx
    test bl,%8
    jz %%drawa2fm
    mov [edi+3],bl
%%drawa2fm
    test bh,%8
    jz %%drawb2fm
    mov [edi+2],bh
%%drawb2fm
    shr ebx,16
    test bl,%8
    jz %%drawc2fm
    mov [edi+1],bl
%%drawc2fm
    test bh,%8
    jz %%drawd2fm
    mov [edi],bh
%%drawd2fm
    add ecx,8
    sub edi,288
    dec dword[tleftnb]
    jnz %%nextbfm
    add edi,288
%%done
    pop edx
    pop ecx
    inc cx
    test dword[vrama+eax],4000h
    jz %%noflipxb
    sub cx,2
%%noflipxb
    add edi,8
    xor dword[switch16x16],1
    jnz near %%nexttile
%%ntile
    mov ebx,[ng16bbgval]
    add ax,2
    inc dword[bg1totng+ebx*4]
    test eax,03Fh
    jz %%tileadd
%%next
    dec byte[tleftn]
    jnz near %4
    pop ebx
    ret
%5
    add edi,16
    jmp %%ntile
%%docache
    call %3
    jmp %%returnfromcache
%%tileadd
    add ax,[bgtxadd]
    jmp %%next
%endmacro

%macro ProcessBuildWindow 1
    mov dword[ngwinen],0
    test byte[winbg1enval+ebx+%1*256],0Ah
    jz %%nowindowing
    push eax
    push ebx
;NEWSYM winlogicaval, times 256 dw 0
    mov al,[winlogicaval+ebx*2]
    shr al,%1*2
    and al,03h
    mov [nglogicval],al
    mov eax,ebx
    add ebx,%1*256
    call BuildWindow
    mov eax,edi
    sub eax,esi
    cmp dword[ngwintable],0
    jne %%notzero
    sub [ngwintable+4],eax
    jmp %%done
%%notzero
    sub [ngwintable],eax
%%done
    pop ebx
    pop eax
%%nowindowing
%endmacro

%macro drawbgtileng 2
    mov dword[ng16bprval],0
    mov dword[ng16bbgval],%1
    cmp byte[t16x161+ebx+%1*256],1
    je near .tiles16x16
    push ebx
    mov eax,[BGPT1+ebx*2+%1*512]
    test ecx,100h
    jz .noyinc
    add eax,[BGPT1Y+ebx*2+%1*512]
.noyinc
    lea ecx,[ecx*8]
    and ecx,07C0h      ; 1Fh*40h
    add eax,ecx
    mov ecx,[BG1SXl+ebx*2+%1*512]
    mov edx,[BGPT1X+ebx*2+%1*512]
    test ecx,100h
    jz .noxinc
    add eax,edx
    neg dx
.noxinc
    mov edi,ecx
    sub dx,64
    and ecx,0F8h
    and eax,0FFFFh
    shr ecx,2
    mov [bgtxadd],edx
    mov [bgtxad+ebx*2+%2*512],dx
    add eax,ecx
    mov ecx,[BGOPT1+ebx*2+%1*512]
    mov edx,[BGMA+ebx]
    and edi,07h
    and edx,07h
    and ecx,0FFFFh
    mov edx,[colormodedef+edx*4+%1]
    neg edi
    cmp dl,2
    jne near .no4bit
    shr ecx,5
    add edi,esi
    mov [ngptrdat+%2*1024+ebx*4],ecx
    mov [ngptrdat2],ecx
    mov [ngceax+%2*1024+ebx*4],eax
    mov [ngcedi+%2*1024+ebx*4],edi
    ; eax = pointer to beginning of tile area
    ProcessBuildWindow %1
    jmp drawtileng4b
.no4bit
    cmp dl,1
    jne near .no2bit
    shr ecx,4
    add edi,esi
    mov [ngptrdat+%2*1024+ebx*4],ecx
    mov [ngptrdat2],ecx
    mov [ngceax+%2*1024+ebx*4],eax
    mov [ngcedi+%2*1024+ebx*4],edi
    ; eax = pointer to beginning of tile area
    mov dword[mode0add],0
    ProcessBuildWindow %1
    cmp byte[BGMA+ebx],0
    jne .nomode0
    mov ebx,[mode0ads]
    mov [mode0add],ebx
.nomode0
    jmp drawtileng2b
.no2bit
    cmp dl,3
    jne near .no8bit
    shr ecx,6
    add edi,esi
    mov [ngptrdat+%2*1024+ebx*4],ecx
    mov [ngptrdat2],ecx
    mov [ngceax+%2*1024+ebx*4],eax
    mov [ngcedi+%2*1024+ebx*4],edi
    ; eax = pointer to beginning of tile area
    ProcessBuildWindow %1
    jmp drawtileng8b
.no8bit
    pop ebx
    ret

.tiles16x16
    mov dword[taddnfy16x16],0
    mov dword[taddfy16x16],16
    test ecx,08h
    jz .nobottomy
    mov dword[taddnfy16x16],16
    mov dword[taddfy16x16],-16
.nobottomy
    push ebx
    mov eax,[BGPT1+ebx*2+%1*512]
    test ecx,200h
    jz .noyinc2
    add eax,[BGPT1Y+ebx*2+%1*512]
.noyinc2
    lea ecx,[ecx*4]
    and ecx,07C0h      ; 1Fh*40h
    add eax,ecx
    mov ecx,[BG1SXl+ebx*2+%1*512]
    mov edx,[BGPT1X+ebx*2+%1*512]
    test ecx,200h
    jz .noxinc2
    add eax,edx
    neg dx
.noxinc2
    mov edi,ecx
    sub dx,64
    and ecx,1F0h
    and eax,0FFFFh
    shr ecx,3
    mov [bgtxadd],edx
    mov [bgtxad+ebx*2+%2*512],dx
    add eax,ecx
    mov ecx,[BGOPT1+ebx*2+%1*512]
    mov edx,[BGMA+ebx]
    and edi,0Fh
    and edx,07h
    and ecx,0FFFFh
    mov edx,[colormodedef+edx*4+%1]
    neg edi
    cmp dl,2
    jne near .no4bit2
    shr ecx,5
    add edi,esi
    mov [ngptrdat+%2*1024+ebx*4],ecx
    mov [ngptrdat2],ecx
    mov [ngceax+%2*1024+ebx*4],eax
    mov [ngcedi+%2*1024+ebx*4],edi
    ; eax = pointer to beginning of tile area
    ProcessBuildWindow %1
    jmp drawtileng16x164b
.no4bit2
    cmp dl,1
    jne near .no2bit2
    shr ecx,4
    add edi,esi
    mov [ngptrdat+%2*1024+ebx*4],ecx
    mov [ngptrdat2],ecx
    mov [ngceax+%2*1024+ebx*4],eax
    mov [ngcedi+%2*1024+ebx*4],edi
    ; eax = pointer to beginning of tile area
    mov dword[mode0add],0
    ProcessBuildWindow %1
    cmp byte[BGMA+ebx],0
    jne .nomode02
    mov ebx,[mode0ads]
    mov [mode0add],ebx
.nomode02
    jmp drawtileng16x162b
.no2bit2
    cmp dl,3
    jne near .no8bit
    shr ecx,6
    add edi,esi
    mov [ngptrdat+%2*1024+ebx*4],ecx
    mov [ngptrdat2],ecx
    mov [ngceax+%2*1024+ebx*4],eax
    mov [ngcedi+%2*1024+ebx*4],edi
    ; eax = pointer to beginning of tile area
    ProcessBuildWindow %1
    jmp drawtileng16x168b
.no8bit2
    pop ebx
    ret
%endmacro

%macro drawbgtilengpr1 2
    mov dword[ng16bprval],2000h
    mov dword[ng16bbgval],%1
    cmp byte[t16x161+ebx+%1*256],1
    je near .tiles16x16
    push ebx
    mov edx,[BGMA+ebx]
    mov ecx,[bgtxad+ebx*2+%2*512]
    and edx,07h
    mov [bgtxadd],cx
    mov ecx,[ngptrdat+%2*1024+ebx*4]
    mov edx,[colormodedef+edx*4+%1]
    mov [ngptrdat2],ecx
    mov eax,[ngceax+%2*1024+ebx*4]
    mov edi,[ngcedi+%2*1024+ebx*4]
    cmp dl,2
    jne near .no4bit
    ; eax = pointer to beginning of tile area
    ProcessBuildWindow %1
    jmp drawtileng4b
.no4bit
    cmp dl,1
    jne near .no2bit
    ; eax = pointer to beginning of tile area
    mov dword[mode0add],0
    ProcessBuildWindow %1
    cmp byte[BGMA+ebx],0
    jne .nomode0
    mov ebx,[mode0ads]
    mov [mode0add],ebx
.nomode0
    jmp drawtileng2b
.no2bit
    cmp dl,3
    jne near .no8bit
    ; eax = pointer to beginning of tile area
    ProcessBuildWindow %1
    jmp drawtileng8b
.no8bit
    pop ebx
    ret
.tiles16x16
    mov ecx,[BG1SYl+ebx*2+%1*512]
    and ecx,0FFFFh
    mov dword[taddnfy16x16],0
    add ecx,ebx
    mov dword[taddfy16x16],16
    test ecx,08h
    jz .nobottomy
    mov dword[taddnfy16x16],16
    mov dword[taddfy16x16],-16
.nobottomy
    push ebx
    mov edx,[BGMA+ebx]
    mov ecx,[bgtxad+ebx*2+%2*512]
    and edx,07h
    mov [bgtxadd],cx
    mov ecx,[ngptrdat+%2*1024+ebx*4]
    mov edx,[colormodedef+edx*4+%1]
    mov [ngptrdat2],ecx
    mov eax,[ngceax+%2*1024+ebx*4]
    mov edi,[ngcedi+%2*1024+ebx*4]
    cmp dl,2
    jne near .no4bit2
    ; eax = pointer to beginning of tile area
    ProcessBuildWindow %1
    jmp drawtileng16x164b
.no4bit2
    cmp dl,1
    jne near .no2bit2
    ; eax = pointer to beginning of tile area
    mov dword[mode0add],0
    ProcessBuildWindow %1
    cmp byte[BGMA+ebx],0
    jne .nomode02
    mov ebx,[mode0ads]
    mov [mode0add],ebx
.nomode02
    jmp drawtileng16x162b
.no2bit2
    cmp dl,3
    jne near .no8bit2
    ; eax = pointer to beginning of tile area
    ProcessBuildWindow %1
    jmp drawtileng16x168b
.no8bit2
    pop ebx
    ret
%endmacro

%macro drawlineng 8
    ; tile value : bit 15 = flipy, bit 14 = flipx, bit 13 = priority value
    ;              bit 10-12 = palette, 0-9=tile#
    mov ebx,[ng16bbgval]
    mov dl,ch
    inc dword[bg1drwng+ebx*4]
    and ecx,3FFh
    and edx,1Fh
    add ecx,[ngptrdat2]
    mov edx,[%6+edx*4]
    %7
    jnz near %%docache
%%returnfromcache
    cmp byte[%1+ecx],2
    je near %5
    cmp byte[%1+ecx],0
    je near %%parttile
    %2
    ; start drawing from ecx
    test dword[vrama+eax],8000h
    jnz near %%flipyfull
    add ecx,[yposng]
    test dword[vrama+eax],4000h
    jnz near %%flipxfull
    mov ebx,[ecx]
    add ebx,edx
    mov [edi],ebx
    mov ebx,[ecx+4]
    add ebx,edx
    mov [edi+4],ebx
    jmp %5
%%flipxfull
    mov ebx,[ecx+4]
    bswap ebx
    add ebx,edx
    mov [edi],ebx
    mov ebx,[ecx]
    bswap ebx
    add ebx,edx
    mov [edi+4],ebx
    jmp %5
%%flipyfull
    add ecx,[flipyposng]
    test word[vrama+eax],4000h
    jnz near %%flipxyfull
    mov ebx,[ecx]
    add ebx,edx
    mov [edi],ebx
    mov ebx,[ecx+4]
    add ebx,edx
    mov [edi+4],ebx
    jmp %5
%%flipxyfull
    mov ebx,[ecx+4]
    bswap ebx
    add ebx,edx
    mov [edi],ebx
    mov ebx,[ecx]
    bswap ebx
    add ebx,edx
    mov [edi+4],ebx
    jmp %5
%%parttile
    %2
    ; start drawing from ecx to edi
    test word[vrama+eax],8000h
    jnz near %%flipypart
    add ecx,[yposng]
    test word[vrama+eax],4000h
    jnz near %%flipxpart
    mov ebx,[ecx]
    or ebx,ebx
    jz %%drawd
    add ebx,edx
    test bl,%8
    jz %%drawa
    mov [edi],bl
%%drawa
    test bh,%8
    jz %%drawb
    mov [edi+1],bh
%%drawb
    shr ebx,16
    test bl,%8
    jz %%drawc
    mov [edi+2],bl
%%drawc
    test bh,%8
    jz %%drawd
    mov [edi+3],bh
%%drawd
    mov ebx,[ecx+4]
    or ebx,ebx
    jz %%drawd2
    add ebx,edx
    test bl,%8
    jz %%drawa2
    mov [edi+4],bl
%%drawa2
    test bh,%8
    jz %%drawb2
    mov [edi+5],bh
%%drawb2
    shr ebx,16
    test bl,%8
    jz %%drawc2
    mov [edi+6],bl
%%drawc2
    test bh,%8
    jz %%drawd2
    mov [edi+7],bh
%%drawd2
    jmp %5

%%flipxpart
    mov ebx,[ecx]
    or ebx,ebx
    jz %%drawdf
    add ebx,edx
    test bl,%8
    jz %%drawaf
    mov [edi+7],bl
%%drawaf
    test bh,%8
    jz %%drawbf
    mov [edi+6],bh
%%drawbf
    shr ebx,16
    test bl,%8
    jz %%drawcf
    mov [edi+5],bl
%%drawcf
    test bh,%8
    jz %%drawdf
    mov [edi+4],bh
%%drawdf
    mov ebx,[ecx+4]
    or ebx,ebx
    jz %%drawd2f
    add ebx,edx
    test bl,%8
    jz %%drawa2f
    mov [edi+3],bl
%%drawa2f
    test bh,%8
    jz %%drawb2f
    mov [edi+2],bh
%%drawb2f
    shr ebx,16
    test bl,%8
    jz %%drawc2f
    mov [edi+1],bl
%%drawc2f
    test bh,%8
    jz %%drawd2f
    mov [edi],bh
%%drawd2f
    jmp %5

%%flipypart
    add ecx,[flipyposng]
    test word[vrama+eax],4000h
    jnz near %%flipxypart
    mov ebx,[ecx]
    or ebx,ebx
    jz %%drawdm
    add ebx,edx
    test bl,%8
    jz %%drawam
    mov [edi],bl
%%drawam
    test bh,%8
    jz %%drawbm
    mov [edi+1],bh
%%drawbm
    shr ebx,16
    test bl,%8
    jz %%drawcm
    mov [edi+2],bl
%%drawcm
    test bh,%8
    jz %%drawdm
    mov [edi+3],bh
%%drawdm
    mov ebx,[ecx+4]
    or ebx,ebx
    jz %%drawd2m
    add ebx,edx
    test bl,%8
    jz %%drawa2m
    mov [edi+4],bl
%%drawa2m
    test bh,%8
    jz %%drawb2m
    mov [edi+5],bh
%%drawb2m
    shr ebx,16
    test bl,%8
    jz %%drawc2m
    mov [edi+6],bl
%%drawc2m
    test bh,%8
    jz %%drawd2m
    mov [edi+7],bh
%%drawd2m
    jmp %5

%%flipxypart
    mov ebx,[ecx]
    or ebx,ebx
    jz %%drawdfm
    add ebx,edx
    test bl,%8
    jz %%drawafm
    mov [edi+7],bl
%%drawafm
    test bh,%8
    jz %%drawbfm
    mov [edi+6],bh
%%drawbfm
    shr ebx,16
    test bl,%8
    jz %%drawcfm
    mov [edi+5],bl
%%drawcfm
    test bh,%8
    jz %%drawdfm
    mov [edi+4],bh
%%drawdfm
    mov ebx,[ecx+4]
    or ebx,ebx
    jz %%drawd2fm
    add ebx,edx
    test bl,%8
    jz %%drawa2fm
    mov [edi+3],bl
%%drawa2fm
    test bh,%8
    jz %%drawb2fm
    mov [edi+2],bh
%%drawb2fm
    shr ebx,16
    test bl,%8
    jz %%drawc2fm
    mov [edi+1],bl
%%drawc2fm
    test bh,%8
    jz %%drawd2fm
    mov [edi],bh
%%drawd2fm
%5
    mov ebx,[ng16bbgval]
    add ax,2
    inc dword[bg1totng+ebx*4]
    add edi,8
    test eax,03Fh
    jz %%tileadd
%%next
    dec byte[tleftn]
    jnz near %4
    pop ebx
    cmp byte[curmosaicsz],1
    jne near domosaicng
    ret
%%docache
    call %3
    jmp %%returnfromcache
%%tileadd
    add ax,[bgtxadd]
    jmp %%next
%endmacro

%macro drawlineng16x16 8
    ; tile value : bit 15 = flipy, bit 14 = flipx, bit 13 = priority value
    ;              bit 10-12 = palette, 0-9=tile#
    mov ebx,[ng16bbgval]
    mov dl,ch
    inc dword[bg1drwng+ebx*4]
    and ecx,3FFh
    and edx,1Fh
    add ecx,[ngptrdat2]
    add cx,[taddnfy16x16]
    test dword[vrama+eax],8000h
    jz %%noflipy
    add cx,[taddfy16x16]
%%noflipy
    test dword[vrama+eax],4000h
    jz %%noflipx
    inc cx
%%noflipx
%%nexttile
    push ecx
    push edx
    mov edx,[%6+edx*4]
    %7
    jnz near %%docache
%%returnfromcache
    cmp byte[%1+ecx],2
    je near %%done
    cmp byte[%1+ecx],0
    je near %%parttile
    %2
    ; start drawing from ecx
    test dword[vrama+eax],8000h
    jnz near %%flipyfull
    add ecx,[yposng]
    test dword[vrama+eax],4000h
    jnz near %%flipxfull
    mov ebx,[ecx]
    add ebx,edx
    mov [edi],ebx
    mov ebx,[ecx+4]
    add ebx,edx
    mov [edi+4],ebx
    jmp %%done
%%flipxfull
    mov ebx,[ecx+4]
    bswap ebx
    add ebx,edx
    mov [edi],ebx
    mov ebx,[ecx]
    bswap ebx
    add ebx,edx
    mov [edi+4],ebx
    jmp %%done
%%flipyfull
    add ecx,[flipyposng]
    test word[vrama+eax],4000h
    jnz near %%flipxyfull
    mov ebx,[ecx]
    add ebx,edx
    mov [edi],ebx
    mov ebx,[ecx+4]
    add ebx,edx
    mov [edi+4],ebx
    jmp %%done
%%flipxyfull
    mov ebx,[ecx+4]
    bswap ebx
    add ebx,edx
    mov [edi],ebx
    mov ebx,[ecx]
    bswap ebx
    add ebx,edx
    mov [edi+4],ebx
    jmp %%done
%%parttile
    %2
    ; start drawing from ecx to edi
    test word[vrama+eax],8000h
    jnz near %%flipypart
    add ecx,[yposng]
    test word[vrama+eax],4000h
    jnz near %%flipxpart
    mov ebx,[ecx]
    or ebx,ebx
    jz %%drawd
    add ebx,edx
    test bl,%8
    jz %%drawa
    mov [edi],bl
%%drawa
    test bh,%8
    jz %%drawb
    mov [edi+1],bh
%%drawb
    shr ebx,16
    test bl,%8
    jz %%drawc
    mov [edi+2],bl
%%drawc
    test bh,%8
    jz %%drawd
    mov [edi+3],bh
%%drawd
    mov ebx,[ecx+4]
    or ebx,ebx
    jz %%drawd2
    add ebx,edx
    test bl,%8
    jz %%drawa2
    mov [edi+4],bl
%%drawa2
    test bh,%8
    jz %%drawb2
    mov [edi+5],bh
%%drawb2
    shr ebx,16
    test bl,%8
    jz %%drawc2
    mov [edi+6],bl
%%drawc2
    test bh,%8
    jz %%drawd2
    mov [edi+7],bh
%%drawd2
    jmp %%done

%%flipxpart
    mov ebx,[ecx]
    or ebx,ebx
    jz %%drawdf
    add ebx,edx
    test bl,%8
    jz %%drawaf
    mov [edi+7],bl
%%drawaf
    test bh,%8
    jz %%drawbf
    mov [edi+6],bh
%%drawbf
    shr ebx,16
    test bl,%8
    jz %%drawcf
    mov [edi+5],bl
%%drawcf
    test bh,%8
    jz %%drawdf
    mov [edi+4],bh
%%drawdf
    mov ebx,[ecx+4]
    or ebx,ebx
    jz %%drawd2f
    add ebx,edx
    test bl,%8
    jz %%drawa2f
    mov [edi+3],bl
%%drawa2f
    test bh,%8
    jz %%drawb2f
    mov [edi+2],bh
%%drawb2f
    shr ebx,16
    test bl,%8
    jz %%drawc2f
    mov [edi+1],bl
%%drawc2f
    test bh,%8
    jz %%drawd2f
    mov [edi],bh
%%drawd2f
    jmp %%done

%%flipypart
    add ecx,[flipyposng]
    test word[vrama+eax],4000h
    jnz near %%flipxypart
    mov ebx,[ecx]
    or ebx,ebx
    jz %%drawdm
    add ebx,edx
    test bl,%8
    jz %%drawam
    mov [edi],bl
%%drawam
    test bh,%8
    jz %%drawbm
    mov [edi+1],bh
%%drawbm
    shr ebx,16
    test bl,%8
    jz %%drawcm
    mov [edi+2],bl
%%drawcm
    test bh,%8
    jz %%drawdm
    mov [edi+3],bh
%%drawdm
    mov ebx,[ecx+4]
    or ebx,ebx
    jz %%drawd2m
    add ebx,edx
    test bl,%8
    jz %%drawa2m
    mov [edi+4],bl
%%drawa2m
    test bh,%8
    jz %%drawb2m
    mov [edi+5],bh
%%drawb2m
    shr ebx,16
    test bl,%8
    jz %%drawc2m
    mov [edi+6],bl
%%drawc2m
    test bh,%8
    jz %%drawd2m
    mov [edi+7],bh
%%drawd2m
    jmp %%done

%%flipxypart
    mov ebx,[ecx]
    or ebx,ebx
    jz %%drawdfm
    add ebx,edx
    test bl,%8
    jz %%drawafm
    mov [edi+7],bl
%%drawafm
    test bh,%8
    jz %%drawbfm
    mov [edi+6],bh
%%drawbfm
    shr ebx,16
    test bl,%8
    jz %%drawcfm
    mov [edi+5],bl
%%drawcfm
    test bh,%8
    jz %%drawdfm
    mov [edi+4],bh
%%drawdfm
    mov ebx,[ecx+4]
    or ebx,ebx
    jz %%drawd2fm
    add ebx,edx
    test bl,%8
    jz %%drawa2fm
    mov [edi+3],bl
%%drawa2fm
    test bh,%8
    jz %%drawb2fm
    mov [edi+2],bh
%%drawb2fm
    shr ebx,16
    test bl,%8
    jz %%drawc2fm
    mov [edi+1],bl
%%drawc2fm
    test bh,%8
    jz %%drawd2fm
    mov [edi],bh
%%drawd2fm
%%done
    pop edx
    pop ecx
    inc cx
    test dword[vrama+eax],4000h
    jz %%noflipxb
    sub cx,2
%%noflipxb
    add edi,8
    xor dword[switch16x16],1
    jnz near %%nexttile
%%ntile
    mov ebx,[ng16bbgval]
    add ax,2
    inc dword[bg1totng+ebx*4]
    test eax,03Fh
    jz %%tileadd
%%next
    dec byte[tleftn]
    jnz near %4
    pop ebx
    cmp byte[curmosaicsz],1
    jne near domosaicng
    ret
%5
    add edi,16
    jmp %%ntile
%%docache
    call %3
    jmp %%returnfromcache
%%tileadd
    add ax,[bgtxadd]
    jmp %%next
%endmacro

%macro drawbglineng 2
    mov dword[ng16bprval],0
    mov dword[ng16bbgval],%1
    cmp byte[bgmode],5
    jb %%nointerl
    test byte[intrlng+ebx],01h
    jz %%nointerl
    add ecx,ebx
    add ecx,[cfieldad]
%%nointerl
    push ebx
    mov byte[curmosaicsz],1
    xor eax,eax
    test byte[mosenng+ebx],1 << %1
    jz %%nomosaic
    mov al,[mosszng+ebx]
    or al,al
    jz %%nomosaic
    inc al
    mov byte[curmosaicsz],al
    mov cl,al
    mov al,bl
    div cl
    mul cl
    mov ebx,eax
    mov [pesimpng],esi
    mov edi,xtravbuf+16
    mov ecx,64
    xor eax,eax
    mov esi,xtravbuf+16
    rep stosd
    or ebx,ebx
    jnz %%nozeroline
    inc ebx
%%nozeroline
    mov ecx,[BG1SYl+ebx*2+%1*512]
    and ecx,0FFFFh
    add ecx,ebx
    jmp %%yesmosaic
%%nomosaic
    cmp byte[BGMA+ebx],5
    jae near .tiles16x8
%%yesmosaic
    cmp byte[t16x161+ebx+%1*256],1
    je near .tiles16x16
    cmp byte[osm2dis],1
    je .nooffsetm
    cmp byte[BGMA+ebx],2
    je near .offsetm
    cmp byte[bgmode],4
    je .nooffsetm
    cmp byte[BGMA+ebx],4
    je near .offsetm
.nooffsetm
    mov eax,[BGPT1+ebx*2+%1*512]
    test ecx,100h
    jz .noyinc
    add eax,[BGPT1Y+ebx*2+%1*512]
.noyinc
    lea ecx,[ecx*8]
    mov edx,ecx
    and ecx,07C0h      ; 1Fh*40h
    and edx,38h
    add eax,ecx
    mov [yposng],edx
    xor edx,38h
    mov ecx,[BG1SXl+ebx*2+%1*512]
    mov [flipyposng],edx
    mov edx,[BGPT1X+ebx*2+%1*512]
    test ecx,100h
    jz .noxinc
    add eax,edx
    neg dx
.noxinc
    mov edi,ecx
    sub dx,64
    and ecx,0F8h
    and eax,0FFFFh
    shr ecx,2
    mov [bgtxadd],edx
    mov [bgtxad+ebx*2+%2*512],dx
    add eax,ecx
    mov ecx,[BGOPT1+ebx*2+%1*512]
    mov edx,[BGMA+ebx]
    and edi,07h
    and edx,07h
    and ecx,0FFFFh
    mov edx,[colormodedef+edx*4+%1]
    neg edi
    cmp dl,2
    jne near .no4bit
    shr ecx,5
    add edi,esi
    mov [ngptrdat+%2*1024+ebx*4],ecx
    mov [ngptrdat2],ecx
    mov [ngceax+%2*1024+ebx*4],eax
    mov [ngcedi+%2*1024+ebx*4],edi
    ; eax = pointer to beginning of tile area
    ProcessBuildWindow %1
    jmp drawlineng4b
.no4bit
    cmp dl,1
    jne near .no2bit
    shr ecx,4
    add edi,esi
    mov [ngptrdat+%2*1024+ebx*4],ecx
    mov [ngptrdat2],ecx
    mov [ngceax+%2*1024+ebx*4],eax
    mov [ngcedi+%2*1024+ebx*4],edi
    ; eax = pointer to beginning of tile area
    mov dword[mode0add],0
    ProcessBuildWindow %1
    cmp byte[BGMA+ebx],0
    jne .nomode0
    mov ebx,[mode0ads]
    mov [mode0add],ebx
.nomode0
    jmp drawlineng2b
.no2bit
    cmp dl,3
    jne near .no8bit
    shr ecx,6
    add edi,esi
    mov [ngptrdat+%2*1024+ebx*4],ecx
    mov [ngptrdat2],ecx
    mov [ngceax+%2*1024+ebx*4],eax
    mov [ngcedi+%2*1024+ebx*4],edi
    ; eax = pointer to beginning of tile area
    ProcessBuildWindow %1
    jmp drawlineng8b
.no8bit
    pop ebx
    ret

.tiles16x16
    mov dword[taddnfy16x16],0
    mov dword[taddfy16x16],16
    test ecx,08h
    jz .nobottomy
    mov dword[taddnfy16x16],16
    mov dword[taddfy16x16],-16
.nobottomy
    mov eax,[BGPT1+ebx*2+%1*512]
    test ecx,200h
    jz .noyinc2
    add eax,[BGPT1Y+ebx*2+%1*512]
.noyinc2
    lea edx,[ecx*8]
    lea ecx,[ecx*4]
    and edx,38h
    and ecx,07C0h      ; 1Fh*40h
    mov [yposng],edx
    xor edx,38h
    add eax,ecx
    mov [flipyposng],edx
    mov ecx,[BG1SXl+ebx*2+%1*512]
    mov edx,[BGPT1X+ebx*2+%1*512]
    test ecx,200h
    jz .noxinc2
    add eax,edx
    neg dx
.noxinc2
    mov edi,ecx
    sub dx,64
    and ecx,1F0h
    and eax,0FFFFh
    shr ecx,3
    mov [bgtxadd],edx
    mov [bgtxad+ebx*2+%2*512],dx
    add eax,ecx
    mov ecx,[BGOPT1+ebx*2+%1*512]
    mov edx,[BGMA+ebx]
    and edi,0Fh
    and edx,07h
    and ecx,0FFFFh
    mov edx,[colormodedef+edx*4+%1]
    neg edi
    cmp dl,2
    jne near .no4bit2
    shr ecx,5
    add edi,esi
    mov [ngptrdat+%2*1024+ebx*4],ecx
    mov [ngptrdat2],ecx
    mov [ngceax+%2*1024+ebx*4],eax
    mov [ngcedi+%2*1024+ebx*4],edi
    ; eax = pointer to beginning of tile area
    ProcessBuildWindow %1
    jmp drawlineng16x164b
.no4bit2
    cmp dl,1
    jne near .no2bit2
    shr ecx,4
    add edi,esi
    mov [ngptrdat+%2*1024+ebx*4],ecx
    mov [ngptrdat2],ecx
    mov [ngceax+%2*1024+ebx*4],eax
    mov [ngcedi+%2*1024+ebx*4],edi
    ; eax = pointer to beginning of tile area
    mov dword[mode0add],0
    ProcessBuildWindow %1
    cmp byte[BGMA+ebx],0
    jne .nomode02
    mov ebx,[mode0ads]
    mov [mode0add],ebx
.nomode02
    jmp drawlineng16x162b
.no2bit2
    cmp dl,3
    jne near .no8bit
    shr ecx,6
    add edi,esi
    mov [ngptrdat+%2*1024+ebx*4],ecx
    mov [ngptrdat2],ecx
    mov [ngceax+%2*1024+ebx*4],eax
    mov [ngcedi+%2*1024+ebx*4],edi
    ; eax = pointer to beginning of tile area
    ProcessBuildWindow %1
    jmp drawlineng16x168b
.no8bit2
    pop ebx
    ret

.tiles16x8
    cmp byte[t16x161+ebx+%1*256],1
    je .tiles16x16hr
    mov dword[taddnfy16x16],0
    mov dword[taddfy16x16],0
    mov eax,[BGPT1+ebx*2+%1*512]
    test ecx,100h
    jz .noyinc2c
    add eax,[BGPT1Y+ebx*2+%1*512]
.noyinc2c
    lea ecx,[ecx*8]
    mov edx,ecx
    and ecx,07C0h      ; 1Fh*40h
    and edx,38h
    jmp .tiles16x8hr
.tiles16x16hr
    mov dword[taddnfy16x16],0
    mov dword[taddfy16x16],16
    test ecx,08h
    jz .nobottomy2
    mov dword[taddnfy16x16],16
    mov dword[taddfy16x16],-16
.nobottomy2
    mov eax,[BGPT1+ebx*2+%1*512]
    test ecx,200h
    jz .noyinc2b
    add eax,[BGPT1Y+ebx*2+%1*512]
.noyinc2b
    lea edx,[ecx*8]
    lea ecx,[ecx*4]
    and edx,38h
    and ecx,07C0h      ; 1Fh*40h
.tiles16x8hr
    mov [yposng],edx
    xor edx,38h
    add eax,ecx
    mov [flipyposng],edx
    mov ecx,[BG1SXl+ebx*2+%1*512]
    add ecx,ecx
    mov edx,[BGPT1X+ebx*2+%1*512]
    test ecx,200h
    jz .noxinc2b
    add eax,edx
    neg dx
.noxinc2b
    mov edi,ecx
    sub dx,64
    and ecx,01F0h
    and eax,0FFFFh
    shr ecx,3
    mov [bgtxadd],edx
    mov [bgtxad+ebx*2+%2*512],dx
    add eax,ecx
    mov ecx,[BGOPT1+ebx*2+%1*512]
    mov edx,[BGMA+ebx]
    and edi,0Fh
    and edx,07h
    and ecx,0FFFFh
    shr edi,1
    mov edx,[colormodedef+edx*4+%1]
    neg edi
    cmp dl,2
    jne near .no4bit2b
    shr ecx,5
    add edi,esi
    mov [ngptrdat+%2*1024+ebx*4],ecx
    mov [ngptrdat2],ecx
    mov [ngceax+%2*1024+ebx*4],eax
    mov [ngcedi+%2*1024+ebx*4],edi
    ; eax = pointer to beginning of tile area
    mov dword[cbgval],%1
    jmp drawlineng16x84b
.no4bit2b
    cmp dl,1
    jne near .no2bit2b
    shr ecx,4
    add edi,esi
    mov [ngptrdat+%2*1024+ebx*4],ecx
    mov [ngptrdat2],ecx
    mov [ngceax+%2*1024+ebx*4],eax
    mov [ngcedi+%2*1024+ebx*4],edi
    ; eax = pointer to beginning of tile area
    mov dword[mode0add],0
    mov dword[cbgval],%1
    jmp drawlineng16x82b
.no2bit2b
    pop ebx
    ret

    ; Offsetmode calculation : <b2-7,2109>*1024+<b3-7,2112>*32+<b3-7,2111>
.offsetm
    xor edx,edx
    mov dx,[BG3SYl+ebx*2]
;    and dx,0F8h
    shr edx,3
    shl edx,6
    xor eax,eax
    mov ax,[BGPT3+ebx*2]
    add ax,dx
    xor edx,edx
    mov dx,[BG3SXl+ebx*2]
    and dx,0F8h
    mov [ofsmcyps],ebx
    shr edx,3
    shl edx,1
    add ax,dx
    mov dx,[bg3scrolx]
    test dx,8000h
    jz .nooma
    and dx,0F000h
    shr dx,5
    add ax,dx
.nooma
;    cmp byte[BGMA+ebx],4
;    je .offsetm4
    add eax,40h
;.offsetm4
    mov edx,eax
    and edx,0FFFFFFC0h
    add edx,[vram]
    mov [ofsmcptr],edx
    and eax,3Fh
    mov [ofsmcptr2],eax
    mov eax,[BGPT1Y+ebx*2+%1*512]
    mov [ofsmady],eax
    mov eax,[BGPT1X+ebx*2+%1*512]
    mov [ofsmadx],eax
    mov eax,[BGPT1+ebx*2+%1*512]
    mov [ofsmtptr],eax
    mov [ofsmtptrs],eax
    test ecx,100h
    jz .noyincd
    add eax,[BGPT1Y+ebx*2+%1*512]
.noyincd
    lea ecx,[ecx*8]
    mov edx,ecx
    and ecx,07C0h      ; 1Fh*40h
    and edx,38h
    add eax,ecx
    mov [yposng],edx
    mov [yposngom],edx
    xor edx,38h
    mov ecx,[BG1SXl+ebx*2+%1*512]
    mov [flipyposng],edx
    mov [flipyposngom],edx
    mov edx,[BGPT1X+ebx*2+%1*512]
    test ecx,100h
    jz .noxincd
    add eax,edx
    add [ofsmtptr],edx
    neg dx
.noxincd
    mov edi,ecx
    sub dx,64
    and ecx,0F8h
    and eax,0FFFFh
    shr ecx,2
    mov [bgtxadd],edx
    mov [bgtxad+ebx*2+%2*512],dx
    add eax,ecx
    add [ofsmtptr],ecx
    mov [ofsmmptr],eax

    mov word[bgtxadd2],0
    cmp word[BGPT3X+ebx*2],0
    je .yesoverfl
    mov cx,word[BG3SXl+ebx*2]
    add cx,16
    test cx,100h
    jz .notoverfl
    add dword[ofsmcptr],800h
    sub word[bgtxadd2],800h
    jmp .yesoverfl
.notoverfl
    add word[bgtxadd2],800h
.yesoverfl

    mov dword[ofshvaladd],0
    mov ecx,[BGOPT1+ebx*2+%1*512]
    mov edx,[BGMA+ebx]
    and edi,07h
    and edx,07h
    and ecx,0FFFFh
    mov edx,[colormodedef+edx*4+%1]
    neg edi
    cmp dl,2
    jne near .no4bitd
    shr ecx,5
    add edi,esi
    mov [ngptrdat+%2*1024+ebx*4],ecx
    mov [ngptrdat2],ecx
    mov [ngceax+%2*1024+ebx*4],eax
    mov [ngcedi+%2*1024+ebx*4],edi
    ; eax = pointer to beginning of tile area
    mov dword[ofsmval],2000h << %1
    mov dword[ofsmvalh],2000h << %1
    cmp byte[hdmaearlstart],0
    je .ofsmvalhack
    mov dword[ofsmvalh],0
.ofsmvalhack
    mov dword[cbgval],%1
    ProcessBuildWindow %1
    jmp drawlinengom4b
.no4bitd
    cmp dl,1
    jne near .no2bitdn
    ; eax = pointer to beginning of tile area
    shr ecx,4
    add edi,esi
    mov [ngptrdat+%2*1024+ebx*4],ecx
    mov [ngptrdat2],ecx
    mov [ngceax+%2*1024+ebx*4],eax
    mov [ngcedi+%2*1024+ebx*4],edi
    ; eax = pointer to beginning of tile area
    mov dword[mode0add],0
    mov byte[tleftn],33
.loopdn
    mov cx,[vrama+eax]
    test cx,2000h
    jnz near .fintiledn
    drawlinengom2 tltype2b, preparet2ba, cachesingle2bng,.loopdn,.fintiledn,ngpalcon2b,test2ba,03h,%1
.no2bitdn
    cmp dl,3
    jne near .no8bitdn
    ; eax = pointer to beginning of tile area
    shr ecx,6
    add edi,esi
    mov [ngptrdat+%2*1024+ebx*4],ecx
    mov [ngptrdat2],ecx
    mov [ngceax+%2*1024+ebx*4],eax
    mov [ngcedi+%2*1024+ebx*4],edi
    ; eax = pointer to beginning of tile area
    mov byte[tleftn],33
.loopdn2
    mov cx,[vrama+eax]
    test cx,2000h
    jnz near .fintiledn2
    drawlinengom2 tltype8b, preparet8ba, cachesingle8bng,.loopdn2,.fintiledn2,ngpalcon8b,test8ba,0FFh,%1
.no8bitdn
    pop ebx
    ret
%endmacro

%macro mosender 1
.nodraw
    add edi,%1
    add esi,%1
    dec ecx
    jnz .next
    pop esi
    mov dword[ignor512],0
    ret
%endmacro

%macro drawbglinengpr1 2
    mov dword[ng16bprval],2000h
    mov dword[ng16bbgval],%1
    push ebx
    mov byte[curmosaicsz],1
    xor eax,eax
    test byte[mosenng+ebx],1 << %1
    jz %%nomosaic
    mov al,[mosszng+ebx]
    or al,al
    jz %%nomosaic
    inc al
    mov byte[curmosaicsz],al
    mov cl,al
    mov al,bl
    div cl
    mul cl
    mov ebx,eax
    mov [pesimpng],esi
    mov edi,xtravbuf+16
    mov ecx,64
    xor eax,eax
    mov esi,xtravbuf+16
    rep stosd
    or ebx,ebx
    jnz %%nomosaic
    inc ebx
    jmp %%yesmosaic
%%nomosaic
    cmp byte[BGMA+ebx],5
    jae near .tiles16x8
%%yesmosaic
    cmp byte[t16x161+ebx+%1*256],1
    je near .tiles16x16
    cmp byte[osm2dis],1
    je .nooffsetm
    cmp byte[BGMA+ebx],2
    je near .offsetm
;    cmp byte[BGMA+ebx],4
;    je near .offsetm
.nooffsetm
    mov eax,[BG1SYl+ebx*2+%1*512]
    and eax,0FFFFh
    add eax,ebx
    test byte[intrlng+ebx],01h
    jz %%nointerl
    add eax,ebx
    add eax,[cfieldad]
%%nointerl
    lea eax,[eax*8]
    and eax,38h
    mov [yposng],eax
    xor eax,38h
    mov [flipyposng],eax

    mov edx,[BGMA+ebx]
    mov ecx,[bgtxad+ebx*2+%2*512]
    and edx,07h
    mov [bgtxadd],cx
    mov ecx,[ngptrdat+%2*1024+ebx*4]
    mov edx,[colormodedef+edx*4+%1]
    mov [ngptrdat2],ecx
    mov eax,[ngceax+%2*1024+ebx*4]
    mov edi,[ngcedi+%2*1024+ebx*4]
    cmp dl,2
    jne near .no4bit
    ; eax = pointer to beginning of tile area
    ProcessBuildWindow %1
    jmp drawlineng4b
.no4bit
    cmp dl,1
    jne near .no2bit
    ; eax = pointer to beginning of tile area
    mov dword[mode0add],0
    ProcessBuildWindow %1
    cmp byte[BGMA+ebx],0
    jne .nomode0
    mov ebx,[mode0ads]
    mov [mode0add],ebx
.nomode0
    jmp drawlineng2b
.no2bit
    cmp dl,3
    jne near .no8bit
    ; eax = pointer to beginning of tile area
    ProcessBuildWindow %1
    jmp drawlineng8b
.no8bit
    pop ebx
    ret

.tiles16x16
    mov ecx,[BG1SYl+ebx*2+%1*512]
    and ecx,0FFFFh
    mov dword[taddnfy16x16],0
    add ecx,ebx
    test byte[intrlng+ebx],01h
    jz %%nointerl2
    add ecx,ebx
    add ecx,[cfieldad]
%%nointerl2
    mov dword[taddfy16x16],16
    test ecx,08h
    jz .nobottomy
    mov dword[taddnfy16x16],16
    mov dword[taddfy16x16],-16
.nobottomy

    lea eax,[ecx*8]
    and eax,38h
    mov [yposng],eax
    xor eax,38h
    mov [flipyposng],eax

    mov edx,[BGMA+ebx]
    mov ecx,[bgtxad+ebx*2+%2*512]
    and edx,07h
    mov [bgtxadd],cx
    mov ecx,[ngptrdat+%2*1024+ebx*4]
    mov edx,[colormodedef+edx*4+%1]
    mov [ngptrdat2],ecx
    mov eax,[ngceax+%2*1024+ebx*4]
    mov edi,[ngcedi+%2*1024+ebx*4]
    cmp dl,2
    jne near .no4bit2
    ; eax = pointer to beginning of tile area
    ProcessBuildWindow %1
    jmp drawlineng16x164b
.no4bit2
    cmp dl,1
    jne near .no2bit2
    ; eax = pointer to beginning of tile area
    mov dword[mode0add],0
    ProcessBuildWindow %1
    cmp byte[BGMA+ebx],0
    jne .nomode02
    mov ebx,[mode0ads]
    mov [mode0add],ebx
.nomode02
    jmp drawlineng16x162b
.no2bit2
    cmp dl,3
    jne near .no8bit2
    ; eax = pointer to beginning of tile area
    ProcessBuildWindow %1
    jmp drawlineng16x168b
.no8bit2
    pop ebx
    ret

.tiles16x8
    mov ecx,[BG1SYl+ebx*2+%1*512]
    and ecx,0FFFFh
    add ecx,ebx
    test byte[intrlng+ebx],01h
    jz %%nointerl3
    add ecx,ebx
    add ecx,[cfieldad]
%%nointerl3
    mov dword[taddnfy16x16],0
    mov dword[taddfy16x16],16
    test ecx,08h
    jz .nobottomyb
    mov dword[taddnfy16x16],16
    mov dword[taddfy16x16],-16
.nobottomyb
    cmp byte[t16x161+ebx+%1*256],1
    je near .tiles16x16hr
    mov dword[taddnfy16x16],0
    mov dword[taddfy16x16],0
.tiles16x16hr

    lea eax,[ecx*8]
    and eax,38h
    mov [yposng],eax
    xor eax,38h
    mov [flipyposng],eax

    mov edx,[BGMA+ebx]
    mov ecx,[bgtxad+ebx*2+%2*512]
    and edx,07h
    mov [bgtxadd],cx
    mov ecx,[ngptrdat+%2*1024+ebx*4]
    mov edx,[colormodedef+edx*4+%1]
    mov [ngptrdat2],ecx
    mov eax,[ngceax+%2*1024+ebx*4]
    mov edi,[ngcedi+%2*1024+ebx*4]
    cmp dl,2
    jne near .no4bit2b
    ; eax = pointer to beginning of tile area
    mov dword[cbgval],%1
    jmp drawlineng16x84b
.no4bit2b
    cmp dl,1
    jne near .no2bit2b
    ; eax = pointer to beginning of tile area
    mov dword[mode0add],0
    mov dword[cbgval],%1
    jmp drawlineng16x82b
.no2bit2b
    pop ebx
    ret

.offsetm
    xor edx,edx
    mov dx,[BG3SYl+ebx*2]
;    and dx,0F8h
    shr edx,3
    shl edx,6
    xor eax,eax
    mov ax,[BGPT3+ebx*2]
    add ax,dx
    xor edx,edx
    mov dx,[BG3SXl+ebx*2]
    and dx,0F8h
    mov [ofsmcyps],ebx
    shr edx,3
    shl edx,1
    add ax,dx
    mov dx,[bg3scrolx]
    test dx,8000h
    jz .nooma
    and dx,0F000h
    shr dx,5
    add ax,dx
.nooma
    mov edx,eax
;    cmp byte[BGMA+ebx],4
;    je .offsetm4
    add edx,40h
;.offsetm4
    and edx,0FFC0h
    add edx,[vram]
    mov [ofsmcptr],edx
    and eax,3Fh
    mov [ofsmcptr2],eax
    mov eax,[BGPT1Y+ebx*2+%1*512]
    mov [ofsmady],eax
    mov eax,[BGPT1X+ebx*2+%1*512]
    mov [ofsmadx],eax
    mov eax,[BGPT1+ebx*2+%1*512]
    mov [ofsmtptr],eax
    mov [ofsmtptrs],eax

    mov word[bgtxadd2],0
    cmp word[BGPT3X+ebx*2],0
    je .yesoverfl
    mov cx,word[BG3SXl+ebx*2]
    add cx,16
    test cx,100h
    jz .notoverfl
    add dword[ofsmcptr],800h
    sub word[bgtxadd2],800h
    jmp .yesoverfl
.notoverfl
    add word[bgtxadd2],800h
.yesoverfl

    mov ecx,[BG1SXl+ebx*2+%1*512]
    mov edx,[BGPT1X+ebx*2+%1*512]
    test ecx,100h
    jz .noxincdd
    add [ofsmtptr],edx
.noxincdd
    and ecx,0F8h
    shr ecx,2
    add [ofsmtptr],ecx
    mov eax,[BG1SYl+ebx*2+%1*512]
    and eax,0FFFFh
    add eax,ebx
    lea eax,[eax*8]
    and eax,38h
    mov [yposng],eax
    mov [yposngom],eax
    xor eax,38h
    mov [flipyposng],eax
    mov [flipyposngom],eax
    mov edx,[BGMA+ebx]
    mov ecx,[bgtxad+ebx*2+%2*512]
    and edx,07h
    mov [bgtxadd],cx
    mov ecx,[ngptrdat+%2*1024+ebx*4]
    mov edx,[colormodedef+edx*4+%1]
    mov [ngptrdat2],ecx
    mov eax,[ngceax+%2*1024+ebx*4]
    mov edi,[ngcedi+%2*1024+ebx*4]
    mov [ofsmmptr],eax
    mov dword[ofshvaladd],0
    cmp dl,2
    jne near .no4bitd
    ; eax = pointer to beginning of tile area
    mov dword[ofsmval],2000h << %1
    mov dword[ofsmvalh],2000h << %1
    cmp byte[hdmaearlstart],0
    je .ofsmvalhack
    mov dword[ofsmvalh],0
.ofsmvalhack
    mov dword[cbgval],%1
    ProcessBuildWindow %1
    jmp drawlinengom4b
.no4bitd
    cmp dl,1
    jne near .no2bitdn
    ; eax = pointer to beginning of tile area
    mov byte[tleftn],33
.loopdn
    mov cx,[vrama+eax]
    test cx,2000h
    jz near .fintiledn
    drawlinengom2 tltype2b, preparet2ba, cachesingle2bng,.loopdn,.fintiledn,ngpalcon2b,test2ba,03h,%1
.no2bitdn
    cmp dl,3
    jne near .no8bitdn
    ; eax = pointer to beginning of tile area
    mov byte[tleftn],33
.loopdn2
    mov cx,[vrama+eax]
    test cx,2000h
    jz near .fintiledn2
    drawlinengom2 tltype8b, preparet8ba, cachesingle8bng,.loopdn2,.fintiledn2,ngpalcon8b,test8ba,0FFh,%1
.no8bitdn
    pop ebx
    ret
%endmacro
