


실제 하드웨어와 같은 버스·타이밍 동작으로 에뮬레이터 만들기
에뮬레이터를 만들거나 고칠 때 씁니다. 하드웨어 부품별로 코드를 나누고, 버스 읽기·쓰기와 타이밍, DMA를 실기와 똑같이 재현하며, 실기에서 통과하는 참조 프로그램으로 테스트하고, 저장 상태와 공개 API를 안정적으로 유지합니다.
이 AI 규칙을 사용하려면
## 특이한 구현의 이유를 적고 타입 체크와 테스트 돌리기
원래 하드웨어를 모를 수 있는 엔지니어도 이해할 수 있도록 에뮬레이터 코드를 작성하세요. 특이한 구현은 그 자체로 명확하다고 가정하지 말고, 타이밍 규칙, 부작용, 우회책이 존재하는 이유를 설명하세요. 동작을 명확히 하는 데 도움이 될 때는 권위 있는 하드웨어 자료를 연결하세요.
저장소에 문서화된 포맷팅, 린트, 타입 검사, 테스트, 빌드, 감시 모드, 벤치마크 명령을 찾아 사용하세요. 필수 검사를 변경 작업의 일부로 취급하세요.
- 반복 작업 중에는 포맷팅과 대상이 명확한 테스트를 실행하세요.
- 공개 선언이나 타입이 지정된 경계가 바뀌면 타입 검사를 실행하세요.
- 커밋하거나 인계하기 전에 권위 있는 전체 테스트 스위트를 실행하세요.
- 큰 변경이나 성능 회귀가 의심될 때는 성능 벤치마크를 실행하세요.
- 관련 없는 리팩터링을 대상이 명확한 수정과 분리하세요.
메서드, 옵션, 콜백, 내보내기, 지원되는 입력 형식이 바뀌면 공개 예제와 API 참조를 갱신하세요. 국소적인 구현 세부 사항은 가까운 주석에 기록하고, 프로젝트 수준 지침에는 여러 컴포넌트에 적용되는 아키텍처와 규칙만 두세요.
## 에뮬레이터를 하드웨어 부품 단위의 컴포넌트로 나누기
에뮬레이터가 모델링하는 하드웨어 하위 시스템을 중심으로 구성하세요. 작은 조정자로 컴포넌트를 조율하고 렌더링, 오디오, 상태, 영구 메모리 갱신을 위한 콜백을 제공하세요.
프로세서, 비디오, 오디오, 카트리지 또는 메모리 매핑, 프로그램 로딩, 렌더링 헬퍼, 컨트롤러, 직렬화의 책임을 분리하세요. 각 컴포넌트에 명확한 인터페이스를 제공하고 내부 상태를 직접 소유하게 하세요.
하드웨어 변형이 실제로 공통 기반 동작을 공유하고 특정 매핑 또는 뱅킹 규칙만 재정의할 때만 상속을 사용하세요. 독립적인 하위 시스템에는 합성을 우선하고 컴포넌트 경계를 넘는 숨겨진 접근을 피하세요.
공통 시간 기준을 정의하세요. 프레임 기반 실행도 각 프레임 안에서 정확한 사이클 계산이 필요하지만, 표시 타이밍과 스케줄링은 계속 호스트 애플리케이션이 담당합니다.
모든 상태 보유 컴포넌트가 사용하는 대칭적인 직렬화 및 복원 계약을 통해 저장 상태 변환을 중앙화하세요.
## 더미 읽기·쓰기까지 포함해 버스 접근을 실기대로 재현하기
버스를 단순한 주소-값 조회가 아니라 상태를 가진 동작으로 모델링하세요. 실제 하드웨어는 가장 최근 값을 유지하거나, 매핑되지 않은 주소 또는 쓰기 전용 주소에서 래치된 데이터를 반환하거나, 값의 일부 비트만 구동할 수 있습니다.
서로 다른 하드웨어 버스가 독립적인 상태를 유지한다면 각각의 래치를 추적하세요. 관찰 가능한 로드, 쓰기, 스택 작업, 연산 코드 가져오기, 인터럽트 벡터 가져오기가 일어날 때마다 적절한 래치를 갱신하세요. 장치가 값의 일부만 구동한다면 해당 비트와 유지된 버스 상태를 하드웨어와 정확히 같은 방식으로 결합하세요.
더미 읽기와 더미 쓰기를 실제 버스 작업으로 구현하세요. 프로그램이 반환값을 전혀 사용하지 않더라도 래치된 값을 갱신하고 I/O 부작용을 유발할 수 있습니다.
각 주소 지정 방식의 버스 순서를 명시적으로 구현하세요.
- 인덱스 주소 지정은 페이지 보정 전에 중간 주소를 읽을 수 있습니다.
- 제로 페이지 인덱싱은 인덱스를 적용하기 전에 인덱스가 적용되지 않은 주소를 읽을 수 있습니다.
- 간접 인덱싱은 유효 주소에 도달하기 전에 포인터나 중간 주소를 읽을 수 있습니다.
- 저장 명령과 읽기-수정-쓰기 명령은 페이지를 넘지 않아도 필수 더미 접근을 수행할 수 있습니다.
- 읽기-수정-쓰기 명령은 수정된 값을 쓰기 전에 원래 값을 먼저 쓸 수 있습니다.
가져오기가 스택 작업 전후에 발생한다면 명령별 순서를 보존하세요. 최종 레지스터 값이 같아지는 작업이라도 순서를 바꾸면 버스에서 관찰 가능한 오류가 생길 수 있습니다.
## 명령 도중에도 장치 시간을 맞추고 DMA를 실제 버스 사이클로 다루기
에뮬레이터가 한 컴포넌트를 원자적으로 실행하는 반면 실제 하드웨어의 컴포넌트가 맞물려 진행된다면, 명령 실행 도중 레지스터 접근에서 오래된 상태가 나타날 수 있습니다. 접근이 관찰 가능해지는 경계에서 이를 보정하세요.
현재 명령이 완료한 버스 작업 수를 추적하세요. 동기화된 장치의 레지스터를 읽거나 쓰기 전에 경과한 작업에 대한 정확한 클록 비율만큼 그 장치를 진행하세요. 나중의 프레임 수준 진행량에서 이미 적용한 작업을 빼서 시간을 절대 두 번 계산하지 마세요.
인터럽트 플래그 생성과 인터럽트 전달을 별도로 모델링하세요. 억제 제어는 외부 인터럽트 신호만 막는 것이 아니라 상태 플래그 자체가 생성되지 않게 할 수 있습니다. 테스트는 이 두 동작을 구분해야 합니다.
DMA를 실제 버스 사이클의 점유로 표현하세요. 전송은 현재 버스 값을 바꾸거나, 프로세서 진행을 지연시키거나, 출력값이 버스 상태에 의존하는 명령의 결과를 바꿀 수 있습니다. DMA, 명령 접근, 장치 부작용 사이의 순서를 보존하세요.
문서화된 비공식 명령이나 경계 사례 명령은 신뢰할 수 있는 자료와 테스트만을 바탕으로 구현하세요. 일반 소프트웨어가 사용하지 않는다는 이유만으로 사이클 동작을 단순화하지 마세요.
## 실기에서 통과하는 참조 프로그램으로 테스트하기
각기 다른 목적을 가진 여러 테스트 계층을 사용하세요.
- 단위 테스트는 초기화, 명령 의미, 매핑 규칙, 메모리 미러링, 상태 전환, 오류 처리를 검증합니다.
- 대상이 명확한 회귀 테스트는 프레임 버퍼, 오디오 샘플, 버스 추적 또는 그 밖의 결정적 출력을 고정합니다.
- 통합 테스트 하네스는 신뢰할 수 있는 진단 프로그램을 실행하고 상세한 머신 상태나 오류 코드를 비교합니다.
- 하드웨어 정확도 테스트 스위트는 분리된 명령 테스트로 드러낼 수 없는 상호 작용을 다룹니다.
실제 하드웨어에서 통과한다고 알려진 확립된 참조 프로그램은 올바른 것으로 취급하세요. 참조 프로그램을 탓하기 전에 에뮬레이터, 하네스, 테스트 픽스처, 환경을 조사하세요.
허용된 실패는 한정된 이유와 함께 명시적으로 기록하세요. 알려진 실패 목록은 새로운 회귀를 숨기거나 기존 예외의 범위를 넓힐 수 있는 허가가 아닙니다.
하드웨어가 중간 접근을 관찰할 수 있을 때는 최종 값과 작업 순서를 모두 테스트하세요. 사양 수정이나 이전에 잘못 분류된 동작으로 인해 구현이 바뀔 때마다 회귀 사례를 추가하세요.
## 저장 상태를 완전히 되돌릴 수 있게 하고 크래시 후 실행 멈추기
저장 상태에는 프로세서, 비디오, 오디오, 매퍼, 래치, 인터럽트, 타이밍 상태를 비롯해 향후 실행에 영향을 주는 모든 컴포넌트가 포함되어야 합니다. 데이터가 파싱되는지만 확인하지 말고, 직렬화 후 복원했을 때 실행이 재현되는지 검증하세요.
코어를 하나의 호스트 환경에 결합하지 말고, 명확한 콜백 또는 저장 경계를 통해 영구 메모리를 제공하세요.
일반 컨트롤러는 명시적인 버튼 전환과 직렬 프로토콜을 가진 단순한 상태 머신으로 유지하세요. 특수 주변 장치는 고유한 공간, 타이밍, 빛 감지 동작을 보존하는 전용 API를 통해 모델링하세요.
복구할 수 없는 실행 예외가 발생한 뒤에는 명시적인 실행 중단 상태를 설정하고 이후 프레임 실행을 막으세요. 부분적으로 변경된 상태에서 계속하지 말고, 문서화된 재설정 또는 프로그램 재로드를 복구에 필수로 요구하세요.
허용되는 프로그램 입력과 공개 콜백 타입을 안정적으로 유지하세요. 브라우저와 서버 사용자가 같은 API 계약을 보도록 공개 타입 선언을 구현과 함께 유지하세요.
## 생성 파일은 빌드로만 만들고 테스트하지 못한 부분 보고하기
승인된 빌드를 통해 배포 번들, 축소 파일, 소스 맵, 선언을 생성하세요. 생성된 출력을 직접 편집하지 마세요.
프로젝트가 지원한다고 명시한 모든 런타임 대상과 모듈 형식을 검증하세요. 지속적 통합에서는 로컬에서 요구되는 것과 동일한 포맷팅, 린트, 빌드, 타입, 테스트 게이트를 실행해야 합니다.
하드웨어 동작을 변경하기 전에 권위 있는 사양과 신뢰할 수 있는 구현 참고 사항을 확인하세요. 명확하지 않은 코드의 이유를 해당 작업 가까이에 기록하고, 순서를 바꿀 때 관찰 가능한 결과도 포함하세요.
최종 변경 내역에서 의도하지 않은 생성 파일 편집, 오래된 공개 문서, 테스트하지 않은 타이밍 경로, 관련 없는 정리를 확인하세요. 실행한 대상 검사, 해당되는 경우 벤치마크 결과, 알려진 실패, 아직 검증되지 않은 하드웨어 경로를 보고하세요.
