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

📄 cpuaddr.inc

📁 NES game Emulator in Linux.c and asm codes.
💻 INC
📖 第 1 页 / 共 2 页
字号:
%if 0

SNEeSe, an Open Source Super NES emulator.


Copyright (c) 1998-2004 Charles Bilyue'.
Portions Copyright (c) 2003-2004 Daniel Horchner.

This is free software.  See 'LICENSE' for details.
You must read and accept the license prior to use.

%endif

; SNEeSe 65c816 CPU emulation core
; Originally written by Savoury SnaX (Not quite sure if I like AT&T)
; Maintained/rewritten by Charles Bilyue'
;
; Compile under NASM
;
; This file contains:
;  65c816 addressing mode macros
;
; Note: As of 0.372 (11-99), be very careful when modifying this code,
; and the CPU loops! The CPU loops set eax/ebx to 0, except al/bl, and
; esi to the address of the data at PB:PC (opcode + operands),
; and the new address mode emulation expects this!
;
; Final address in ebx, or eax when address is to be stored in PC!

; Helper macro for read-modify-write operations.

;insn, addr
%macro RMW 2
 RMW_ %+ %2 %1
%endmacro


;helper macro for nonzero DL fixup/quirks
%macro Check_DL_Not_Zero 0
%ifdef S_8bit
%if S_8bit
 test dl,dl
 jz %%fixup
 add R_Cycles,_5A22_FAST_CYCLE
 jmp %%no_fixup
%%fixup:
 mov bh,dh 
%%no_fixup:
%else
 add dl,255
 sbb edx,edx
 and edx,_5A22_FAST_CYCLE
 add R_Cycles,edx
%endif
%endif
%endmacro


; Implied
%macro ADDR_Implied 0
 inc R_PC
 add R_Cycles,_5A22_FAST_CYCLE
%endmacro


; shift, rotate, increment, and decrement of registers
;  RMW 8-bit and 16-bit
; M  ASL-0A  INC-1A  ROL-2A  DEC-3A  LSR-4A  ROR-6A
;  X DEY-88  INY-C8  DEX-CA  INX-E8
%macro RMW_Accumulator 1
 ADDR_Implied
%if M_8bit
 mov al,B_A
%else
 mov eax,B_A
%endif
 add R_Cycles,_5A22_FAST_CYCLE
 %1
%if M_8bit
 mov B_A,al
%else
 mov B_A,ax
%endif
%endmacro

%macro RMW_Index_X 1
 ADDR_Implied
%if X_8bit
 mov al,B_X
%else
 mov eax,B_X
%endif
 add R_Cycles,_5A22_FAST_CYCLE
 %1
%if X_8bit
 mov B_X,al
%else
 mov B_X,ax
%endif
%endmacro

%macro RMW_Index_Y 1
 ADDR_Implied
%if X_8bit
 mov al,B_Y
%else
 mov eax,B_Y
%endif
 add R_Cycles,_5A22_FAST_CYCLE
 %1
%if X_8bit
 mov B_Y,al
%else
 mov B_Y,ax
%endif
%endmacro


; Immediate (read-only)
;  Read 8-bit and 16-bit
;    ORA-09  AND-29  EOR-49  ADC-69  BIT-89  LDY-A0  LDX-A2  LDA-A9
;    CPY-C0  CMP-C9  CPX-E0  SBC-E9
;  Read 8-bit
;    REP-C2  SEP-E2
;
%macro ADDR_Immediate 0
%endmacro

%macro READ8_Immediate 0
 GET_PBPC ebx
 inc bx
 GET_BYTE
 add R_PC,byte 2
%endmacro

%macro READ16_Immediate 0-1 0
 GET_PBPC ebx
 inc bx
 GET_WORD wrap
%ifnidni %1,JSR
%ifnidni %1,JMP
 add R_PC,byte 3
%endif
%else
 add R_PC,byte 2
 add R_Cycles,_5A22_FAST_CYCLE
%endif
%endmacro

%macro READ24_Immediate 0-1 0
 GET_PBPC ebx
 inc bx
