⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 windows.asm

📁 NES game Emulator in Linux.c and asm codes.
💻 ASM
📖 第 1 页 / 共 2 页
字号:
.and_draw_outside_2:

.intersect_or_entry:
 mov cl,[Win_Count+edx]
 test cl,cl
 jz .or_copy_win2

 mov ch,[Win_Count+esi]
 test ch,ch
 jz .or_copy_win1

.or_win1_loop:
 ; start with leftmost window bands
 mov al,[edx+Win_Bands]
 mov bl,[esi+Win_Bands]
 cmp al,bl
 jbe .or_no_swap
 rol cx,8
 mov ebx,edx
 mov edx,esi
 mov esi,ebx
.or_no_swap:

 mov ax,[edx+Win_Bands]

.or_win2_loop:
 mov bx,[esi+Win_Bands]

 ; compare window 2 left edge against window 1 right edge
 test ah,ah
 jz .or_win1right_edge

 cmp bl,ah      ;win2left, win1right
 ja .or_no_intersect

.or_win1right_edge:

 dec ah
 dec bh
 cmp ah,bh
 ja .or_max_right
 mov ah,bh
.or_max_right:
 inc ah

 add esi,byte 2
 dec ch
 jnz .or_win2_loop

.or_no_intersect:
 dec cl
 jz .or_last_band

 mov bx,[edx+Win_Bands+2]
 add edx,byte 2

 ; compare next band left edge against accumulated band right edge
 test ah,ah
 jz .or_win1right_edge2

 cmp bl,ah      ;win2left, win1right
 ja .or_no_intersect2

.or_win1right_edge2:

 dec ah
 dec bh
 cmp ah,bh
 ja .or_max_right2
 mov ah,bh
.or_max_right2:
 inc ah

 test ch,ch
 jnz .or_win2_loop
 jmp .or_no_intersect

.or_no_intersect2:
 mov [edi+ebp*2+Win_Bands],al
 mov [edi+ebp*2+Win_Bands+1],ah
 inc ebp

 test ch,ch
 jnz .or_win1_loop
 mov ax,bx
 jmp .or_no_intersect

.or_last_band:
 mov [edi+ebp*2+Win_Bands],ax
 inc ebp

.or_copy_win2:
 mov cl,ch
 mov edx,esi
.or_copy_win1:
 test cl,cl
 jz .or_done
.or_copy_another:
 mov ax,[edx+Win_Bands]
 add edx,byte 2
 mov [edi+ebp*2+Win_Bands],ax
 inc ebp
 dec cl
 jnz .or_copy_another
.or_done:
 mov eax,ebp
 mov [edi+Win_Count],al
 ret


;if we're doing xor, we flip the inversion of one of the windows
.intersect_xor_check:
 ;fixup for xor/xnor
 and ah,1
 xor al,ah

.intersect_xor_setup:
 add edi,esi

 LOAD_WIN_TABLE 1
 LOAD_WIN_TABLE 2,esi

 ; we want drawn areas, not window areas, so we need the inverted results...
 test al,1
 jnz .xor_draw_outside_1
 add edx,byte Win_In - Win_Out
.xor_draw_outside_1:

 test al,4
 jz .xor_draw_outside_2
 add esi,byte Win_In - Win_Out
.xor_draw_outside_2:

.intersect_xor_entry:
EXTERN_C xor_bands
 mov cl,[Win_Count+edx]
 mov ch,[Win_Count+esi]

%if Win_Bands
 add edx,Win_Bands
 add esi,Win_Bands
%endif

 push edi
 xor eax,eax
 add edi,byte Win_Bands
 mov al,ch
 and ecx,byte 0x7F
 push edi
 push eax
 push ecx
 push esi
 push edx
 call C_LABEL(xor_bands)
 mov edi,[esp+20]
 add esp,byte 24
 mov [edi+Win_Count],al
 ret

EXPORT_EQU_C Intersect_Window_Area_AND,C_LABEL(Recalc_Window_Area_BG).intersect_and_entry
EXPORT_EQU_C Intersect_Window_Area_OR,C_LABEL(Recalc_Window_Area_BG).intersect_or_entry
EXPORT_EQU_C Intersect_Window_Area_XOR,C_LABEL(Recalc_Window_Area_BG).intersect_xor_entry

ALIGNC
EXPORT_C Recalc_Window_Effects
 push eax
 push ecx
 push edx
 push ebx
 push ebp
 push esi
 push edi

 test byte [Redo_Windowing],Redo_Win(1)
 jz .win1_ok

 Recalc_Single_Window C_LABEL(WH0), C_LABEL(WH1), 1

.win1_ok:
 test byte [Redo_Windowing],Redo_Win(2)
 jz .win2_ok

 Recalc_Single_Window C_LABEL(WH2), C_LABEL(WH3), 2

.win2_ok:


 mov al,[Redo_Windowing]
 and al,[Layers_In_Use]

 push eax
 test al,Redo_Win_BG(1)
 jz .bg1_ok

 Recalc_Window_BG_Main 1
 Recalc_Window_BG_Sub 1
.bg1_ok:


 mov al,[esp]
 test al,Redo_Win_BG(2)
 jz .bg2_ok

 Recalc_Window_BG_Main 2
 Recalc_Window_BG_Sub 2
.bg2_ok:


 mov al,[esp]
 test al,Redo_Win_BG(3)
 jz .bg3_ok

 Recalc_Window_BG_Main 3
 Recalc_Window_BG_Sub 3
