www.pudn.com > sn068s.zip > TILES.ASM
;%define WATCH_RECACHE_SETS ;%define Profile_Recache_Sets ;%define NEVER_RECACHE_TILES ;%define NO_RECACHE_2BPL %define ALT_RECACHE_4_8_BPL ;%define NO_RECACHE_4BPL ;%define NO_RECACHE_8BPL ; ; ; Tile Functions - In Assembler cos everything else is! ; Line-from-tile plotters with tile caching ; ; VRAM tile address in %esi + LineAddress(Y) + VRAMAddress... ; Cache tile address varies by depth... ; ; Tile recache ; esi = cache address (input) ; = tile address (internal) ; edi = cache address (internal) ; eax,ebx,ecx,edx,ebp destroyed ; In all the plotters... ; esi = cache address (input) ; edi = cache address (internal) ; = screen address (input) ; In check-first plotters... ; dl = palette bitmask (internal) ; (except 8-bpl) ; eax = pixels (internal) ; eax,dl destroyed ; In blank tile plotters ; Nothing ; In no-check plotters... ; ah = palette bitmask (internal) ; (except 8-bpl) ; al = pixels (internal) ; dl = pixels (internal) ; ax,dl destroyed ; %define SNEeSe_tiles_asm %include "misc.ni" %include "PPU.ni" %include "tiles.ni" %include "screen.ni" ;%include "sprites.ni" extern _SNES_Screen8 section .text EXPORT_C tiles_text_start section .data EXPORT_C tiles_data_start section .bss EXPORT_C tiles_bss_start section .data ALIGND BPL0_2: dd 0x00000000,0xFD000000,0x00FD0000,0xFDFD0000 dd 0x0000FD00,0xFD00FD00,0x00FDFD00,0xFDFDFD00 dd 0x000000FD,0xFD0000FD,0x00FD00FD,0xFDFD00FD dd 0x0000FDFD,0xFD00FDFD,0x00FDFDFD,0xFDFDFDFD BPL1_2: dd 0x00000000,0xFE000000,0x00FE0000,0xFEFE0000 dd 0x0000FE00,0xFE00FE00,0x00FEFE00,0xFEFEFE00 dd 0x000000FE,0xFE0000FE,0x00FE00FE,0xFEFE00FE dd 0x0000FEFE,0xFE00FEFE,0x00FEFEFE,0xFEFEFEFE BPL0_4: dd 0x00000000,0xF1000000,0x00F10000,0xF1F10000 dd 0x0000F100,0xF100F100,0x00F1F100,0xF1F1F100 dd 0x000000F1,0xF10000F1,0x00F100F1,0xF1F100F1 dd 0x0000F1F1,0xF100F1F1,0x00F1F1F1,0xF1F1F1F1 BPL1_4: dd 0x00000000,0xF2000000,0x00F20000,0xF2F20000 dd 0x0000F200,0xF200F200,0x00F2F200,0xF2F2F200 dd 0x000000F2,0xF20000F2,0x00F200F2,0xF2F200F2 dd 0x0000F2F2,0xF200F2F2,0x00F2F2F2,0xF2F2F2F2 BPL2_4: dd 0x00000000,0xF4000000,0x00F40000,0xF4F40000 dd 0x0000F400,0xF400F400,0x00F4F400,0xF4F4F400 dd 0x000000F4,0xF40000F4,0x00F400F4,0xF4F400F4 dd 0x0000F4F4,0xF400F4F4,0x00F4F4F4,0xF4F4F4F4 BPL3_4: dd 0x00000000,0xF8000000,0x00F80000,0xF8F80000 dd 0x0000F800,0xF800F800,0x00F8F800,0xF8F8F800 dd 0x000000F8,0xF80000F8,0x00F800F8,0xF8F800F8 dd 0x0000F8F8,0xF800F8F8,0x00F8F8F8,0xF8F8F8F8 BPL0_8: dd 0x00000000,0x01000000,0x00010000,0x01010000 dd 0x00000100,0x01000100,0x00010100,0x01010100 dd 0x00000001,0x01000001,0x00010001,0x01010001 dd 0x00000101,0x01000101,0x00010101,0x01010101 BPL1_8: dd 0x00000000,0x02000000,0x00020000,0x02020000 dd 0x00000200,0x02000200,0x00020200,0x02020200 dd 0x00000002,0x02000002,0x00020002,0x02020002 dd 0x00000202,0x02000202,0x00020202,0x02020202 BPL2_8: dd 0x00000000,0x04000000,0x00040000,0x04040000 dd 0x00000400,0x04000400,0x00040400,0x04040400 dd 0x00000004,0x04000004,0x00040004,0x04040004 dd 0x00000404,0x04000404,0x00040404,0x04040404 BPL3_8: dd 0x00000000,0x08000000,0x00080000,0x08080000 dd 0x00000800,0x08000800,0x00080800,0x08080800 dd 0x00000008,0x08000008,0x00080008,0x08080008 dd 0x00000808,0x08000808,0x00080808,0x08080808 BPL4_8: dd 0x00000000,0x10000000,0x00100000,0x10100000 dd 0x00001000,0x10001000,0x00101000,0x10101000 dd 0x00000010,0x10000010,0x00100010,0x10100010 dd 0x00001010,0x10001010,0x00101010,0x10101010 BPL5_8: dd 0x00000000,0x20000000,0x00200000,0x20200000 dd 0x00002000,0x20002000,0x00202000,0x20202000 dd 0x00000020,0x20000020,0x00200020,0x20200020 dd 0x00002020,0x20002020,0x00202020,0x20202020 BPL6_8: dd 0x00000000,0x40000000,0x00400000,0x40400000 dd 0x00004000,0x40004000,0x00404000,0x40404000 dd 0x00000040,0x40000040,0x00400040,0x40400040 dd 0x00004040,0x40004040,0x00404040,0x40404040 BPL7_8: dd 0x00000000,0x80000000,0x00800000,0x80800000 dd 0x00008000,0x80008000,0x00808000,0x80808000 dd 0x00000080,0x80000080,0x00800080,0x80800080 dd 0x00008080,0x80008080,0x00808080,0x80808080 ALIGND EXPORT Tile_Line_8_2 EXPORT Tile_Line_8_4 dd PLOT8_4BplTile dd PLOT8_4BplTile_X EXPORT Tile_Line_16_2_Even EXPORT Tile_Line_16_4_Even dd PLOT16_4BplTile_Even dd PLOT16_4BplTile_Even_X EXPORT Tile_Line_16_2 EXPORT Tile_Line_16_4 dd PLOT16_4BplTile dd PLOT16_4BplTile_X EXPORT Tile_Line_8_8 dd PLOT8_8BplTile dd PLOT8_8BplTile_X EXPORT Tile_Line_16_8 dd PLOT16_8BplTile dd PLOT16_8BplTile_X section .bss ALIGNB EXPORT_C TileCache2,skipk 256 EXPORT_C TileCache4,skipk 128 EXPORT_C TileCache8,skipk 64 EXPORT_C TileTag2,skipk 32 EXPORT_C TileTag4,skipk 16 EXPORT_C TileTag8,skipk 8 EXPORT TilesetAddress,skipl EXPORT ColourBase,skipb EXPORT PixMask,skipb section .text ; In tile decoder (to be rewritten): ; eax/ebp = pixels ; ebx/ecx = bitplane LUT addressing ; dl = line bitplanes OR'd together (clear bits = non-plotted pixels) ; dh = line counter ; esi = VRAM bitplane source address ; edi = index for tile tag (*1) and tile cache (*8) ALIGNC EXPORT Recache_Tile_Set %ifdef NEVER_RECACHE_TILES ret %endif push eax push ebx push ecx push edx push ebp push esi %ifdef Profile_Recache_Sets extern _Tiles_Recached, _Sets_Recached add [_Tiles_Recached],edi inc dword [_Sets_Recached] %endif %ifdef WATCH_RECACHE_SETS extern _BreaksLast inc dword [_BreaksLast] %endif %ifndef ALT_RECACHE_4_8_BPL xor ebx,ebx xor ecx,ecx ;shr edi,2 %endif %ifndef NO_RECACHE_2BPL push edi mov edi,[Tile_Recache_Set_Begin] %ifdef ALT_RECACHE_4_8_BPL %define NO_RECACHE_4BPL %define NO_RECACHE_8BPL shl edi,5 ; index for tile tag (*1) and tile cache (*8) %else ;shl edi,3 ; index for tile tag (*1) and tile cache (*8) shl edi,5 ; index for tile tag (*1) and tile cache (*8) %endif lea esi,[_VRAM+edi*2] ; address in VRAM of first 2bpl tile to recache .2bpl_tile_loop: %ifdef ALT_RECACHE_4_8_BPL xor ebx,ebx xor ecx,ecx mov dh,32 %else ;mov dh,8 mov dh,32 %endif mov bl,[esi] mov cl,[esi+16] mov bl,[esi+16*2] mov cl,[esi+16*3] mov bl,[_TileCache2+edi*8] mov cl,[_TileCache2+edi*8+16] mov bl,[_TileCache2+edi*8+16*2] mov cl,[_TileCache2+edi*8+16*3] mov bl,[_TileCache2+edi*8+16*4] mov cl,[_TileCache2+edi*8+16*5] mov bl,[_TileCache2+edi*8+16*6] mov cl,[_TileCache2+edi*8+16*7] mov bl,[_TileCache2+edi*8+16*8] mov cl,[_TileCache2+edi*8+16*9] mov bl,[_TileCache2+edi*8+16*10] mov cl,[_TileCache2+edi*8+16*11] mov bl,[_TileCache2+edi*8+16*12] mov cl,[_TileCache2+edi*8+16*13] mov bl,[_TileCache2+edi*8+16*14] mov cl,[_TileCache2+edi*8+16*15] .2bpl_line_loop: ; Bp0=*(LineAddress+0) mov dl,[esi] mov bl,0x0F mov cl,0xF0 and cl,dl and bl,dl shr cl,2 mov ebp,[BPL0_2+ebx*4] mov bl,0x0F mov eax,[BPL0_2+ecx] ; Bp1=*(LineAddress+1) mov cl,[esi+1] and bl,cl ;or dl,cl ;tag and cl,0xF0 shr cl,2 ;inc dl ;tag or ebp,[BPL1_2+ebx*4] or eax,[BPL1_2+ecx] %ifdef ALT_RECACHE_4_8_BPL push ebp push eax %endif ;mov [_TileTag2+edi],dl mov [_TileCache2+edi*8],eax add esi,byte 2 mov [_TileCache2+edi*8+4],ebp inc edi dec dh jnz .2bpl_line_loop %ifdef ALT_RECACHE_4_8_BPL mov dh,8 mov bl,[_TileCache4+edi*4-16*8] mov cl,[_TileCache4+edi*4-16*7] mov bl,[_TileCache4+edi*4-16*6] mov cl,[_TileCache4+edi*4-16*5] mov bl,[_TileCache4+edi*4-16*4] mov cl,[_TileCache4+edi*4-16*3] mov bl,[_TileCache4+edi*4-16*2] mov cl,[_TileCache4+edi*4-16] .4bpl_line_loop: ;2bpl 0/1/2/3:7, 4bpl 0/1:7, 8bpl 0:7 ;combine lines from 2-bpl tiles 2 & 3 mov ebp,[esp+64] mov ecx,[esp+64+4] pop eax pop ebx ; shift high tile up and remove bits for combine shl eax,2 and ebp,~0x0C0C0C0C shl ebx,2 and ecx,~0x0C0C0C0C and eax,~0x03030303 and ebx,~0x03030303 ; combine lines or eax,ebp or ebx,ecx ; save for later mov [esp+64-8],eax mov [esp+64-8+4],ebx ; and store in 4-bpl tile 1 line mov [_TileCache4-8+edi*4],eax mov [_TileCache4-4+edi*4],ebx ;combine lines from 2-bpl tiles 0 & 1 mov eax,[esp+64*2-8] mov ebx,[esp+64*2-8+4] mov ebp,[esp+64*2-8+64] mov ecx,[esp+64*2-8+64+4] ; shift high tile up and remove bits for combine shl eax,2 and ebp,~0x0C0C0C0C shl ebx,2 and ecx,~0x0C0C0C0C and eax,~0x03030303 and ebx,~0x03030303 ; combine lines or eax,ebp or ebx,ecx ; save for later mov [esp+64*2+64-8],eax mov [esp+64*2+64-8+4],ebx ; and store in 4-bpl tile 0 line mov [_TileCache4-64-8+edi*4],eax mov [_TileCache4-64-4+edi*4],ebx sub edi,byte 2 dec dh jnz near .4bpl_line_loop mov bl,[_TileCache8+edi*2+16*2-16*4] mov cl,[_TileCache8+edi*2+16*2-16*3] mov bl,[_TileCache8+edi*2+16*2-16*2] mov cl,[_TileCache8+edi*2+16*2-16] mov dh,8 .8bpl_line_loop: ;combine lines from 4-bpl tiles 0 & 1 mov ebp,[esp+64*2] mov ecx,[esp+64*2+4] pop eax pop ebx ; shift high tile up and remove bits for combine shl eax,4 and ebp,~0xF0F0F0F0 shl ebx,4 and ecx,~0xF0F0F0F0 and eax,~0x0F0F0F0F and ebx,~0x0F0F0F0F ; combine lines or eax,ebp or ebx,ecx ; store new line 8-bpl line mov [_TileCache8-8+16*2+edi*2],eax mov [_TileCache8-4+16*2+edi*2],ebx sub edi,byte 4 dec dh jnz .8bpl_line_loop add edi,byte 32+16 sub esp,byte -128 %endif dec dword [esp] %ifdef ALT_RECACHE_4_8_BPL jnz near .2bpl_tile_loop %else jnz near .2bpl_tile_loop %endif pop eax %endif %ifndef NO_RECACHE_4BPL mov edi,[Tile_Recache_Set_Begin] mov edx,[Tile_Recache_Set_End] ;shr edi,byte 1 ; edi = Tile_Recache_Set_Begin / 2 ;shr edx,byte 1 inc edx ; edx = (Tile_Recache_Set_End / 2) + 1 sub edx,edi ; Count of 4bpl tiles to recache shl edi,4 ; edi = Tile_Recache_Set_Begin / 2 add edx,edx ;shl edi,3 ; index for tile tag (*1) and tile cache (*8) push edx lea esi,[_VRAM+edi*4] ; address in VRAM of first 4bpl tile to recache .4bpl_tile_loop: mov dh,8 .4bpl_line_loop: mov cl,[_TileCache4+edi*8] ; Bp0=*(LineAddress+0) mov dl,[esi] mov bl,0x0F mov cl,0xF0 and cl,dl and bl,dl shr cl,2 mov ebp,[BPL0_4+ebx*4] mov bl,0x0F mov eax,[BPL0_4+ecx] ; Bp1=*(LineAddress+1) mov cl,[esi+1] and bl,cl ;or dl,cl and cl,0xF0 shr cl,2 or ebp,[BPL1_4+ebx*4] mov bl,0x0F or eax,[BPL1_4+ecx] ; Bp2=*(LineAddress+16) mov cl,[esi+16] and bl,cl ;or dl,cl and cl,0xF0 shr cl,2 or ebp,[BPL2_4+ebx*4] mov bl,0x0F or eax,[BPL2_4+ecx] ; Bp3=*(LineAddress+17) mov cl,[esi+17] and bl,cl ;or dl,cl and cl,0xF0 shr cl,2 ;inc dl or ebp,[BPL3_4+ebx*4] or eax,[BPL3_4+ecx] ;mov [_TileTag4+edi],dl mov [_TileCache4+edi*8],eax add esi,byte 2 mov [_TileCache4+edi*8+4],ebp inc edi dec dh jnz near .4bpl_line_loop add esi,byte 16 dec dword [esp] jnz near .4bpl_tile_loop pop eax %endif %ifndef NO_RECACHE_8BPL mov edi,[Tile_Recache_Set_Begin] mov edx,[Tile_Recache_Set_End] ;shr edi,byte 2 ; edi = Tile_Recache_Set_Begin / 4 ;shr edx,byte 2 inc edx ; edx = (Tile_Recache_Set_End / 4) + 1 sub edx,edi ; Count of 8bpl tiles to recache shl edi,3 ; index for tile tag (*1) and tile cache (*8) push edx lea esi,[_VRAM+edi*8] ; address in VRAM of first 8bpl tile to recache .8bpl_tile_loop: mov dh,8 .8bpl_line_loop: mov cl,[_TileCache8+edi*8] ; Bp0=*(LineAddress+0) mov dl,[esi] mov bl,0x0F mov cl,0xF0 and cl,dl and bl,dl shr cl,2 mov ebp,[BPL0_8+ebx*4] mov bl,0x0F mov eax,[BPL0_8+ecx] ; Bp1=*(LineAddress+1) mov cl,[esi+1] and bl,cl ;or dl,cl and cl,0xF0 shr cl,2 or ebp,[BPL1_8+ebx*4] mov bl,0x0F or eax,[BPL1_8+ecx] ; Bp2=*(LineAddress+16) mov cl,[esi+16] and bl,cl ;or dl,cl and cl,0xF0 shr cl,2 or ebp,[BPL2_8+ebx*4] mov bl,0x0F or eax,[BPL2_8+ecx] ; Bp3=*(LineAddress+17) mov cl,[esi+17] and bl,cl ;or dl,cl and cl,0xF0 shr cl,2 or ebp,[BPL3_8+ebx*4] mov bl,0x0F or eax,[BPL3_8+ecx] ; Bp4=*(LineAddress+32) mov cl,[esi+32] and bl,cl ;or dl,cl and cl,0xF0 shr cl,2 or ebp,[BPL4_8+ebx*4] mov bl,0x0F or eax,[BPL4_8+ecx] ; Bp5=*(LineAddress+33) mov cl,[esi+33] and bl,cl ;or dl,cl and cl,0xF0 shr cl,2 or ebp,[BPL5_8+ebx*4] mov bl,0x0F or eax,[BPL5_8+ecx] ; Bp6=*(LineAddress+48) mov cl,[esi+48] and bl,cl ;or dl,cl and cl,0xF0 shr cl,2 or ebp,[BPL6_8+ebx*4] mov bl,0x0F or eax,[BPL6_8+ecx] ; Bp7=*(LineAddress+49) mov cl,[esi+49] and bl,cl ;or dl,cl and cl,0xF0 shr cl,2 ;inc dl or ebp,[BPL7_8+ebx*4] or eax,[BPL7_8+ecx] ;mov [_TileTag8+edi],dl mov [_TileCache8+edi*8],eax add esi,byte 2 mov [_TileCache8+edi*8+4],ebp inc edi dec dh jnz near .8bpl_line_loop add esi,byte 48 dec dword [esp] jnz near .8bpl_tile_loop pop eax %endif pop esi pop ebp pop edx pop ecx pop ebx pop eax ret %macro P8_Plot_8 1-2 0 ;Xflip,Add=0 and esi,0x3FF*64+8*7 add esi,[TilesetAddress] %ifnidni %1,Xflip Plot_2 0,4,0,4 Plot_2 1,5,1,5 Plot_2 2,6,2,6 Plot_2 3,7,3,7 %else Plot_2 7,3,0,4 Plot_2 6,2,1,5 Plot_2 5,1,2,6 Plot_2 4,0,3,7 %endif %endmacro %macro P16_Plot_8 1-2 0 ;Xflip,Add=0 %ifnidni %1,Xflip push esi call PLOT8_8BplTile pop esi add esi,byte 64 add edi,byte 8 call PLOT8_8BplTile sub edi,byte 8 %else push esi add esi,byte 64 call PLOT8_8BplTile_X pop esi add edi,byte 8 call PLOT8_8BplTile_X sub edi,byte 8 %endif %endmacro %macro P8_Plot_4 1-2 0 ;Xflip,Add=0 and esi,0x3FF*64+8*7 add esi,[TilesetAddress] %ifnidni %1,Xflip Plot_2_Paletted 0,4,0+%2,4+%2 Plot_2_Paletted 1,5,1+%2,5+%2 Plot_2_Paletted 2,6,2+%2,6+%2 Plot_2_Paletted 3,7,3+%2,7+%2 %else Plot_2_Paletted 7,3,0+%2,4+%2 Plot_2_Paletted 6,2,1+%2,5+%2 Plot_2_Paletted 5,1,2+%2,6+%2 Plot_2_Paletted 4,0,3+%2,7+%2 %endif %endmacro %macro P8_Plot_Half_4 1-2 0 ;Xflip,Add=0 and esi,0x3FF*64+8*7 add esi,[TilesetAddress] %ifnidni %1,Xflip Plot_2_Paletted 0,4,0,2 Plot_2_Paletted 2,6,1,3 %else Plot_2_Paletted 6,2,0,2 Plot_2_Paletted 4,0,1,3 %endif %endmacro %macro P16_Plot_Half_4 1-2 0 ;Xflip,Add=0 %ifnidni %1,Xflip push esi call PLOT8_4BplTile_Even pop esi add esi,byte 64 add edi,byte 4 call PLOT8_4BplTile_Even sub edi,byte 4 %else push esi add esi,byte 64 call PLOT8_4BplTile_Even_X pop esi add edi,byte 4 call PLOT8_4BplTile_Even_X sub edi,byte 4 %endif %endmacro %macro P16_Plot_4 1-2 0 ;Xflip,Add=0 %ifnidni %1,Xflip push esi call PLOT8_4BplTile pop esi add esi,byte 64 add edi,byte 8 call PLOT8_4BplTile sub edi,byte 8 %else push esi add esi,byte 64 call PLOT8_4BplTile_X pop esi add edi,byte 8 call PLOT8_4BplTile_X sub edi,byte 8 %endif %endmacro %macro P8_Plot_2 1-2 0 ;Xflip,Add=0 P8_Plot_4 %1,%2 %endmacro %macro P8_Plot_Half_2 1-2 0 ;Xflip,Add=0 P8_Plot_Half_4 %1,%2 %endmacro %macro P16_Plot_Half_2 1-2 0 ;Xflip,Add=0 %ifnidni %1,Xflip push esi call PLOT8_2BplTile_Even pop esi add esi,byte 64 add edi,byte 4 call PLOT8_2BplTile_Even sub edi,byte 4 %else push esi add esi,byte 64 call PLOT8_2BplTile_Even_X pop esi add edi,byte 4 call PLOT8_2BplTile_Even_X sub edi,byte 4 %endif %endmacro %macro P16_Plot_2 1-2 0 ;Xflip,Add=0 %ifnidni %1,Xflip push esi call PLOT8_2BplTile pop esi add esi,byte 64 add edi,byte 8 call PLOT8_2BplTile sub edi,byte 8 %else push esi add esi,byte 64 call PLOT8_2BplTile_X pop esi add edi,byte 8 call PLOT8_2BplTile_X sub edi,byte 8 %endif %endmacro EXPORT_C tile_plotters_text_start ALIGNC PLOT8_8BplTile: P8_Plot_8 noflip ret ALIGNC PLOT8_8BplTile_X: P8_Plot_8 Xflip ret ALIGNC PLOT8_4BplTile: P8_Plot_4 noflip ret ALIGNC PLOT8_4BplTile_X: P8_Plot_4 Xflip ret ALIGNC PLOT8_2BplTile: P8_Plot_2 noflip ret ALIGNC PLOT8_2BplTile_X: P8_Plot_2 Xflip ret PLOT8_4BplTile_Even: P8_Plot_Half_4 noflip ret PLOT8_4BplTile_Even_X: P8_Plot_Half_4 Xflip ret PLOT8_2BplTile_Even: P8_Plot_Half_2 noflip ret PLOT8_2BplTile_Even_X: P8_Plot_Half_2 Xflip ret ALIGNC PLOT16_4BplTile_Even: P16_Plot_Half_4 noflip ret ALIGNC PLOT16_4BplTile_Even_X: P16_Plot_Half_4 Xflip ret ALIGNC PLOT16_2BplTile_Even: P16_Plot_Half_2 noflip ret ALIGNC PLOT16_2BplTile_Even_X: P16_Plot_Half_2 Xflip ret ALIGNC PLOT16_8BplTile: P16_Plot_8 noflip ret ALIGNC PLOT16_8BplTile_X: P16_Plot_8 Xflip ret ALIGNC PLOT16_4BplTile: P16_Plot_4 noflip ret ALIGNC PLOT16_4BplTile_X: P16_Plot_4 Xflip ret ALIGNC PLOT16_2BplTile: P16_Plot_2 noflip ret ALIGNC PLOT16_2BplTile_X: P16_Plot_2 Xflip ret ALIGNC EXPORT Invalidate_Tile_Caches mov dword [Tile_Recache_Set_Begin],0 mov dword [Tile_Recache_Set_End],0x3FF ret section .text ALIGNC section .data ALIGND section .bss ALIGNB