%ifnidni %1,JSR
 GET_LONG wrap
%ifnidni %1,JMP
 add R_PC,byte 4
%endif
%else
 READ16_Immediate
 push eax
 mov al,B_PB
 E0_PUSH_B
 add R_Cycles,_5A22_FAST_CYCLE
 GET_PBPC ebx
 GET_BYTE
 movzx ecx,al
 shl ecx,16
 pop eax
 add ecx,eax
 GET_PBPC eax
 E0_PUSH_W
 mov eax,ecx
 Stack_Fixup
%endif
%endmacro

; Absolute
;  Address = DB:a16
;  Read 8-bit and 16-bit
;    ORA-0D  BIT-2C  AND-2D  EOR-4D  ADC-6D  LDY-AC  LDA-AD  LDX-AE
;    CPY-CC  CMP-CD  CPX-EC  SBC-ED
;  Write 8-bit and 16-bit
;    STZ-9C  STY-8C  STA-8D  STX-8E
;  RMW 8-bit and 16-bit
;    TSB-0C  ASL-0E  TRB-1C  ROL-2E  LSR-4E  ROR-6E  DEC-CE  INC-EE
;
; if present, argument specifies post-index
%macro ADDR_Absolute 0-2 0,0
 mov eax,B_DB_Shifted   ;implied bank
 READ16_Immediate

%ifnidni %1,0           ;helper: index

%ifidni %2,0
%define %%wrapcheck X_8bit
%else
%define %%wrapcheck 0
%endif

%if %%wrapcheck         ;time always taken
 mov ebx,(1 << 24) - 1  ;clip for indexing
 add eax,%1
 and ebx,eax
 add R_Cycles,%2
%else                   ;penalty for address wrap
 mov ebx,(1 << 24) - 1  ;clip for indexing
 mov edx,eax
 add eax,%1
 sub dh,ah
 and ebx,eax
 add dh,255
 sbb edx,edx
 and edx,_5A22_FAST_CYCLE   ;address page wrap?
 add R_Cycles,edx
%endif

%else
 mov ebx,eax
%endif
%endmacro

%macro READ8_Absolute 0
 ADDR_Absolute
 GET_BYTE
%endmacro

%macro READ16_Absolute 0
 ADDR_Absolute
 GET_WORD
%endmacro

%macro WRITE8_Absolute 1
 ADDR_Absolute
 mov al,%1
 SET_BYTE
%endmacro

%macro WRITE16_Absolute 1
 ADDR_Absolute
 mov eax,%1
 SET_WORD
%endmacro

%macro RMW_Absolute 1
 READ %+ M_size %+ _Absolute
 add R_Cycles,_5A22_FAST_CYCLE
 %1
%if M_8bit
 SET_BYTE
%else
 SET_WORD_HL
%endif
%endmacro


; Absolute Long (corrupts eax)
;  Address = a24
;  Read 8-bit and 16-bit
;    ORA-0F  AND-2F  EOR-4F  ADC-6F  LDA-AF  CMP-CF  SBC-EF
;  Write 8-bit and 16-bit
;    STA-8F
;
; if present, argument specifies post-index
%macro ADDR_Absolute_Long 0-1 0
 READ24_Immediate
%ifnidni %1,0
 mov ebx,(1 << 24) - 1
 add eax,%1             ;helper: index
 and ebx,eax            ;clip for indexing
%else
 mov ebx,eax
%endif
%endmacro

%macro READ8_Absolute_Long 0
 ADDR_Absolute_Long
 GET_BYTE
%endmacro

%macro READ16_Absolute_Long 0
 ADDR_Absolute_Long
 GET_WORD
%endmacro

%macro WRITE8_Absolute_Long 1
 ADDR_Absolute_Long
 mov al,%1
 SET_BYTE
%endmacro

%macro WRITE16_Absolute_Long 1
 ADDR_Absolute_Long
 mov eax,%1
 SET_WORD
%endmacro