.bg3_ok:


 mov al,[esp]
 test al,Redo_Win_BG(4)
 jz .bg4_ok

 Recalc_Window_BG_Main 4
 Recalc_Window_BG_Sub 4
.bg4_ok:


 mov al,[Layers_In_Use]
 xor al,0xFF
 and al,[Redo_Windowing]
 and al,~(Redo_Win(1) | Redo_Win(2))
 mov [Redo_Windowing],al

 pop eax

 pop edi
 pop esi
 pop ebp
 pop ebx
 pop edx
 pop ecx
 pop eax
 ret

; max output bands is 1 more than max input bands; only in case where
;neither outermost band edges are at screen edge
EXPORT_C Invert_Window_Bands
;esi = base address for input bands; first byte is count
;edi = base address for output bands; first byte is count
;edx = count of bands output (count up)
;ecx = count of bands input (count down)

 xor ecx,ecx
 xor edx,edx ;current output
 mov cl,[esi]
 test ecx,ecx
 jnz .no_bands

 xor eax,eax
 mov ah,[esi+1]
 test ah,ah
 jz .no_left_edge_band
 mov [edi+1],eax        ;00 xx
 inc edx

.no_left_edge_band:
 dec ecx
 jz .last_band

.next_band:
 mov ax,[esi+2]
 mov [edi+edx*2+1],ax
 add esi,2
 inc edx
 dec ecx
 jnz .next_band

.last_band:
 mov cl,[esi+2]
 test cl,cl
 jz .no_more_bands
 mov [edi+edx*2+1],cx   ;xx 00
 inc edx
.no_more_bands:
 mov [edi],dl
 ret

.no_bands:
 mov dword [edi],1      ;01 00 00 - 1 band, full area
 ret

; windows:
%if 0
 There are 5 basic window types for purposes of calculating
  intersections:

  1) full area (no invert: left = 0, right = 255; invert: left > right);
  2) no area (no invert: left > right; invert: left = 0, right = 255);
  3) flush to left side (no invert: left = 0, right < 255;
   invert: left > 0, right = 255);
  4) flush to right side (no invert: left > 0, right = 255;
   invert: left = 0, right < 255);
  5) flush to neither side (no invert: left > 0, right < 255);
  6) two runs, flush to either side (invert: left > 0, right < 255).

 Intersections can produce the following in addition:
  7) two runs: one flush to left side, one flush to neither side;
  8) two runs: one flush to right side, one flush to neither side;
  9) two runs, flush to neither side;
  10) three runs: two flush to either side, one in center.

 Types 1 and 2 are the easiest to intersect.
  1) result of OR is full area;
   result of AND is other window;
   result of XOR is other window inverted;
   result of XNOR is other window.
  2) result of OR is other window;
   result of AND is no area;
   result of XOR is other window;
   result of XNOR is other window inverted.

TMW/TSW clipping is only done inside window areas defined by
 WH0-WH1 (window 1) and WH2-WH3 (window 2), when enabled
 (W12SEL/W34SEL/WOBJSEL odd bits).

Window areas can be inverted (W12SEL/W34SEL/WOBJSEL even bits).

When specified areas of windows 1/2 overlap, final window area is determined
 by specified logic (WBGLOG/WOBJLOG).

Color arithmetic is done inside the area of the color window.

w2  w1
 /\/\  /--+ enable
 ||||  |/-+ invert window area
 76543210
 \  /\  /
 BG2 BG1 - ($2123) W12SEL
 BG4 BG3 - ($2124) W34SEL
 COL OBJ - ($2125) WOBJSEL

 COL = Color window - related to CGWSEL ($2130)

WH0-WH1 Left and right position for window 1
WH2-WH3 Left and right position for window 2
 if (left > right) no window range

       /+-+ logic - 00 = or; 01 = and; 10 = xor; 11 = xnor
       ||
 76543210
 \/||||\/
BG4||||BG1 ($212A: WBGLOG)
   \/\/OBJ ($212B: WOBJLOG)
 BG3  BG2 ($212A: WBGLOG)
      COL ($212B: WOBJLOG)
 bits 4-7 are ignored in $212B: WOBJLOG

 bits 5-7 are ignored in $212C-212F (TM, TS, TMW, TSW)
 76543210
 xxx||||\-+ BG1
    |||\--+ BG2
    ||\---+ BG3
    |\----+ BG4
    \-----+ OBJ
 ($212C) TM specifies layers to be used as main screen
 ($212D) TS specifics layers to be used as sub screen, for screen arithmetic
 ($212E) TMW is mask to be inverted and applied with bitwise AND to TM
  inside window areas
 ($212F) TSW is mask to be inverted and applied with bitwise AND to TS
  inside window areas

 $2130 - CGWSEL
 76543210
 ||||xx|\-+ 1 = enable direct color mode (for BGMODEs 3,4,7)
 ||||  \--+ 0 = arithmetic with fixed color; 1 = arithmetic with screen
 ||\+-----+ sub screen normal display select \ 00 = on; 01 = on inside
 \+-------+ main screen normal display select/ 10 = on outside; 11 = off

 $2131 - CGADSUB

 76543210
 |||||||\-+ enable color arithmetic for BG1
 ||||||\--+ enable color arithmetic for BG2
 |||||\---+ enable color arithmetic for BG3
 ||||\----+ enable color arithmetic for BG4
 |||\-----+ enable color arithmetic for OBJ
 ||\------+ enable color arithmetic for back area
 |\-------+ 1 = halve-result of arithmetic (except for back area)
 \--------+ 0 = color addition; 1 = color subtraction
%endif


section .text
ALIGNC
section .data
ALIGND
section .bss
ALIGNB

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -