경고: 이 문서의 오래된 판을 편집하고 있습니다. 이것을 게시하면, 이 판 이후로 바뀐 모든 편집이 사라집니다.경고: 로그인하지 않았습니다. 편집을 하면 IP 주소가 공개되게 됩니다. 로그인하거나 계정을 생성하면 편집자가 사용자 이름으로 기록되고, 다른 장점도 있습니다.스팸 방지 검사입니다. 이것을 입력하지 마세요! 2A03은 RP2A03의 약칭으로, [[NTSC]] 방식 [[NES]] [[CPU]] 칩의 일반적인 명칭이다. 이 칩은 MOS Technology [[6502]] 프로세서(10진 모드 없음), 오디오, 조이패드, DMA 기능으로 구성된다. PAL 방식 시스템에서는 유사한 RP2A07을 사용하는데, 이 칩은 클럭 속도가 다르고 샘플 오디오 속도가 조정되었으며 DMA 버그가 수정되었다. ===2A03 레지스터 사양=== 2A03은 6502 코어의 레지스터 외에도 [[사운드]] 생성([[NES APU]] 참조), 조이스틱 입력, [[OAM DMA]] 전송을 위한 22개의 메모리 매핑 레지스터를 포함한다. PPU 및 매퍼 레지스터의 주소와 달리, CPU 레지스터 주소는 완전히 디코딩된다. 이는 CPU 레지스터의 끝($4020)부터 주소 공간의 최상단($FFFF)까지의 전체 공간을 게임팩에서 사용할 수 있음을 의미한다. $4018-$401F 범위는 정식 발매된 NES에서 아무 기능도 하지 않는다. 이 영역은 실제 생산품에는 적용되지 않은 2A03 기능을 위해 의도되었다. 다양한 2A03 리비전에는 테스트 레지스터(정상 작동 시 비활성화됨) 또는 회로의 나머지 부분과 연결이 끊긴 채 불완전하게 구현된 IRQ 카운터의 흔적이 포함되어 있다. [[매퍼]]는 2A03과 충돌 없이 이 영역에 쓰기 가능한 레지스터를 배치할 수 있지만, [[DMA]]와의 충돌 때문에 읽기 가능한 레지스터를 배치하는 것은 피해야 한다. (이 문서의 의미는 [[MMC5]]에 설명하도록 하겠다.) {| class="wikitable" |+ 2A03 레지스터 ! 주소 ! 이름 ! 설명 (쓰기) ! 설명 (읽기) |- | $4000 | SQ1_VOL (Pulse 1) | 듀티 사이클 및 볼륨 | 오픈 버스 |- | $4001 | SQ1_SWEEP | 스위프 제어 레지스터 | |- | $4002 | SQ1_LO | 주기의 하위 바이트 | |- | $4003 | SQ1_HI | 주기의 상위 바이트 및 길이 카운터 값 | |- | $4004 | SQ2_VOL (Pulse 2) | 듀티 사이클 및 볼륨 | |- | $4005 | SQ2_SWEEP | 스위프 제어 레지스터 | |- | $4006 | SQ2_LO | 주기의 하위 바이트 | |- | $4007 | SQ2_HI | 주기의 상위 바이트 및 길이 카운터 값 | |- | $4008 | TRI_LINEAR (Triangle) | 선형 카운터 | |- | $4009 | | 사용 안 함 | |- | $400A | TRI_LO | 주기의 하위 바이트 | |- | $400B | TRI_HI | 주기의 상위 바이트 및 길이 카운터 값 | |- | $400C | NOISE_VOL (Noise) | 볼륨 | |- | $400D | | 사용 안 함 | |- | $400E | NOISE_LO | 주기 및 파형 모양 | |- | $400F | NOISE_HI | 길이 카운터 값 | |- | $4010 | DMC_FREQ (DMC) | IRQ 플래그, 루프 플래그 및 주파수 | |- | $4011 | DMC_RAW | 7비트 DAC | |- | $4012 | DMC_START | 시작 주소 = $C000 + $40 * $xx | |- | $4013 | DMC_LEN | 샘플 길이 = $10 * $xx + 1 바이트 (128 * $xx + 8 샘플) | |- | $4014 | OAMDMA | OAM DMA: $xx00-$xxFF에서 OAMDATA($2004)를 통해 OAM으로 256바이트 복사 | |- | $4015 | SND_CHN | 사운드 채널 활성화 | 사운드 채널 및 IRQ 상태 |- | $4016 | JOY1 | 조이스틱 스트로브 | 조이스틱 1 데이터 |- | $4017 | JOY2 | 프레임 카운터 제어 | 조이스틱 2 데이터 |- | $4018-$401A | | 일반적으로 비활성화된 APU 테스트 기능. (CPU 테스트 모드 참조) | |- | $401C-$401F | | 항상 비활성화된 미완성 IRQ 타이머 기능. (RP2A03 프로그래머블 인터벌 타이머 참조) | |} ===6502 명령어=== __NOTOC__ {| class="wikitable" style="text-align: center" |+ 6502 공식 명령어 |- | [[#ADC|ADC]] || [[#AND|AND]] || [[#ASL|ASL]] || [[#BCC|BCC]] || [[#BCS|BCS]] || [[#BEQ|BEQ]] || [[#BIT|BIT]] || [[#BMI|BMI]] || [[#BNE|BNE]] || [[#BPL|BPL]] || [[#BRK|BRK]] || [[#BVC|BVC]] || [[#BVS|BVS]] || [[#CLC|CLC]] |- | [[#CLD|CLD]] || [[#CLI|CLI]] || [[#CLV|CLV]] || [[#CMP|CMP]] || [[#CPX|CPX]] || [[#CPY|CPY]] || [[#DEC|DEC]] || [[#DEX|DEX]] || [[#DEY|DEY]] || [[#EOR|EOR]] || [[#INC|INC]] || [[#INX|INX]] || [[#INY|INY]] || [[#JMP|JMP]] |- | [[#JSR|JSR]] || [[#LDA|LDA]] || [[#LDX|LDX]] || [[#LDY|LDY]] || [[#LSR|LSR]] || [[#NOP|NOP]] || [[#ORA|ORA]] || [[#PHA|PHA]] || [[#PHP|PHP]] || [[#PLA|PLA]] || [[#PLP|PLP]] || [[#ROL|ROL]] || [[#ROR|ROR]] || [[#RTI|RTI]] |- | [[#RTS|RTS]] || [[#SBC|SBC]] || [[#SEC|SEC]] || [[#SED|SED]] || [[#SEI|SEI]] || [[#STA|STA]] || [[#STX|STX]] || [[#STY|STY]] || [[#TAX|TAX]] || [[#TAY|TAY]] || [[#TSX|TSX]] || [[#TXA|TXA]] || [[#TXS|TXS]] || [[#TYA|TYA]] |} == 종류별 공식 명령어 == {| class="wikitable sortable" style="text-align: center" ! 종류 !colspan=8 class="unsortable" | 명령어 |- |style="text-align: left" | 접근 (Access) |style="border-right: none;" | [[#LDA|LDA]] |style="border-left: none;" | [[#STA|STA]] |style="border-right: none;" | [[#LDX|LDX]] |style="border-left: none;" | [[#STX|STX]] |style="border-right: none;" | [[#LDY|LDY]] |style="border-left: none;" | [[#STY|STY]] |style="border-right: none;" | |style="border-left: none;" | |- |style="text-align: left" | 전송 (Transfer) |style="border-right: none;" | [[#TAX|TAX]] |style="border-left: none;" | [[#TXA|TXA]] |style="border-right: none;" | [[#TAY|TAY]] |style="border-left: none;" | [[#TYA|TYA]] |style="border-right: none;" | |style="border-left: none; border-right: none;" | |style="border-left: none; border-right: none;" | |style="border-left: none;" | |- |style="text-align: left" | 산술 (Arithmetic) |style="border-right: none;" | [[#ADC|ADC]] |style="border-left: none;" | [[#SBC|SBC]] |style="border-right: none;" | [[#INC|INC]] |style="border-left: none;" | [[#DEC|DEC]] |style="border-right: none;" | [[#INC|INX]] |style="border-left: none;" | [[#DEC|DEX]] |style="border-right: none;" | [[#INY|INY]] |style="border-left: none;" | [[#DEY|DEY]] |- |style="text-align: left" | 시프트 (Shift) |style="border-right: none;" | [[#ASL|ASL]] |style="border-left: none;" | [[#LSR|LSR]] |style="border-right: none;" | [[#ROL|ROL]] |style="border-left: none;" | [[#ROR|ROR]] |style="border-right: none;" | |style="border-left: none; border-right: none;" | |style="border-left: none; border-right: none;" | |style="border-left: none;" | |- |style="text-align: left" | 비트연산 (Bitwise) |[[#AND|AND]] |[[#ORA|ORA]] |[[#EOR|EOR]] |[[#BIT|BIT]] |style="border-right: none;" | |style="border-left: none; border-right: none;" | |style="border-left: none; border-right: none;" | |style="border-left: none;" | |- |style="text-align: left" | 비교 (Compare) |[[#CMP|CMP]] |[[#CPX|CPX]] |[[#CPY|CPY]] |style="border-right: none;" | |style="border-left: none; border-right: none;" | |style="border-left: none; border-right: none;" | |style="border-left: none; border-right: none;" | |style="border-left: none;" | |- |style="text-align: left" | 분기 (Branch) |style="border-right: none;" | [[#BCC|BCC]] |style="border-left: none;" | [[#BCS|BCS]] |style="border-right: none;" | [[#BEQ|BEQ]] |style="border-left: none;" | [[#BNE|BNE]] |style="border-right: none;" | [[#BPL|BPL]] |style="border-left: none;" | [[#BMI|BMI]] |style="border-right: none;" | [[#BVC|BVC]] |style="border-left: none;" | [[#BVS|BVS]] |- |style="text-align: left" | 점프 (Jump) |[[#JMP|JMP]] |style="border-right: none;" | [[#JSR|JSR]] |style="border-left: none;" | [[#RTS|RTS]] |style="border-right: none;" | [[#BRK|BRK]] |style="border-left: none;" | [[#RTI|RTI]] |style="border-right: none;" | |style="border-left: none; border-right: none;" | |style="border-left: none;" | |- |style="text-align: left" | 스택 (Stack) |style="border-right: none;" | [[#PHA|PHA]] |style="border-left: none;" | [[#PLA|PLA]] |style="border-right: none;" | [[#PHP|PHP]] |style="border-left: none;" | [[#PLP|PLP]] |style="border-right: none;" | [[#TXS|TXS]] |style="border-left: none;" | [[#TSX|TSX]] |style="border-right: none;" | |style="border-left: none;" | |- |style="text-align: left" | 플래그 (Flags) |style="border-right: none;" | [[#CLC|CLC]] |style="border-left: none;" | [[#SEC|SEC]] |style="border-right: none;" | [[#CLI|CLI]] |style="border-left: none;" | [[#SEI|SEI]] |style="border-right: none;" | [[#CLD|CLD]] |style="border-left: none;" | [[#SED|SED]] |[[#CLV|CLV]] | |- |style="text-align: left" | 기타 (Other) |[[#NOP|NOP]] |style="border-right: none;" | |style="border-left: none; border-right: none;" | |style="border-left: none; border-right: none;" | |style="border-left: none; border-right: none;" | |style="border-left: none; border-right: none;" | |style="border-left: none; border-right: none;" | |style="border-left: none;" | |} == 공식 명령어 == {{Anchor|ADC}} === ADC - 캐리와 함께 더하기 (Add with Carry) === <code>A = A + 메모리 + C</code> ADC는 캐리 플래그와 메모리 값을 어큐뮬레이터에 더합니다. 그 후 캐리 플래그는 비트 7에서 나오는 캐리 값으로 설정되어, 다음 바이트 덧셈으로 1을 넘겨줌으로써 1바이트보다 큰 값을 더할 수 있게 합니다. 이는 부호 없는 오버플로로 생각할 수도 있습니다. 첫 바이트를 더하기 전에 [[#CLC|CLC]]로 캐리를 클리어하여 알려진 상태로 만들어, 1만큼의 오차를 피하는 것이 일반적입니다. 오버플로 플래그는 부호 있는 오버플로나 언더플로가 발생했는지를 나타냅니다. 이는 두 입력이 모두 양수인데 결과가 음수이거나, 두 입력이 모두 음수인데 결과가 양수인 경우에 발생합니다. {| class="wikitable" ! 플래그 !! 새로운 값 !! 비고 |- | [[Status_flags#C|C - 캐리]] || 결과 > $FF || 결과가 $FF를 초과하여 오버플로(랩어라운드)되면, 부호 없는 오버플로가 발생한 것입니다. |- | [[Status_flags#Z|Z - 제로]] || 결과 == 0 || |- | [[Status_flags#V|V - 오버플로]] || (결과 ^ A) & (결과 ^ 메모리) & $80 || 결과의 부호가 A와 메모리의 부호와 모두 다르면, 부호 있는 오버플로(또는 언더플로)가 발생한 것입니다. |- | [[Status_flags#N|N - 네거티브]] || 결과의 비트 7 || |} {| class="wikitable" ! 주소 지정 모드 !! 옵코드 !! 바이트 !! 사이클 |- | [[Addressing_modes#Immediate|#Immediate]] || $69 || 2 || 2 |- | [[Addressing_modes#Zero_page_read|Zero Page]] || $65 || 2 || 3 |- | [[Addressing_modes#Zero_page_indexed_read|Zero Page,X]] || $75 || 2 || 4 |- | [[Addressing_modes#Absolute_read|Absolute]] || $6D || 3 || 4 |- | [[Addressing_modes#Absolute_indexed_read|Absolute,X]] || $7D || 3 || 4 (페이지 교차 시 5) |- | [[Addressing_modes#Absolute_indexed_read|Absolute,Y]] || $79 || 3 || 4 (페이지 교차 시 5) |- | [[Addressing_modes#Indirect_x_read|(Indirect,X)]] || $61 || 2 || 6 |- | [[Addressing_modes#Indirect_y_read|(Indirect),Y]] || $71 || 2 || 5 (페이지 교차 시 6) |} 참조: [[#SBC|SBC]], [[#CLC|CLC]] ---- {{Anchor|AND}} === AND - 비트 단위 AND (Bitwise AND) === <code>A = A & 메모리</code> 이 명령어는 메모리 값과 어큐뮬레이터를 비트 단위로 AND 연산합니다. 두 입력 비트가 모두 1이면 결과 비트는 1이 되고, 그렇지 않으면 0이 됩니다. {| class="mw-collapsible mw-collapsed wikitable" |+ style="white-space:nowrap; border:1px solid; padding:3px; border-color:rgb(162, 169, 177); background-color:rgb(234, 236, 240);" | AND 진리표 |- ! A !! 메모리 !! 결과 |- | 0 || 0 || 0 |- | 0 || 1 || 0 |- | 1 || 0 || 0 |- | 1 || 1 || 1 |} {| class="wikitable" ! 플래그 !! 새로운 값 |- | [[Status_flags#Z|Z - 제로]] || 결과 == 0 |- | [[Status_flags#N|N - 네거티브]] || 결과의 비트 7 |} {| class="wikitable" ! 주소 지정 모드 !! 옵코드 !! 바이트 !! 사이클 |- | [[Addressing_modes#Immediate|#Immediate]] || $29 || 2 || 2 |- | [[Addressing_modes#Zero_page_read|Zero Page]] || $25 || 2 || 3 |- | [[Addressing_modes#Zero_page_indexed_read|Zero Page,X]] || $35 || 2 || 4 |- | [[Addressing_modes#Absolute_read|Absolute]] || $2D || 3 || 4 |- | [[Addressing_modes#Absolute_indexed_read|Absolute,X]] || $3D || 3 || 4 (페이지 교차 시 5) |- | [[Addressing_modes#Absolute_indexed_read|Absolute,Y]] || $39 || 3 || 4 (페이지 교차 시 5) |- | [[Addressing_modes#Indirect_x_read|(Indirect,X)]] || $21 || 2 || 6 |- | [[Addressing_modes#Indirect_y_read|(Indirect),Y]] || $31 || 2 || 5 (페이지 교차 시 6) |} 참조: [[#ORA|ORA]], [[#EOR|EOR]] ---- {{Anchor|ASL}} === ASL - 산술 왼쪽 시프트 (Arithmetic Shift Left) === <code>값 = 값 << 1</code>, 또는 시각적으로: <code> C <- [76543210] <- 0</code> ASL은 메모리 값 또는 어큐뮬레이터의 모든 비트를 왼쪽으로 한 자리씩 시프트하여, 각 비트의 값을 다음 비트로 이동시킵니다. 비트 7은 캐리 플래그로 시프트되고, 0이 비트 0으로 시프트됩니다. 이는 부호 없는 값을 2로 곱하는 것과 같으며, 캐리는 오버플로를 나타냅니다. 이것은 읽기-수정-쓰기(read-modify-write) 명령어입니다. 즉, 메모리에서 작동하는 주소 지정 모드는 수정된 값을 쓰기 전에 원래 값을 먼저 메모리에 다시 씁니다. 이 추가적인 쓰기는 하드웨어 레지스터를 대상으로 할 때 중요할 수 있습니다. {| class="wikitable" ! 플래그 !! 새로운 값 |- | [[Status_flags#C|C - 캐리]] || 값의 비트 7 |- | [[Status_flags#Z|Z - 제로]] || 결과 == 0 |- | [[Status_flags#N|N - 네거티브]] || 결과의 비트 7 |} {| class="wikitable" ! 주소 지정 모드 !! 옵코드 !! 바이트 !! 사이클 |- | [[Addressing_modes#Accumulator|Accumulator]] || $0A || 1 || 2 |- | [[Addressing_modes#Zero_page_rmw|Zero Page]] || $06 || 2 || 5 |- | [[Addressing_modes#Zero_page_indexed_rmw|Zero Page,X]] || $16 || 2 || 6 |- | [[Addressing_modes#Absolute_rmw|Absolute]] || $0E || 3 || 6 |- | [[Addressing_modes#Absolute_indexed_rmw|Absolute,X]] || $1E || 3 || 7 |} 참조: [[#LSR|LSR]], [[#ROL|ROL]], [[#ROR|ROR]] ---- {{Anchor|BCC}} === BCC - 캐리가 클리어되면 분기 (Branch if Carry Clear) === <code>PC = PC + 2 + 메모리 (부호 있음)</code> 캐리 플래그가 클리어(0)이면, BCC는 상대 오프셋을 프로그램 카운터에 더하여 가까운 위치로 분기합니다. 오프셋은 부호가 있으며, 분기 명령어 '다음'의 첫 바이트를 기준으로 [-128, 127]의 범위를 가집니다. 이보다 멀리 분기하려면 [[#JMP|JMP]] 명령어를 사용하고, 캐리가 설정되었을 때 [[#BCS|BCS]]로 해당 [[#JMP|JMP]]를 건너뛰어야 합니다. 캐리 플래그는 문맥에 따라 다른 의미를 가집니다. BCC는 비교 후에 레지스터가 메모리 값보다 작을 경우 분기하는 데 사용될 수 있으므로, 때때로 BLT(Branch if Less Than)라고도 불립니다. 또한 [[#SBC|SBC]] 후에는 부호 없는 값이 언더플로되었을 경우, [[#ADC|ADC]] 후에는 오버플로되지 '않았을' 경우 분기하는 데 사용될 수 있습니다. {| class="wikitable" ! 주소 지정 모드 !! 옵코드 !! 바이트 !! 사이클 |- | [[Addressing_modes#Relative|Relative]] || $90 || 2 || 2 (분기 시 3, 페이지 교차 시 4)[[#footnote|*]] |} 참조: [[#BCS|BCS]], [[#JMP|JMP]] ---- {{Anchor|BCS}} === BCS - 캐리가 설정되면 분기 (Branch if Carry Set) === <code>PC = PC + 2 + 메모리 (부호 있음)</code> 캐리 플래그가 설정(1)되면, BCS는 분기 오프셋을 프로그램 카운터에 더하여 가까운 위치로 분기합니다. 오프셋은 부호가 있으며, 분기 명령어 '다음'의 첫 바이트를 기준으로 [-128, 127]의 범위를 가집니다. 이보다 멀리 분기하려면 [[#JMP|JMP]] 명령어를 사용하고, 캐리가 클리어되었을 때 [[#BCC|BCC]]로 해당 [[#JMP|JMP]]를 건너뛰어야 합니다. 캐리 플래그는 문맥에 따라 다른 의미를 가집니다. BCS는 비교 후에 레지스터가 메모리 값보다 크거나 같을 경우 분기하는 데 사용될 수 있으므로, 때때로 BGE(Branch if Greater Than or Equal)라고도 불립니다. 또한 [[#ADC|ADC]] 후에는 부호 없는 값이 오버플로되었을 경우, [[#SBC|SBC]] 후에는 언더플로되지 '않았을' 경우 분기하는 데 사용될 수 있습니다. {| class="wikitable" ! 주소 지정 모드 !! 옵코드 !! 바이트 !! 사이클 |- | [[Addressing_modes#Relative|Relative]] || $B0 || 2 || 2 (분기 시 3, 페이지 교차 시 4)[[#footnote|*]] |} 참조: [[#BCC|BCC]], [[#JMP|JMP]] ---- {{Anchor|BEQ}} === BEQ - 같으면 분기 (Branch if Equal) === <code>PC = PC + 2 + 메모리 (부호 있음)</code> 제로 플래그가 설정(1)되면, BEQ는 분기 오프셋을 프로그램 카운터에 더하여 가까운 위치로 분기합니다. 오프셋은 부호가 있으며, 분기 명령어 '다음'의 첫 바이트를 기준으로 [-128, 127]의 범위를 가집니다. 이보다 멀리 분기하려면 [[#JMP|JMP]] 명령어를 사용하고, 제로가 클리어되었을 때 [[#BNE|BNE]]로 해당 [[#JMP|JMP]]를 건너뛰어야 합니다. 비교 연산은 이 플래그를 사용하여 비교된 값들이 같은지 여부를 나타냅니다. A, X, 또는 Y를 변경하는 모든 명령어는 레지스터가 0이 되는지 여부에 따라 암묵적으로 제로 플래그를 설정하거나 클리어합니다. {| class="wikitable" ! 주소 지정 모드 !! 옵코드 !! 바이트 !! 사이클 |- | [[Addressing_modes#Relative|Relative]] || $F0 || 2 || 2 (분기 시 3, 페이지 교차 시 4)[[#footnote|*]] |} 참조: [[#BNE|BNE]], [[#JMP|JMP]] ---- {{Anchor|BIT}} === BIT - 비트 테스트 (Bit Test) === <code>A & 메모리</code> BIT는 플래그를 수정하지만, 메모리나 레지스터는 변경하지 않습니다. 제로 플래그는 어큐뮬레이터와 메모리 값의 AND 연산 결과에 따라 설정되며, 이는 효과적으로 비트마스크를 적용한 후 설정된 비트가 있는지 확인하는 것과 같습니다. 메모리 값의 비트 7과 6은 네거티브 및 오버플로 플래그로 직접 로드되어, 마스크를 A에 로드할 필요 없이 쉽게 확인할 수 있습니다. BIT는 CPU 플래그만 변경하기 때문에, 때때로 CPU 레지스터를 덮어쓰지 않고 하드웨어 레지스터의 읽기 부작용을 트리거하거나, 3 사이클 [[#NOP|NOP]]처럼 사이클을 낭비하는 데 사용됩니다. 고급 기술로, 피연산자에 1 또는 2바이트 명령어를 숨겨두고 직접 점프할 때만 실행되도록 하여 두 코드 경로를 인터리빙하는 데 가끔 사용됩니다. 그러나 피연산자의 명령어는 읽을 주소로 취급되므로, 하드웨어 레지스터를 읽을 경우 부작용을 일으킬 위험이 있습니다. 이 기술은 공간, 시간 또는 레지스터 사용에 대한 제약이 심할 때 유용할 수 있습니다. {| class="wikitable" ! 플래그 !! 새로운 값 |- | [[Status_flags#Z|Z - 제로]] || 결과 == 0 |- | [[Status_flags#V|V - 오버플로]] || 메모리의 비트 6 |- | [[Status_flags#N|N - 네거티브]] || 메모리의 비트 7 |} {| class="wikitable" ! 주소 지정 모드 !! 옵코드 !! 바이트 !! 사이클 |- | [[Addressing_modes#Zero_page_read|Zero page]] || $24 || 2 || 3 |- | [[Addressing_modes#Absolute_read|Absolute]] || $2C || 3 || 4 |} 참조: [[#AND|AND]] ---- {{Anchor|BMI}} === BMI - 음수이면 분기 (Branch if Minus) === <code>PC = PC + 2 + 메모리 (부호 있음)</code> 네거티브 플래그가 설정(1)되면, BMI는 분기 오프셋을 프로그램 카운터에 더하여 가까운 위치로 분기합니다. 오프셋은 부호가 있으며, 분기 명령어 '다음'의 첫 바이트를 기준으로 [-128, 127]의 범위를 가집니다. 이보다 멀리 분기하려면 [[#JMP|JMP]] 명령어를 사용하고, 네거티브가 클리어되었을 때 [[#BPL|BPL]]로 해당 [[#JMP|JMP]]를 건너뛰어야 합니다. A, X, 또는 Y를 변경하는 모든 명령어는 비트 7(부호 비트)에 따라 암묵적으로 네거티브 플래그를 설정하거나 클리어합니다. {| class="wikitable" ! 주소 지정 모드 !! 옵코드 !! 바이트 !! 사이클 |- | [[Addressing_modes#Relative|Relative]] || $30 || 2 || 2 (분기 시 3, 페이지 교차 시 4)[[#footnote|*]] |} 참조: [[#BPL|BPL]], [[#JMP|JMP]] ---- {{Anchor|BNE}} === BNE - 같지 않으면 분기 (Branch if Not Equal) === <code>PC = PC + 2 + 메모리 (부호 있음)</code> 제로 플래그가 클리어(0)이면, BNE는 분기 오프셋을 프로그램 카운터에 더하여 가까운 위치로 분기합니다. 오프셋은 부호가 있으며, 분기 명령어 '다음'의 첫 바이트를 기준으로 [-128, 127]의 범위를 가집니다. 이보다 멀리 분기하려면 [[#JMP|JMP]] 명령어를 사용하고, 네거티브가 설정되었을 때 [[#BEQ|BEQ]]로 해당 [[#JMP|JMP]]를 건너뛰어야 합니다. 비교 연산은 이 플래그를 사용하여 비교된 값들이 같은지 여부를 나타냅니다. A, X, 또는 Y를 변경하는 모든 명령어는 레지스터가 0이 되는지 여부에 따라 암묵적으로 제로 플래그를 설정하거나 클리어합니다. {| class="wikitable" ! 주소 지정 모드 !! 옵코드 !! 바이트 !! 사이클 |- | [[Addressing_modes#Relative|Relative]] || $D0 || 2 || 2 (분기 시 3, 페이지 교차 시 4)[[#footnote|*]] |} 참조: [[#BEQ|BEQ]], [[#JMP|JMP]] ---- {{Anchor|BPL}} === BPL - 양수이면 분기 (Branch if Plus) === <code>PC = PC + 2 + 메모리 (부호 있음)</code> 네거티브 플래그가 클리어(0)이면, BPL는 분기 오프셋을 프로그램 카운터에 더하여 가까운 위치로 분기합니다. 오프셋은 부호가 있으며, 분기 명령어 '다음'의 첫 바이트를 기준으로 [-128, 127]의 범위를 가집니다. 이보다 멀리 분기하려면 [[#JMP|JMP]] 명령어를 사용하고, 네거티브가 설정되었을 때 [[#BMI|BMI]]로 해당 [[#JMP|JMP]]를 건너뛰어야 합니다. A, X, 또는 Y를 변경하는 모든 명령어는 비트 7(부호 비트)에 따라 암묵적으로 네거티브 플래그를 설정하거나 클리어합니다. {| class="wikitable" ! 주소 지정 모드 !! 옵코드 !! 바이트 !! 사이클 |- | [[Addressing_modes#Relative|Relative]] || $10 || 2 || 2 (분기 시 3, 페이지 교차 시 4)[[#footnote|*]] |} 참조: [[#BMI|BMI]], [[#JMP|JMP]] ---- {{Anchor|BRK}} === BRK - 중단 (소프트웨어 IRQ) (Break) === <code>스택에 PC + 2를 [[#PHA|푸시]]</code><br /> <code>스택에 NV11DIZC 플래그를 [[#PHA|푸시]]</code><br /> <code>PC = ($FFFE)</code> BRK는 인터럽트 요청(IRQ)을 트리거합니다. IRQ는 보통 외부 하드웨어에 의해 트리거되며, BRK는 소프트웨어에서 이를 수행하는 유일한 방법입니다. 일반적인 IRQ처럼, 현재 프로그램 카운터와 프로세서 플래그를 스택에 푸시하고, 인터럽트 비활성화 플래그를 설정한 후, IRQ 핸들러로 점프합니다. 일반적인 IRQ와 달리, 스택에 푸시되는 플래그 바이트에 브레이크 플래그를 설정하고([[#PHP|PHP]]처럼), 인터럽트 비활성화 플래그가 설정되어 있어도 인터럽트를 트리거합니다. 특히, 스택에 푸시되는 반환 주소는 BRK 옵코드 다음 바이트를 건너뜁니다. 이러한 이유로, BRK는 종종 사용되지 않는 즉시 피연산자를 가진 2바이트 명령어로 간주됩니다. 불행히도, 6502 버그로 인해 BRK IRQ는 동시에 발생하는 NMI에 의해 무시될 수 있습니다. 이 경우, NMI 핸들러만 호출되고 IRQ 핸들러는 건너뜁니다. 그러나 스택에 푸시된 플래그 바이트에는 여전히 브레이크 플래그가 설정되어 있으므로, NMI 핸들러는 이 플래그를 확인하여 (느리지만) 이 상황이 발생했음을 감지할 수 있습니다. BRK는 값 $00을 사용하기 때문에, 프로그래밍 가능한 ROM의 모든 바이트는 BRK 명령어로 덮어써서 실행을 IRQ 핸들러로 보낼 수 있습니다. 이는 일회성 프로그래밍 가능 ROM을 패치하는 데 유용합니다. BRK는 또한 시스템 콜 메커니즘으로 사용될 수 있으며, 사용되지 않는 바이트는 소프트웨어에서 인수로 사용될 수 있습니다 (접근하기는 불편하지만). NES 게임의 맥락에서, BRK는 종종 크래시 핸들러로 가장 유용합니다. 사용되지 않는 프로그램 공간을 $00으로 채우고 IRQ 핸들러가 디버깅 정보를 표시하거나 다른 방식으로 크래시를 깔끔하게 처리합니다. {| class="wikitable" ! 플래그 !! 새로운 값 !! 비고 |- | [[Status_flags#I|I - 인터럽트 비활성화]] || 1 || 이전 플래그가 스택에 푸시된 후 1로 설정됩니다. 이 플래그 변경의 효과는 지연되지 '않습니다'. |- | [[Status_flags#B|B - 브레이크]] || 1로 푸시됨 || 이 플래그는 CPU의 실제 상태가 아닌, 스택에 푸시된 플래그 바이트에만 존재합니다. |} {| class="wikitable" ! 주소 지정 모드 !! 옵코드 !! 바이트 !! 사이클 !! 비고 |- | [[Addressing_modes#BRK|Implied]] || $00 || 1 || 7 || BRK는 1바이트만 사용하지만, 반환 주소는 다음 바이트를 건너뜁니다. |- | [[Addressing_modes#BRK|#Immediate]] || $00 || 2 || 7 || BRK가 다음 바이트를 건너뛰기 때문에, 종종 2바이트 명령어로 간주됩니다. |} 참조: [[#RTI|RTI]], [[#PHP|PHP]] ---- {{Anchor|BVC}} === BVC - 오버플로가 클리어되면 분기 (Branch if Overflow Clear) === <code>PC = PC + 2 + 메모리 (부호 있음)</code> 오버플로 플래그가 클리어(0)이면, BVC는 분기 오프셋을 프로그램 카운터에 더하여 가까운 위치로 분기합니다. 오프셋은 부호가 있으며, 분기 명령어 '다음'의 첫 바이트를 기준으로 [-128, 127]의 범위를 가집니다. 이보다 멀리 분기하려면 [[#JMP|JMP]] 명령어를 사용하고, 오버플로가 설정되었을 때 [[#BVS|BVS]]로 해당 [[#JMP|JMP]]를 건너뛰어야 합니다. 제로, 네거티브, 심지어 캐리와 달리, 오버플로는 매우 적은 수의 명령어에 의해서만 수정됩니다. 주로 [[#BIT|BIT]] 명령어와 함께 사용되며, 특히 하드웨어 레지스터를 폴링할 때 사용됩니다. 또한 [[#ADC|ADC]] 및 [[#SBC|SBC]]와 함께 부호 있는 오버플로에 사용되기도 합니다. 표준 6502 칩은 외부 장치가 핀을 사용하여 오버플로를 설정할 수 있게 하여 소프트웨어가 해당 이벤트를 폴링할 수 있도록 하지만, NES의 2A03에는 이 기능이 없습니다. {| class="wikitable" ! 주소 지정 모드 !! 옵코드 !! 바이트 !! 사이클 |- | [[Addressing_modes#Relative|Relative]] || $50 || 2 || 2 (분기 시 3, 페이지 교차 시 4)[[#footnote|*]] |} 참조: [[#BVS|BVS]], [[#JMP|JMP]] ---- {{Anchor|BVS}} === BVS - 오버플로가 설정되면 분기 (Branch if Overflow Set) === <code>PC = PC + 2 + 메모리 (부호 있음)</code> 오버플로 플래그가 설정(1)되면, BVS는 분기 오프셋을 프로그램 카운터에 더하여 가까운 위치로 분기합니다. 오프셋은 부호가 있으며, 분기 명령어 '다음'의 첫 바이트를 기준으로 [-128, 127]의 범위를 가집니다. 이보다 멀리 분기하려면 [[#JMP|JMP]] 명령어를 사용하고, 오버플로가 클리어되었을 때 [[#BVC|BVC]]로 해당 [[#JMP|JMP]]를 건너뛰어야 합니다. 제로, 네거티브, 심지어 캐리와 달리, 오버플로는 매우 적은 수의 명령어에 의해서만 수정됩니다. 주로 [[#BIT|BIT]] 명령어와 함께 사용되며, 특히 하드웨어 레지스터를 폴링할 때 사용됩니다. 또한 [[#ADC|ADC]] 및 [[#SBC|SBC]]와 함께 부호 있는 오버플로에 사용되기도 합니다. 표준 6502 칩은 외부 장치가 핀을 사용하여 오버플로를 설정할 수 있게 하여 소프트웨어가 해당 이벤트를 폴링할 수 있도록 하지만, NES의 2A03 CPU에는 이 기능이 없습니다. {| class="wikitable" ! 주소 지정 모드 !! 옵코드 !! 바이트 !! 사이클 |- | [[Addressing_modes#Relative|Relative]] || $70 || 2 || 2 (분기 시 3, 페이지 교차 시 4)[[#footnote|*]] |} 참조: [[#BVC|BVC]], [[#JMP|JMP]] ---- {{Anchor|CLC}} === CLC - 캐리 클리어 (Clear Carry) === <code>C = 0</code> CLC는 캐리 플래그를 클리어합니다. 특히, 이는 보통 [[#ADC|ADC]]로 값의 하위 바이트를 더하기 전에 추가적인 1이 더해지는 것을 방지하기 위해 수행됩니다. {| class="wikitable" ! 플래그 !! 새로운 값 |- | [[Status_flags#C|C - 캐리]] || 0 |} {| class="wikitable" ! 주소 지정 모드 !! 옵코드 !! 바이트 !! 사이클 |- | [[Addressing_modes#Implied|Implied]] || $18 || 1 || 2 |} 참조: [[#SEC|SEC]] ---- {{Anchor|CLD}} === CLD - 데시멀 클리어 (Clear Decimal) === <code>D = 0</code> CLD는 데시멀 플래그를 클리어합니다. 데시멀 플래그는 보통 BCD(binary-coded decimal) 모드가 활성화되는지를 제어하지만, 이 모드는 NES의 2A03 CPU에서 영구적으로 비활성화되어 있습니다. 그러나 플래그 자체는 여전히 작동하며 상태를 저장하는 데 사용될 수 있습니다. {| class="wikitable" ! 플래그 !! 새로운 값 |- | [[Status_flags#D|D - 데시멀]] || 0 |} {| class="wikitable" ! 주소 지정 모드 !! 옵코드 !! 바이트 !! 사이클 |- | [[Addressing_modes#Implied|Implied]] || $D8 || 1 || 2 |} 참조: [[#SED|SED]] ---- {{Anchor|CLI}} === CLI - 인터럽트 비활성화 클리어 (Clear Interrupt Disable) === <code>I = 0</code> CLI는 인터럽트 비활성화 플래그를 클리어하여, CPU가 하드웨어 IRQ를 처리할 수 있도록 합니다. 이 플래그 변경의 효과는 한 명령어 지연됩니다. 왜냐하면 플래그는 IRQ가 폴링된 후에 변경되어, 보류 중인 IRQ가 감지되고 서비스되기 전에 다음 명령어가 실행될 수 있도록 하기 때문입니다. 이 플래그는 NMI에는 영향을 미치지 않으며, NMI는 이름("non-maskable")에서 알 수 있듯이 CPU가 무시할 수 없습니다. {| class="wikitable" ! 플래그 !! 새로운 값 !! 비고 |- | [[Status_flags#I|I - 인터럽트 비활성화]] || 0 || 이 플래그 변경의 효과는 1 명령어 지연됩니다. |} {| class="wikitable" ! 주소 지정 모드 !! 옵코드 !! 바이트 !! 사이클 |- | [[Addressing_modes#Implied|Implied]] || $58 || 1 || 2 |} 참조: [[#SEI|SEI]] ---- {{Anchor|CLV}} === CLV - 오버플로 클리어 (Clear Overflow) === <code>V = 0</code> CLV는 오버플로 플래그를 클리어합니다. 이에 해당하는 SEV 명령어는 없습니다. 대신, 오버플로 설정은 6502 CPU에서 외부 하드웨어에 의해 제어되는 핀으로 노출되어 있으며, NES의 2A03 CPU에는 전혀 노출되어 있지 않습니다. {| class="wikitable" ! 플래그 !! 새로운 값 |- | [[Status_flags#V|V - 오버플로]] || 0 |} {| class="wikitable" ! 주소 지정 모드 !! 옵코드 !! 바이트 !! 사이클 |- | [[Addressing_modes#Implied|Implied]] || $B8 || 1 || 2 |} ---- {{Anchor|CMP}} === CMP - A 비교 (Compare A) === <code>A - 메모리</code> CMP는 A를 메모리 값과 비교하여, 플래그를 적절하게 설정하지만 어떤 레지스터도 수정하지 않습니다. 비교는 뺄셈으로 구현되며, 빌림(borrow)이 없으면 캐리를 설정하고, 결과가 0이면 제로를 설정하고, 결과가 음수이면 네거티브를 설정합니다. 그러나 캐리와 제로는 종종 부등식으로 기억하는 것이 가장 쉽습니다. 비교는 오버플로에 영향을 미치지 '않는다는' 점에 유의하십시오. {| class="wikitable" ! 플래그 !! 새로운 값 |- | [[Status_flags#C|C - 캐리]] || A >= 메모리 |- | [[Status_flags#Z|Z - 제로]] || A == 메모리 |- | [[Status_flags#N|N - 네거티브]] || 결과의 비트 7 |} {| class="wikitable" ! 주소 지정 모드 !! 옵코드 !! 바이트 !! 사이클 |- | [[Addressing_modes#Immediate|#Immediate]] || $C9 || 2 || 2 |- | [[Addressing_modes#Zero_page_read|Zero Page]] || $C5 || 2 || 3 |- | [[Addressing_modes#Zero_page_indexed_read|Zero Page,X]] || $D5 || 2 || 4 |- | [[Addressing_modes#Absolute_read|Absolute]] || $CD || 3 || 4 |- | [[Addressing_modes#Absolute_indexed_read|Absolute,X]] || $DD || 3 || 4 (페이지 교차 시 5) |- | [[Addressing_modes#Absolute_indexed_read|Absolute,Y]] || $D9 || 3 || 4 (페이지 교차 시 5) |- | [[Addressing_modes#Indirect_x_read|(Indirect,X)]] || $C1 || 2 || 6 |- | [[Addressing_modes#Indirect_y_read|(Indirect),Y]] || $D1 || 2 || 5 (페이지 교차 시 6) |} 참조: [[#CPX|CPX]], [[#CPY|CPY]] ---- {{Anchor|CPX}} === CPX - X 비교 (Compare X) === <code>X - 메모리</code> CPX는 X를 메모리 값과 비교하여, 플래그를 적절하게 설정하지만 어떤 레지스터도 수정하지 않습니다. 비교는 뺄셈으로 구현되며, 빌림(borrow)이 없으면 캐리를 설정하고, 결과가 0이면 제로를 설정하고, 결과가 음수이면 네거티브를 설정합니다. 그러나 캐리와 제로는 종종 부등식으로 기억하는 것이 가장 쉽습니다. 비교는 오버플로에 영향을 미치지 '않는다는' 점에 유의하십시오. {| class="wikitable" ! 플래그 !! 새로운 값 |- | [[Status_flags#C|C - 캐리]] || X >= 메모리 |- | [[Status_flags#Z|Z - 제로]] || X == 메모리 |- | [[Status_flags#N|N - 네거티브]] || 결과의 비트 7 |} {| class="wikitable" ! 주소 지정 모드 !! 옵코드 !! 바이트 !! 사이클 |- | [[Addressing_modes#Immediate|#Immediate]] || $E0 || 2 || 2 |- | [[Addressing_modes#Zero_page_read|Zero Page]] || $E4 || 2 || 3 |- | [[Addressing_modes#Absolute_read|Absolute]] || $EC || 3 || 4 |} 참조: [[#CMP|CMP]], [[#CPY|CPY]] ---- {{Anchor|CPY}} === CPY - Y 비교 (Compare Y) === <code>Y - 메모리</code> CPY는 Y를 메모리 값과 비교하여, 플래그를 적절하게 설정하지만 어떤 레지스터도 수정하지 않습니다. 비교는 뺄셈으로 구현되며, 빌림(borrow)이 없으면 캐리를 설정하고, 결과가 0이면 제로를 설정하고, 결과가 음수이면 네거티브를 설정합니다. 그러나 캐리와 제로는 종종 부등식으로 기억하는 것이 가장 쉽습니다. 비교는 오버플로에 영향을 미치지 '않는다는' 점에 유의하십시오. {| class="wikitable" ! 플래그 !! 새로운 값 |- | [[Status_flags#C|C - 캐리]] || Y >= 메모리 |- | [[Status_flags#Z|Z - 제로]] || Y == 메모리 |- | [[Status_flags#N|N - 네거티브]] || 결과의 비트 7 |} {| class="wikitable" ! 주소 지정 모드 !! 옵코드 !! 바이트 !! 사이클 |- | [[Addressing_modes#Immediate|#Immediate]] || $C0 || 2 || 2 |- | [[Addressing_modes#Zero_page_read|Zero Page]] || $C4 || 2 || 3 |- | [[Addressing_modes#Absolute_read|Absolute]] || $CC || 3 || 4 |} 참조: [[#CMP|CMP]], [[#CPX|CPX]] ---- {{Anchor|DEC}} === DEC - 메모리 감소 (Decrement Memory) === <code>메모리 = 메모리 - 1</code> DEC는 메모리 위치에서 1을 뺍니다. 특히, 이 명령어의 어큐뮬레이터 버전은 없으며, 대신 [[#ADC|ADC]] 또는 [[#SBC|SBC]]를 사용해야 합니다. 이것은 읽기-수정-쓰기(read-modify-write) 명령어입니다. 즉, 수정된 값을 쓰기 전에 원래 값을 먼저 메모리에 다시 씁니다. 이 추가적인 쓰기는 하드웨어 레지스터를 대상으로 할 때 중요할 수 있습니다. 감소는 캐리나 오버플로에 영향을 미치지 '않는다는' 점에 유의하십시오. {| class="wikitable" ! 플래그 !! 새로운 값 |- | [[Status_flags#Z|Z - 제로]] || 결과 == 0 |- | [[Status_flags#N|N - 네거티브]] || 결과의 비트 7 |} {| class="wikitable" ! 주소 지정 모드 !! 옵코드 !! 바이트 !! 사이클 |- | [[Addressing_modes#Zero_page_rmw|Zero Page]] || $C6 || 2 || 5 |- | [[Addressing_modes#Zero_page_indexed_rmw|Zero Page,X]] || $D6 || 2 || 6 |- | [[Addressing_modes#Absolute_rmw|Absolute]] || $CE || 3 || 6 |- | [[Addressing_modes#Absolute_indexed_rmw|Absolute,X]] || $DE || 3 || 7 |} 참조: [[#INC|INC]], [[#ADC|ADC]], [[#SBC|SBC]] ---- {{Anchor|DEX}} === DEX - X 감소 (Decrement X) === <code>X = X - 1</code> DEX는 X 레지스터에서 1을 뺍니다. 캐리나 오버플로에 영향을 미치지 '않는다는' 점에 유의하십시오. {| class="wikitable" ! 플래그 !! 새로운 값 |- | [[Status_flags#Z|Z - 제로]] || 결과 == 0 |- | [[Status_flags#N|N - 네거티브]] || 결과의 비트 7 |} {| class="wikitable" ! 주소 지정 모드 !! 옵코드 !! 바이트 !! 사이클 |- | [[Addressing_modes#Implied|Implied]] || $CA || 1 || 2 |} 참조: [[#INX|INX]] ---- {{Anchor|DEY}} === DEY - Y 감소 (Decrement Y) === <code>Y = Y - 1</code> DEY는 Y 레지스터에서 1을 뺍니다. 캐리나 오버플로에 영향을 미치지 '않는다는' 점에 유의하십시오. {| class="wikitable" ! 플래그 !! 새로운 값 |- | [[Status_flags#Z|Z - 제로]] || 결과 == 0 |- | [[Status_flags#N|N - 네거티브]] || 결과의 비트 7 |} {| class="wikitable" ! 주소 지정 모드 !! 옵코드 !! 바이트 !! 사이클 |- | [[Addressing_modes#Implied|Implied]] || $88 || 1 || 2 |} 참조: [[#INY|INY]] ---- {{Anchor|EOR}} === EOR - 비트 단위 배타적 OR (Bitwise Exclusive OR) === <code>A = A ^ 메모리</code> EOR은 메모리 값과 어큐뮬레이터를 비트 단위로 배타적 OR(exclusive-OR) 연산합니다. 입력 비트가 다르면 결과 비트는 1이 되고, 같으면 0이 됩니다. 이 연산은 XOR로도 알려져 있습니다. 6502에는 비트 단위 NOT 명령어가 없지만, 값 $FF와 함께 EOR을 사용하면 동일한 동작을 하여 다른 값의 모든 비트를 반전시킵니다. 사실, EOR은 비트마스크를 사용한 NOT으로 생각할 수 있습니다. 한 값의 모든 1 비트는 다른 값의 해당 비트를 반전시키는 효과를 가지며, 0 비트는 아무것도 하지 않습니다. {| class="mw-collapsible mw-collapsed wikitable" |+ style="white-space:nowrap; border:1px solid; padding:3px; border-color:rgb(162, 169, 177); background-color:rgb(234, 236, 240);" | EOR 진리표 |- ! A !! 메모리 !! 결과 |- | 0 || 0 || 0 |- | 0 || 1 || 1 |- | 1 || 0 || 1 |- | 1 || 1 || 0 |} {| class="wikitable" ! 플래그 !! 새로운 값 |- | [[Status_flags#Z|Z - 제로]] || 결과 == 0 |- | [[Status_flags#N|N - 네거티브]] || 결과의 비트 7 |} {| class="wikitable" ! 주소 지정 모드 !! 옵코드 !! 바이트 !! 사이클 |- | [[Addressing_modes#Immediate|#Immediate]] || $49 || 2 || 2 |- | [[Addressing_modes#Zero_page_read|Zero Page]] || $45 || 2 || 3 |- | [[Addressing_modes#Zero_page_indexed_read|Zero Page,X]] || $55 || 2 || 4 |- | [[Addressing_modes#Absolute_read|Absolute]] || $4D || 3 || 4 |- | [[Addressing_modes#Absolute_indexed_read|Absolute,X]] || $5D || 3 || 4 (페이지 교차 시 5) |- | [[Addressing_modes#Absolute_indexed_read|Absolute,Y]] || $59 || 3 || 4 (페이지 교차 시 5) |- | [[Addressing_modes#Indirect_x_read|(Indirect,X)]] || $41 || 2 || 6 |- | [[Addressing_modes#Indirect_y_read|(Indirect),Y]] || $51 || 2 || 5 (페이지 교차 시 6) |} 참조: [[#AND|AND]], [[#ORA|ORA]] ---- {{Anchor|INC}} === INC - 메모리 증가 (Increment Memory) === <code>메모리 = 메모리 + 1</code> INC는 메모리 위치에 1을 더합니다. 특히, 이 명령어의 어큐뮬레이터 버전은 없으며, 대신 [[#ADC|ADC]] 또는 [[#SBC|SBC]]를 사용해야 합니다. 이것은 읽기-수정-쓰기(read-modify-write) 명령어입니다. 즉, 수정된 값을 쓰기 전에 원래 값을 먼저 메모리에 다시 씁니다. 이 추가적인 쓰기는 하드웨어 레지스터를 대상으로 할 때 중요할 수 있습니다. 증가는 캐리나 오버플로에 영향을 미치지 '않는다는' 점에 유의하십시오. {| class="wikitable" ! 플래그 !! 새로운 값 |- | [[Status_flags#Z|Z - 제로]] || 결과 == 0 |- | [[Status_flags#N|N - 네거티브]] || 결과의 비트 7 |} {| class="wikitable" ! 주소 지정 모드 !! 옵코드 !! 바이트 !! 사이클 |- | [[Addressing_modes#Zero_page_rmw|Zero Page]] || $E6 || 2 || 5 |- | [[Addressing_modes#Zero_page_indexed_rmw|Zero Page,X]] || $F6 || 2 || 6 |- | [[Addressing_modes#Absolute_rmw|Absolute]] || $EE || 3 || 6 |- | [[Addressing_modes#Absolute_indexed_rmw|Absolute,X]] || $FE || 3 || 7 |} 참조: [[#DEC|DEC]], [[#ADC|ADC]], [[#SBC|SBC]] ---- {{Anchor|INX}} === INX - X 증가 (Increment X) === <code>X = X + 1</code> INX는 X 레지스터에 1을 더합니다. 캐리나 오버플로에 영향을 미치지 '않는다는' 점에 유의하십시오. {| class="wikitable" ! 플래그 !! 새로운 값 |- | [[Status_flags#Z|Z - 제로]] || 결과 == 0 |- | [[Status_flags#N|N - 네거티브]] || 결과의 비트 7 |} {| class="wikitable" ! 주소 지정 모드 !! 옵코드 !! 바이트 !! 사이클 |- | [[Addressing_modes#Implied|Implied]] || $E8 || 1 || 2 |} 참조: [[#DEX|DEX]] ---- {{Anchor|INY}} === INY - Y 증가 (Increment Y) === <code>Y = Y + 1</code> INY는 Y 레지스터에 1을 더합니다. 캐리나 오버플로에 영향을 미치지 '않는다는' 점에 유의하십시오. {| class="wikitable" ! 플래그 !! 새로운 값 |- | [[Status_flags#Z|Z - 제로]] || 결과 == 0 |- | [[Status_flags#N|N - 네거티브]] || 결과의 비트 7 |} {| class="wikitable" ! 주소 지정 모드 !! 옵코드 !! 바이트 !! 사이클 |- | [[Addressing_modes#Implied|Implied]] || $C8 || 1 || 2 |} 참조: [[#DEY|DEY]] ---- {{Anchor|JMP}} === JMP - 점프 (Jump) === <code>PC = 메모리</code> JMP는 프로그램 카운터를 새로운 값으로 설정하여, 코드가 새로운 위치에서 실행되도록 합니다. 해당 위치에서 반환하려면, 대신 [[#JSR|JSR]]을 사용해야 합니다. 간접 주소 지정 모드는 피연산자를 포인터로 사용하여, 지정된 주소에서 새로운 2바이트 프로그램 카운터 값을 가져옵니다. 불행히도, CPU 버그로 인해 이 2바이트 변수의 주소가 $FF로 끝나 페이지를 교차하게 되면, CPU는 두 번째 바이트를 읽을 때 페이지를 증가시키지 못해 잘못된 주소를 읽게 됩니다. 예를 들어, JMP ($03FF)는 $03FF와 $0400 대신 ''$0300''을 읽습니다. 이 변수가 페이지를 교차하지 않도록 주의해야 합니다. {| class="wikitable" ! 주소 지정 모드 !! 옵코드 !! 바이트 !! 사이클 |- | [[Addressing_modes#Absolute|Absolute]] || $4C || 3 || 3 |- | [[Addressing_modes#Indirect|(Indirect)]] || $6C || 3 || 5 |} 참조: [[#JSR|JSR]] ---- {{Anchor|JSR}} === JSR - 서브루틴으로 점프 (Jump to Subroutine) === <code>스택에 PC + 2를 [[#PHA|푸시]]</code><br /> <code>PC = 메모리</code> JSR은 현재 프로그램 카운터를 스택에 푸시한 다음, 프로그램 카운터를 새로운 값으로 설정합니다. 이를 통해 코드는 함수를 호출하고 [[#RTS|RTS]]로 JSR 다음 명령어로 돌아올 수 있습니다. 특히, 스택의 반환 주소는 다음 명령어의 시작 지점이 아니라, 그보다 1바이트 앞을 가리킵니다. 이는 [[#RTS|RTS]]가 다음 명령어를 가져오기 전에 프로그램 카운터를 증가시키기 때문입니다. 이는 인터럽트에 의해 푸시되고 [[#RTI|RTI]]에 의해 사용되는 반환 주소와 다릅니다. 인터럽트의 반환 주소는 다음 명령어를 직접 가리킵니다. {| class="wikitable" ! 주소 지정 모드 !! 옵코드 !! 바이트 !! 사이클 |- | [[Addressing_modes#Absolute|Absolute]] || $20 || 3 || 6 |} 참조: [[#RTS|RTS]], [[#JMP|JMP]], [[#RTI|RTI]] ---- {{Anchor|LDA}} === LDA - A 로드 (Load A) === <code>A = 메모리</code> LDA는 메모리 값을 어큐뮬레이터로 로드합니다. {| class="wikitable" ! 플래그 !! 새로운 값 |- | [[Status_flags#Z|Z - 제로]] || 결과 == 0 |- | [[Status_flags#N|N - 네거티브]] || 결과의 비트 7 |} {| class="wikitable" ! 주소 지정 모드 !! 옵코드 !! 바이트 !! 사이클 |- | [[Addressing_modes#Immediate|#Immediate]] || $A9 || 2 || 2 |- | [[Addressing_modes#Zero_page_read|Zero Page]] || $A5 || 2 || 3 |- | [[Addressing_modes#Zero_page_indexed_read|Zero Page,X]] || $B5 || 2 || 4 |- | [[Addressing_modes#Absolute_read|Absolute]] || $AD || 3 || 4 |- | [[Addressing_modes#Absolute_indexed_read|Absolute,X]] || $BD || 3 || 4 (페이지 교차 시 5) |- | [[Addressing_modes#Absolute_indexed_read|Absolute,Y]] || $B9 || 3 || 4 (페이지 교차 시 5) |- | [[Addressing_modes#Indirect_x_read|(Indirect,X)]] || $A1 || 2 || 6 |- | [[Addressing_modes#Indirect_y_read|(Indirect),Y]] || $B1 || 2 || 5 (페이지 교차 시 6) |} 참조: [[#STA|STA]] ---- {{Anchor|LDX}} === LDX - X 로드 (Load X) === <code>X = 메모리</code> LDX는 메모리 값을 X 레지스터로 로드합니다. {| class="wikitable" ! 플래그 !! 새로운 값 |- | [[Status_flags#Z|Z - 제로]] || 결과 == 0 |- | [[Status_flags#N|N - 네거티브]] || 결과의 비트 7 |} {| class="wikitable" ! 주소 지정 모드 !! 옵코드 !! 바이트 !! 사이클 |- | [[Addressing_modes#Immediate|#Immediate]] || $A2 || 2 || 2 |- | [[Addressing_modes#Zero_page_read|Zero Page]] || $A6 || 2 || 3 |- | [[Addressing_modes#Zero_page_indexed_read|Zero Page,Y]] || $B6 || 2 || 4 |- | [[Addressing_modes#Absolute_read|Absolute]] || $AE || 3 || 4 |- | [[Addressing_modes#Absolute_indexed_read|Absolute,Y]] || $BE || 3 || 4 (페이지 교차 시 5) |} 참조: [[#STX|STX]] ---- {{Anchor|LDY}} === LDY - Y 로드 (Load Y) === <code>Y = 메모리</code> LDY는 메모리 값을 Y 레지스터로 로드합니다. {| class="wikitable" ! 플래그 !! 새로운 값 |- | [[Status_flags#Z|Z - 제로]] || 결과 == 0 |- | [[Status_flags#N|N - 네거티브]] || 결과의 비트 7 |} {| class="wikitable" ! 주소 지정 모드 !! 옵코드 !! 바이트 !! 사이클 |- | [[Addressing_modes#Immediate|#Immediate]] || $A0 || 2 || 2 |- | [[Addressing_modes#Zero_page_read|Zero Page]] || $A4 || 2 || 3 |- | [[Addressing_modes#Zero_page_indexed_read|Zero Page,X]] || $B4 || 2 || 4 |- | [[Addressing_modes#Absolute_read|Absolute]] || $AC || 3 || 4 |- | [[Addressing_modes#Absolute_indexed_read|Absolute,X]] || $BC || 3 || 4 (페이지 교차 시 5) |} 참조: [[#STY|STY]] ---- {{Anchor|LSR}} === LSR - 논리적 오른쪽 시프트 (Logical Shift Right) === <code>값 = 값 >> 1</code>, 또는 시각적으로: <code> 0 -> [76543210] -> C</code> LSR은 메모리 값 또는 어큐뮬레이터의 모든 비트를 오른쪽으로 한 자리씩 시프트하여, 각 비트의 값을 다음 비트로 이동시킵니다. 0이 비트 7로 시프트되고, 비트 0은 캐리 플래그로 시프트됩니다. 이는 부호 없는 값을 2로 나누고 내림하는 것과 같으며, 나머지는 캐리에 저장됩니다. 이것은 읽기-수정-쓰기(read-modify-write) 명령어입니다. 즉, 메모리에서 작동하는 주소 지정 모드는 수정된 값을 쓰기 전에 원래 값을 먼저 메모리에 다시 씁니다. 이 추가적인 쓰기는 하드웨어 레지스터를 대상으로 할 때 중요할 수 있습니다. {| class="wikitable" ! 플래그 !! 새로운 값 |- | [[Status_flags#C|C - 캐리]] || 값의 비트 0 |- | [[Status_flags#Z|Z - 제로]] || 결과 == 0 |- | [[Status_flags#N|N - 네거티브]] || 0 |} {| class="wikitable" ! 주소 지정 모드 !! 옵코드 !! 바이트 !! 사이클 |- | [[Addressing_modes#Accumulator|Accumulator]] || $4A || 1 || 2 |- | [[Addressing_modes#Zero_page_rmw|Zero Page]] || $46 || 2 || 5 |- | [[Addressing_modes#Zero_page_indexed_rmw|Zero Page,X]] || $56 || 2 || 6 |- | [[Addressing_modes#Absolute_rmw|Absolute]] || $4E || 3 || 6 |- | [[Addressing_modes#Absolute_indexed_rmw|Absolute,X]] || $5E || 3 || 7 |} 참조: [[#ASL|ASL]], [[#ROL|ROL]], [[#ROR|ROR]] ---- {{Anchor|NOP}} === NOP - 아무 작업 안 함 (No Operation) === NOP는 아무 효과가 없습니다. 단지 공간과 CPU 사이클을 낭비할 뿐입니다. 이 명령어는 원하는 시간만큼 지연시키기 위한 시간 코드 작성, 페이지 교차 여부를 보장하기 위한 패딩, 또는 바이너리에서 코드를 비활성화할 때 유용할 수 있습니다. {| class="wikitable" ! 주소 지정 모드 !! 옵코드 !! 바이트 !! 사이클 |- | [[Addressing_modes#Implied|Implied]] || $EA || 1 || 2 |} ---- {{Anchor|ORA}} === ORA - 비트 단위 OR (Bitwise OR) === <code>A = A | 메모리</code> ORA는 메모리 값과 어큐뮬레이터를 비트 단위로 포괄적 OR(inclusive-OR) 연산합니다. 입력 비트 중 하나라도 1이면 결과 비트는 1이 되고, 그렇지 않으면 0이 됩니다. {| class="mw-collapsible mw-collapsed wikitable" |+ style="white-space:nowrap; border:1px solid; padding:3px; border-color:rgb(162, 169, 177); background-color:rgb(234, 236, 240);" | OR 진리표 |- ! A !! 메모리 !! 결과 |- | 0 || 0 || 0 |- | 0 || 1 || 1 |- | 1 || 0 || 1 |- | 1 || 1 || 1 |} {| class="wikitable" ! 플래그 !! 새로운 값 |- | [[Status_flags#Z|Z - 제로]] || 결과 == 0 |- | [[Status_flags#N|N - 네거티브]] || 결과의 비트 7 |} {| class="wikitable" ! 주소 지정 모드 !! 옵코드 !! 바이트 !! 사이클 |- | [[Addressing_modes#Immediate|#Immediate]] || $09 || 2 || 2 |- | [[Addressing_modes#Zero_page_read|Zero Page]] || $05 || 2 || 3 |- | [[Addressing_modes#Zero_page_indexed_read|Zero Page,X]] || $15 || 2 || 4 |- | [[Addressing_modes#Absolute_read|Absolute]] || $0D || 3 || 4 |- | [[Addressing_modes#Absolute_indexed_read|Absolute,X]] || $1D || 3 || 4 (페이지 교차 시 5) |- | [[Addressing_modes#Absolute_indexed_read|Absolute,Y]] || $19 || 3 || 4 (페이지 교차 시 5) |- | [[Addressing_modes#Indirect_x_read|(Indirect,X)]] || $01 || 2 || 6 |- | [[Addressing_modes#Indirect_y_read|(Indirect),Y]] || $11 || 2 || 5 (페이지 교차 시 6) |} 참조: [[#AND|AND]], [[#EOR|EOR]] ---- {{Anchor|PHA}} === PHA - A 푸시 (Push A) === <code>($0100 + SP) = A</code><br /> <code>SP = SP - 1</code> PHA는 A의 값을 현재 스택 위치에 저장한 다음 스택 포인터를 감소시킵니다. {| class="wikitable" ! 주소 지정 모드 !! 옵코드 !! 바이트 !! 사이클 |- | [[Addressing_modes#Implied|Implied]] || $48 || 1 || 3 |} 참조: [[#PLA|PLA]] ---- {{Anchor|PHP}} === PHP - 프로세서 상태 푸시 (Push Processor Status) === <code>($0100 + SP) = NV11DIZC</code><br /> <code>SP = SP - 1</code> PHP는 6개의 상태 플래그와 B 플래그를 포함하는 바이트를 스택에 저장한 다음 스택 포인터를 감소시킵니다. B 플래그와 추가 비트는 모두 1로 푸시됩니다. 비트 순서는 NV1BDIZC (높은 쪽에서 낮은 쪽으로)입니다. {| class="wikitable" ! 플래그 !! 새로운 값 !! 비고 |- | [[Status_flags#B|B - 브레이크]] || 1로 푸시됨 || 이 플래그는 CPU의 실제 상태가 아닌, 스택에 푸시된 플래그 바이트에만 존재합니다. |} {| class="wikitable" ! 주소 지정 모드 !! 옵코드 !! 바이트 !! 사이클 |- | [[Addressing_modes#Implied|Implied]] || $08 || 1 || 3 |} 참조: [[#PLP|PLP]] ---- {{Anchor|PLA}} === PLA - A 풀 (Pull A) === <code>SP = SP + 1</code><br /> <code>A = ($0100 + SP)</code> PLA는 스택 포인터를 증가시킨 다음 해당 스택 위치의 값을 A로 로드합니다. {| class="wikitable" ! 플래그 !! 새로운 값 |- | [[Status_flags#Z|Z - 제로]] || 결과 == 0 |- | [[Status_flags#N|N - 네거티브]] || 결과의 비트 7 |} {| class="wikitable" ! 주소 지정 모드 !! 옵코드 !! 바이트 !! 사이클 |- | [[Addressing_modes#Implied|Implied]] || $68 || 1 || 4 |} 참조: [[#PHA|PHA]] ---- {{Anchor|PLP}} === PLP - 프로세서 상태 풀 (Pull Processor Status) === <code>SP = SP + 1</code><br /> <code>NVxxDIZC = ($0100 + SP)</code> PLP는 스택 포인터를 증가시킨 다음 해당 스택 위치의 값을 6개의 상태 플래그로 로드합니다. 비트 순서는 NVxxDIZC (높은 쪽에서 낮은 쪽으로)입니다. B 플래그와 추가 비트는 무시됩니다. I 변경의 효과는 한 명령어 지연됩니다. 왜냐하면 플래그는 IRQ가 폴링된 후에 변경되어, [[#CLI|CLI]] 및 [[#SEI|SEI]]와 같이 다음 명령어에서 IRQ가 폴링될 때까지 효과가 지연되기 때문입니다. {| class="wikitable" ! 플래그 !! 새로운 값 !! 비고 |- | [[Status_flags#C|C - 캐리]] || 결과의 비트 0 || |- | [[Status_flags#Z|Z - 제로]] || 결과의 비트 1 || |- | [[Status_flags#I|I - 인터럽트 비활성화]] || 결과의 비트 2 || 이 플래그 변경의 효과는 1 명령어 지연됩니다. |- | [[Status_flags#D|D - 데시멀]] || 결과의 비트 3 || |- | [[Status_flags#V|V - 오버플로]] || 결과의 비트 6 || |- | [[Status_flags#N|N - 네거티브]] || 결과의 비트 7 || |} {| class="wikitable" ! 주소 지정 모드 !! 옵코드 !! 바이트 !! 사이클 |- | [[Addressing_modes#Implied|Implied]] || $28 || 1 || 4 |} 참조: [[#PHP|PHP]] ---- {{Anchor|ROL}} === ROL - 왼쪽으로 회전 (Rotate Left) === <code>값 = 캐리를 통해 값 << 1</code>, 또는 시각적으로: <code> C <- [76543210] <- C</code> ROL은 메모리 값 또는 어큐뮬레이터를 왼쪽으로 시프트하여, 각 비트의 값을 다음 비트로 이동시키고 캐리 플래그를 비트 7 위와 비트 0 아래에 모두 있는 것처럼 취급합니다. 구체적으로, 캐리의 값은 비트 0으로 시프트되고, 비트 7은 캐리로 시프트됩니다. 왼쪽으로 9번 회전하면 값과 캐리가 원래 상태로 돌아옵니다. 이것은 읽기-수정-쓰기(read-modify-write) 명령어입니다. 즉, 메모리에서 작동하는 주소 지정 모드는 수정된 값을 쓰기 전에 원래 값을 먼저 메모리에 다시 씁니다. 이 추가적인 쓰기는 하드웨어 레지스터를 대상으로 할 때 중요할 수 있습니다. {| class="wikitable" ! 플래그 !! 새로운 값 |- | [[Status_flags#C|C - 캐리]] || 값의 비트 7 |- | [[Status_flags#Z|Z - 제로]] || 결과 == 0 |- | [[Status_flags#N|N - 네거티브]] || 결과의 비트 7 |} {| class="wikitable" ! 주소 지정 모드 !! 옵코드 !! 바이트 !! 사이클 |- | [[Addressing_modes#Accumulator|Accumulator]] || $2A || 1 || 2 |- | [[Addressing_modes#Zero_page_rmw|Zero Page]] || $26 || 2 || 5 |- | [[Addressing_modes#Zero_page_indexed_rmw|Zero Page,X]] || $36 || 2 || 6 |- | [[Addressing_modes#Absolute_rmw|Absolute]] || $2E || 3 || 6 |- | [[Addressing_modes#Absolute_indexed_rmw|Absolute,X]] || $3E || 3 || 7 |} 참조: [[#ROR|ROR]], [[#ASL|ASL]], [[#LSR|LSR]] ---- {{Anchor|ROR}} === ROR - 오른쪽으로 회전 (Rotate Right) === <code>값 = 캐리를 통해 값 >> 1</code>, 또는 시각적으로: <code> C -> [76543210] -> C</code> ROR은 메모리 값 또는 어큐뮬레이터를 오른쪽으로 시프트하여, 각 비트의 값을 다음 비트로 이동시키고 캐리 플래그를 비트 7 위와 비트 0 아래에 모두 있는 것처럼 취급합니다. 구체적으로, 캐리의 값은 비트 7로 시프트되고, 비트 0은 캐리로 시프트됩니다. 오른쪽으로 9번 회전하면 값과 캐리가 원래 상태로 돌아옵니다. 이것은 읽기-수정-쓰기(read-modify-write) 명령어입니다. 즉, 메모리에서 작동하는 주소 지정 모드는 수정된 값을 쓰기 전에 원래 값을 먼저 메모리에 다시 씁니다. 이 추가적인 쓰기는 하드웨어 레지스터를 대상으로 할 때 중요할 수 있습니다. {| class="wikitable" ! 플래그 !! 새로운 값 |- | [[Status_flags#C|C - 캐리]] || 값의 비트 0 |- | [[Status_flags#Z|Z - 제로]] || 결과 == 0 |- | [[Status_flags#N|N - 네거티브]] || 결과의 비트 7 |} {| class="wikitable" ! 주소 지정 모드 !! 옵코드 !! 바이트 !! 사이클 |- | [[Addressing_modes#Accumulator|Accumulator]] || $6A || 1 || 2 |- | [[Addressing_modes#Zero_page_rmw|Zero Page]] || $66 || 2 || 5 |- | [[Addressing_modes#Zero_page_indexed_rmw|Zero Page,X]] || $76 || 2 || 6 |- | [[Addressing_modes#Absolute_rmw|Absolute]] || $6E || 3 || 6 |- | [[Addressing_modes#Absolute_indexed_rmw|Absolute,X]] || $7E || 3 || 7 |} 참조: [[#ROL|ROL]], [[#ASL|ASL]], [[#LSR|LSR]] ---- {{Anchor|RTI}} === RTI - 인터럽트에서 복귀 (Return from Interrupt) === <code>스택에서 NVxxDIZC 플래그를 [[#PLA|풀]]</code><br /> <code>스택에서 PC를 [[#PLA|풀]]</code> RTI는 인터럽트 핸들러에서 복귀하며, 먼저 스택에서 6개의 상태 플래그를 풀(pull)한 다음 새로운 프로그램 카운터를 풀합니다. 플래그 풀링은 [[#PLP|PLP]]처럼 동작하지만, 인터럽트 비활성화 플래그의 변경 사항이 1 명령어 지연되지 않고 즉시 적용된다는 점이 다릅니다. 이는 플래그가 명령어에 대한 IRQ가 폴링된 후가 아니라 전에 변경되기 때문입니다. PC 풀링은 [[#RTS|RTS]]처럼 동작하지만, 반환 주소가 1바이트 전이 아닌 다음 명령어의 정확한 주소라는 점이 다릅니다. {| class="wikitable" ! 플래그 !! 새로운 값 !! 비고 |- | [[Status_flags#C|C - 캐리]] || 풀링된 플래그의 비트 0 || |- | [[Status_flags#Z|Z - 제로]] || 풀링된 플래그의 비트 1 || |- | [[Status_flags#I|I - 인터럽트 비활성화]] || 풀링된 플래그의 비트 2 || 이 플래그 변경의 효과는 지연되지 '않습니다'. |- | [[Status_flags#D|D - 데시멀]] || 풀링된 플래그의 비트 3 || |- | [[Status_flags#V|V - 오버플로]] || 풀링된 플래그의 비트 6 || |- | [[Status_flags#N|N - 네거티브]] || 풀링된 플래그의 비트 7 || |} {| class="wikitable" ! 주소 지정 모드 !! 옵코드 !! 바이트 !! 사이클 |- | [[Addressing_modes#Implied|Implied]] || $40 || 1 || 6 |} 참조: [[#BRK|BRK]], [[#PLP|PLP]], [[#RTS|RTS]] ---- {{Anchor|RTS}} === RTS - 서브루틴에서 복귀 (Return from Subroutine) === <code>스택에서 PC를 [[#PLA|풀]]</code><br /> <code>PC = PC + 1</code> RTS는 스택에서 주소를 프로그램 카운터로 풀(pull)한 다음 프로그램 카운터를 증가시킵니다. 이는 보통 함수 끝에서 함수를 호출한 [[#JSR|JSR]] 다음 명령어로 돌아가기 위해 사용됩니다. 그러나 RTS는 점프 테이블을 구현하는 데 사용되기도 합니다([[Jump table]] 및 [[RTS Trick]] 참조). {| class="wikitable" ! 주소 지정 모드 !! 옵코드 !! 바이트 !! 사이클 |- | [[Addressing_modes#Implied|Implied]] || $60 || 1 || 6 |} 참조: [[#JSR|JSR]], [[#PLA|PLA]] ---- {{Anchor|SBC}} === SBC - 캐리와 함께 빼기 (Subtract with Carry) === <code>A = A - 메모리 - ~C</code>, 또는 동등하게: <code>A = A + ~메모리 + C</code> SBC는 메모리 값과 캐리의 비트 단위 NOT을 어큐뮬레이터에서 뺍니다. 이는 메모리 값의 비트 단위 NOT을 [[#ADC|ADC]]를 사용하여 ''더하는'' 방식으로 수행됩니다. 이 구현 세부 사항은 캐리의 역방향 특성을 설명합니다. SBC는 캐리가 설정되었을 때가 아니라 ''클리어''되었을 때 1을 더 빼고, 언더플로가 발생하면 캐리가 클리어되고 그렇지 않으면 설정됩니다. [[#ADC|ADC]]와 마찬가지로, 캐리는 한 뺄셈의 빌림(borrow)을 다음 뺄셈으로 넘겨주어 1바이트보다 큰 값의 뺄셈을 가능하게 합니다. 첫 바이트를 빼기 전에 [[#SEC|SEC]]로 캐리를 설정하여 알려진 상태로 만들어, 1만큼의 오차를 피하는 것이 일반적입니다. 오버플로는 [[#ADC|ADC]]와 동일하게 작동하지만, 메모리 값이 반전됩니다. 따라서 결과의 부호가 A의 부호와 다르고 메모리 값의 부호와 같으면 오버플로 또는 언더플로가 발생합니다. {| class="wikitable" ! 플래그 !! 새로운 값 !! 비고 |- | [[Status_flags#C|C - 캐리]] || ~(결과 < $00) || 결과가 $00 미만으로 언더플로(랩어라운드)되면, 부호 없는 언더플로가 발생한 것입니다. |- | [[Status_flags#Z|Z - 제로]] || 결과 == 0 || |- | [[Status_flags#V|V - 오버플로]] || (결과 ^ A) & (결과 ^ ~메모리) & $80 || 결과의 부호가 A의 부호와 다르고 메모리의 부호와 같으면, 부호 있는 오버플로(또는 언더플로)가 발생한 것입니다. |- | [[Status_flags#N|N - 네거티브]] || 결과의 비트 7 || |} {| class="wikitable" ! 주소 지정 모드 !! 옵코드 !! 바이트 !! 사이클 |- | [[Addressing_modes#Immediate|#Immediate]] || $E9 || 2 || 2 |- | [[Addressing_modes#Zero_page_read|Zero Page]] || $E5 || 2 || 3 |- | [[Addressing_modes#Zero_page_indexed_read|Zero Page,X]] || $F5 || 2 || 4 |- | [[Addressing_modes#Absolute_read|Absolute]] || $ED || 3 || 4 |- | [[Addressing_modes#Absolute_indexed_read|Absolute,X]] || $FD || 3 || 4 (페이지 교차 시 5) |- | [[Addressing_modes#Absolute_indexed_read|Absolute,Y]] || $F9 || 3 || 4 (페이지 교차 시 5) |- | [[Addressing_modes#Indirect_x_read|(Indirect,X)]] || $E1 || 2 || 6 |- | [[Addressing_modes#Indirect_y_read|(Indirect),Y]] || $F1 || 2 || 5 (페이지 교차 시 6) |} 참조: [[#ADC|ADC]], [[#SEC|SEC]] ---- {{Anchor|SEC}} === SEC - 캐리 설정 (Set Carry) === <code>C = 1</code> SEC는 캐리 플래그를 설정합니다. 특히, 이는 보통 [[#SBC|SBC]]로 값의 하위 바이트를 빼기 전에 추가적인 1이 빼지는 것을 방지하기 위해 수행됩니다. {| class="wikitable" ! 플래그 !! 새로운 값 |- | [[Status_flags#C|C - 캐리]] || 1 |} {| class="wikitable" ! 주소 지정 모드 !! 옵코드 !! 바이트 !! 사이클 |- | [[Addressing_modes#Implied|Implied]] || $38 || 1 || 2 |} 참조: [[#CLC|CLC]] ---- {{Anchor|SED}} === SED - 데시멀 설정 (Set Decimal) === <code>D = 1</code> SED는 데시멀 플래그를 설정합니다. 데시멀 플래그는 보통 BCD(binary-coded decimal) 모드가 활성화되는지를 제어하지만, 이 모드는 NES의 2A03 CPU에서 영구적으로 비활성화되어 있습니다. 그러나 플래그 자체는 여전히 작동하며 상태를 저장하는 데 사용될 수 있습니다. {| class="wikitable" ! 플래그 !! 새로운 값 |- | [[Status_flags#D|D - 데시멀]] || 1 |} {| class="wikitable" ! 주소 지정 모드 !! 옵코드 !! 바이트 !! 사이클 |- | [[Addressing_modes#Implied|Implied]] || $F8 || 1 || 2 |} 참조: [[#CLD|CLD]] ---- {{Anchor|SEI}} === SEI - 인터럽트 비활성화 설정 (Set Interrupt Disable) === <code>I = 1</code> SEI는 인터럽트 비활성화 플래그를 설정하여, CPU가 하드웨어 IRQ를 처리하지 못하게 합니다. 이 플래그 변경의 효과는 한 명령어 지연됩니다. 왜냐하면 플래그는 IRQ가 폴링된 후에 변경되어, 이전에 플래그가 0이었다면 이 명령어와 다음 명령어 사이에 IRQ가 서비스될 수 있기 때문입니다. {| class="wikitable" ! 플래그 !! 새로운 값 !! 비고 |- | [[Status_flags#I|I - 인터럽트 비활성화]] || 1 || 이 플래그 변경의 효과는 1 명령어 지연됩니다. |} {| class="wikitable" ! 주소 지정 모드 !! 옵코드 !! 바이트 !! 사이클 |- | [[Addressing_modes#Implied|Implied]] || $78 || 1 || 2 |} 참조: [[#CLI|CLI]] ---- {{Anchor|STA}} === STA - A 저장 (Store A) === <code>메모리 = A</code> STA는 어큐뮬레이터 값을 메모리에 저장합니다. {| class="wikitable" ! 주소 지정 모드 !! 옵코드 !! 바이트 !! 사이클 |- | [[Addressing_modes#Zero_page_write|Zero Page]] || $85 || 2 || 3 |- | [[Addressing_modes#Zero_page_indexed_write|Zero Page,X]] || $95 || 2 || 4 |- | [[Addressing_modes#Absolute_write|Absolute]] || $8D || 3 || 4 |- | [[Addressing_modes#Absolute_indexed_write|Absolute,X]] || $9D || 3 || 5 |- | [[Addressing_modes#Absolute_indexed_write|Absolute,Y]] || $99 || 3 || 5 |- | [[Addressing_modes#Indirect_x_write|(Indirect,X)]] || $81 || 2 || 6 |- | [[Addressing_modes#Indirect_y_write|(Indirect),Y]] || $91 || 2 || 6 |} 참조: [[#LDA|LDA]] ---- {{Anchor|STX}} === STX - X 저장 (Store X) === <code>메모리 = X</code> STX는 X 레지스터 값을 메모리에 저장합니다. {| class="wikitable" ! 주소 지정 모드 !! 옵코드 !! 바이트 !! 사이클 |- | [[Addressing_modes#Zero_page_write|Zero Page]] || $86 || 2 || 3 |- | [[Addressing_modes#Zero_page_indexed_write|Zero Page,Y]] || $96 || 2 || 4 |- | [[Addressing_modes#Absolute_write|Absolute]] || $8E || 3 || 4 |} 참조: [[#LDX|LDX]] ---- {{Anchor|STY}} === STY - Y 저장 (Store Y) === <code>메모리 = Y</code> STY는 Y 레지스터 값을 메모리에 저장합니다. {| class="wikitable" ! 주소 지정 모드 !! 옵코드 !! 바이트 !! 사이클 |- | [[Addressing_modes#Zero_page_write|Zero Page]] || $84 || 2 || 3 |- | [[Addressing_modes#Zero_page_indexed_write|Zero Page,X]] || $94 || 2 || 4 |- | [[Addressing_modes#Absolute_write|Absolute]] || $8C || 3 || 4 |} 참조: [[#LDY|LDY]] ---- {{Anchor|TAX}} === TAX - A를 X로 전송 (Transfer A to X) === <code>X = A</code> TAX는 어큐뮬레이터 값을 X 레지스터로 복사합니다. {| class="wikitable" ! 플래그 !! 새로운 값 |- | [[Status_flags#Z|Z - 제로]] || 결과 == 0 |- | [[Status_flags#N|N - 네거티브]] || 결과의 비트 7 |} {| class="wikitable" ! 주소 지정 모드 !! 옵코드 !! 바이트 !! 사이클 |- | [[Addressing_modes#Implied|Implied]] || $AA || 1 || 2 |} 참조: [[#TXA|TXA]], [[#TAY|TAY]], [[#TYA|TYA]] ---- {{Anchor|TAY}} === TAY - A를 Y로 전송 (Transfer A to Y) === <code>Y = A</code> TAY는 어큐뮬레이터 값을 Y 레지스터로 복사합니다. {| class="wikitable" ! 플래그 !! 새로운 값 |- | [[Status_flags#Z|Z - 제로]] || 결과 == 0 |- | [[Status_flags#N|N - 네거티브]] || 결과의 비트 7 |} {| class="wikitable" ! 주소 지정 모드 !! 옵코드 !! 바이트 !! 사이클 |- | [[Addressing_modes#Implied|Implied]] || $A8 || 1 || 2 |} 참조: [[#TYA|TYA]], [[#TAX|TAX]], [[#TXA|TXA]] ---- {{Anchor|TSX}} === TSX - 스택 포인터를 X로 전송 (Transfer Stack Pointer to X) === <code>X = SP</code> TSX는 스택 포인터 값을 X 레지스터로 복사합니다. {| class="wikitable" ! 플래그 !! 새로운 값 |- | [[Status_flags#Z|Z - 제로]] || 결과 == 0 |- | [[Status_flags#N|N - 네거티브]] || 결과의 비트 7 |} {| class="wikitable" ! 주소 지정 모드 !! 옵코드 !! 바이트 !! 사이클 |- | [[Addressing_modes#Implied|Implied]] || $BA || 1 || 2 |} 참조: [[#TXS|TXS]] ---- {{Anchor|TXA}} === TXA - X를 A로 전송 (Transfer X to A) === <code>A = X</code> TXA는 X 레지스터 값을 어큐뮬레이터로 복사합니다. {| class="wikitable" ! 플래그 !! 새로운 값 |- | [[Status_flags#Z|Z - 제로]] || 결과 == 0 |- | [[Status_flags#N|N - 네거티브]] || 결과의 비트 7 |} {| class="wikitable" ! 주소 지정 모드 !! 옵코드 !! 바이트 !! 사이클 |- | [[Addressing_modes#Implied|Implied]] || $8A || 1 || 2 |} 참조: [[#TAX|TAX]], [[#TAY|TAY]], [[#TYA|TYA]] ---- {{Anchor|TXS}} === TXS - X를 스택 포인터로 전송 (Transfer X to Stack Pointer) === <code>SP = X</code> TXS는 X 레지스터 값을 스택 포인터로 복사합니다. {| class="wikitable" ! 주소 지정 모드 !! 옵코드 !! 바이트 !! 사이클 |- | [[Addressing_modes#Implied|Implied]] || $9A || 1 || 2 |} 참조: [[#TXS|TXS]] ---- {{Anchor|TYA}} === TYA - Y를 A로 전송 (Transfer Y to A) === <code>A = Y</code> TYA는 Y 레지스터 값을 어큐뮬레이터로 복사합니다. {| class="wikitable" ! 플래그 !! 새로운 값 |- | [[Status_flags#Z|Z - 제로]] || 결과 == 0 |- | [[Status_flags#N|N - 네거티브]] || 결과의 비트 7 |} {| class="wikitable" ! 주소 지정 모드 !! 옵코드 !! 바이트 !! 사이클 |- | [[Addressing_modes#Implied|Implied]] || $98 || 1 || 2 |} 참조: [[#TAY|TAY]], [[#TAX|TAX]], [[#TXA|TXA]] ---- {{Anchor|footnote}} === 비고 === 상대 주소 지정 모드(Relative addressing)에 대해, https://www.nesdev.org/6502_cpu.txt 문서는 분기 명령어가 5개의 가능한 사이클을 갖는 것으로 나타내지만, 이 페이지에 언급된 2-4 사이클이 정확합니다. 1 PC R 옵코드 가져오기, PC 증가 2 PC R 피연산자 가져오기, PC 증가 3 PC R 다음 명령어의 옵코드 가져오기, 분기가 발생하면, 피연산자를 PCL에 더함. 그렇지 않으면 PC 증가. 4+ PC* R 다음 명령어의 옵코드 가져오기. PCH 수정. 변경되지 않았다면 PC 증가. 5! PC R 다음 명령어의 옵코드 가져오기, PC 증가. 이 노트들은 문서에서 사이클이 표현되는 방식을 명확히 하는 데 도움이 됩니다: * 분기가 발생하지 않으면, 여기에 표시된 사이클 3은 실제로는 다음 명령어의 사이클 1입니다 (분기 명령어는 2 사이클 후에 종료됨). * 분기가 발생하고 페이지 경계를 넘지 않으면, 여기에 표시된 사이클 4는 다음 명령어의 사이클 1입니다 (분기 명령어는 3 사이클 후에 종료됨). * 페이지 경계가 교차되면, 여기에 표시된 사이클 5는 다음 명령어의 사이클 1입니다 (분기 명령어는 4 사이클 후에 종료됨). 요약: 한식구 위키에서의 모든 기여는 크리에이티브 커먼즈 저작자표시-동일조건변경허락 라이선스로 배포된다는 점을 유의해 주세요(자세한 내용에 대해서는 한식구위키:저작권 문서를 읽어주세요). 만약 여기에 동의하지 않는다면 문서를 저장하지 말아 주세요. 또한, 직접 작성했거나 퍼블릭 도메인과 같은 자유 문서에서 가져왔다는 것을 보증해야 합니다. 저작권이 있는 내용을 허가 없이 저장하지 마세요! 자동 편집 스팸으로부터 위키를 보호하기 위해, 다음 CAPTCHA를 풀어주세요: 취소 편집 도움말 (새 창에서 열림) 이 문서에서 사용한 틀: 틀:NES (편집) 틀:알림 상자 (편집)