; Direct (corrupts eax)
;  Read 8-bit and 16-bit
;    ORA-05  BIT-24  AND-25  EOR-45  ADC-65  LDY-A4  LDA-A5  LDX-A6
;    CPY-C4  CMP-C5  CPX-E4  SBC-E5
;  Write 8-bit and 16-bit
;    STZ-64  STY-84  STA-85  STX-86
;  RMW 8-bit and 16-bit
;    TSB-04  ASL-06  TRB-14  ROL-26  LSR-46  ROR-66  DEC-C6  INC-E6
;

; if present, argument specifies index
%macro ADDR_Direct 0-1 0
 READ8_Immediate
%ifnidni %1,0
 add eax,%1             ;helper: index
%endif
 mov edx,B_D
 mov ebx,(1 << 16) - 1
 add eax,edx            ;(D + byte (+ index, if present))
 and ebx,eax            ;bank 00
 Check_DL_Not_Zero
%ifnidni %1,0
 add R_Cycles,_5A22_FAST_CYCLE
%endif
%endmacro

%macro READ8_Direct 0
 ADDR_Direct
 GET_BYTE
%endmacro

%macro READ16_Direct 0
 ADDR_Direct
%if S_8bit
 GET_WORD wrap
%else
 GET_WORD
%endif
%endmacro

%macro READ24_Direct 0
 ADDR_Direct
%if S_8bit
 GET_LONG wrap
%else
 GET_LONG
%endif
%endmacro

%macro WRITE8_Direct 1
 ADDR_Direct
 mov al,%1
 SET_BYTE
%endmacro

%macro WRITE16_Direct 1
 ADDR_Direct
 mov eax,%1
%if S_8bit
 SET_WORD wrap
%else
 SET_WORD
%endif
%endmacro

%macro RMW_Direct 1
 READ %+ M_size %+ _Direct
 add R_Cycles,_5A22_FAST_CYCLE
 %1
%if M_8bit
 SET_BYTE
%else
%if S_8bit
 SET_WORD_HL wrap
%else
 SET_WORD_HL
%endif
%endif
%endmacro


; if present, argument specifies post-index
%macro ADDR_Direct_Indirect_Base 0-2 0,0
 mov eax,B_DB_Shifted   ;implied bank
%if S_8bit
 GET_WORD wrap
%else
 GET_WORD
%endif

%ifnidni %1,0           ;helper: post-index
%ifidni %2,0
%define %%wrapcheck X_8bit
%else
%define %%wrapcheck 0
%endif

%if %%wrapcheck         ;time always taken
 mov ebx,(1 << 24) - 1  ;clip for indexing
 add eax,%1
 and ebx,eax
 add R_Cycles,%2
%else                   ;penalty for address wrap
 mov ebx,(1 << 24) - 1  ;clip for indexing
 mov edx,eax
 add eax,%1
 sub dh,ah
 and ebx,eax
 add dh,255
 sbb edx,edx
 and edx,_5A22_FAST_CYCLE   ;address page wrap?
 add R_Cycles,edx
%endif

%else
 mov ebx,eax
%endif

%undef %%wrapcheck
%endmacro

; Direct Indirect (corrupts eax)
;  Read 8-bit and 16-bit
;    ORA-12  AND-32  EOR-52  ADC-72  LDA-B2  CMP-D2  SBC-F2
;  Write 8-bit and 16-bit
;    STA-92
;  Push address (doesn't use these macros)
;    PEI-D4
;
; 2 bytes, 5-7 cycles
;
;       1   1  1   1  1 PBR,PC      Op Code     1
;       2   1  1   0  1 PBR,PC+1    DO          1
;   (if DL != 0)
;   (2) 2a  1  1   0  0 PBR,PC+1    IO          1
;       3   1  1   1  0 0,D+DO      AAL         1
;       1   1  1   1  0 0,D+DO+1    AAH         1
;       5   1  1   1  0 DBR,AA      Data Low    1/0
;   (if 16-bit data)
;   (1) 5a  1  1   1  0 DBR,AA+1    Data Low    1/0
; if present, first argument = pre-index, second = post-index
%macro ADDR_Direct_Indirect 0-3 0,0,0
 ADDR_Direct %1
 ADDR_Direct_Indirect_Base %2,%3
%endmacro

%macro READ8_Direct_Indirect 0
 ADDR_Direct_Indirect
 GET_BYTE
%endmacro

%macro READ16_Direct_Indirect 0
 ADDR_Direct_Indirect
 GET_WORD
%endmacro

%macro WRITE8_Direct_Indirect 1
 ADDR_Direct_Indirect
 mov al,%1
 SET_BYTE
%endmacro

%macro WRITE16_Direct_Indirect 1
 ADDR_Direct_Indirect
 mov eax,%1
 SET_WORD
%endmacro

; Direct Indirect Indexed (corrupts eax)
;  Read 8-bit and 16-bit
;    ORA-11  AND-31  EOR-51  ADC-71  LDA-B1  CMP-D1  SBC-F1
;  Write 8-bit and 16-bit
;    STA-91
;
; 2 bytes, 5-8 clocks

;       1   1  1   1  1 PBR,PC          Op Code     1
;       2   1  1   0  1 PBR,PC+1        DO          1
;   (if DL != 0)
;   (2) 2a  1  1   0  0 PBR,PC+1        IO          1
;       3   1  1   1  0 0,D+DO          AAL         1
;       4   1  1   1  0 0,D+DO+1        AAH         1
;   (if index across page boundary, write, or X=0)
;   (4) 4a  1  1   0  0 DBR,AAH,AAL+YL  IO          1
;       5   1  1   1  0 DBR,AA+Y        Data Low    1/0
;   (if 16-bit data)
;   (1) 5a  1  1   1  1 DBR,AA+Y+1      Data High   1/0
%macro ADDR_Direct_Indirect_Indexed 0-1 0
 ADDR_Direct_Indirect 0,B_Y,%1
%endmacro

%macro READ8_Direct_Indirect_Indexed 0
 ADDR_Direct_Indirect_Indexed
 GET_BYTE
%endmacro

%macro READ16_Direct_Indirect_Indexed 0
 ADDR_Direct_Indirect_Indexed
 GET_WORD
%endmacro

%macro WRITE8_Direct_Indirect_Indexed 1
 ADDR_Direct_Indirect_Indexed _5A22_FAST_CYCLE
 mov al,%1
 SET_BYTE
%endmacro

%macro WRITE16_Direct_Indirect_Indexed 1
 ADDR_Direct_Indirect_Indexed _5A22_FAST_CYCLE
 mov eax,%1
 SET_WORD
%endmacro

; Direct Indirect Long (corrupts eax)
;  Read 8-bit and 16-bit
;    ORA-07  AND-27  EOR-47  ADC-67  LDA-A7  CMP-C7  SBC-E7
;  Write 8-bit and 16-bit
;    STA-87
;
; 2 bytes, 6-8 cycles
;
;       1   1  1   1  1 PBR,PC      Op Code     1
;       2   1  1   0  1 PBR,PC+1    DO          1
;   (if DL != 0)
;   (2) 2a  1  1   0  0 PBR,PC+1    IO          1
;       3   1  1   1  0 0,D+DO      AAL         1
;       4   1  1   1  0 0,D+DO+1    AAH         1
;       5   1  1   1  0 0,D+DO+2    AAB         1
;       6   1  1   1  0 AAB,AA      Data Low    1/0
;   (if 16-bit data)
;   (1) 6a  1  1   1  0 AAB,AA+1    Data High   1/0
; if present, argument specifies index
%macro ADDR_Direct_Indirect_Long 0-1 0
 READ24_Direct
%ifnidni %1,0           ;helper: index
 mov ebx,(1 << 24) - 1  ;clip for indexing
 add eax,%1
 and ebx,eax
%else
 mov ebx,eax
%endif
%endmacro

%macro READ8_Direct_Indirect_Long 0
 ADDR_Direct_Indirect_Long
 GET_BYTE
%endmacro

%macro READ16_Direct_Indirect_Long 0
 ADDR_Direct_Indirect_Long
 GET_WORD
%endmacro

%macro WRITE8_Direct_Indirect_Long 1

⌨️ 快捷键说明

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