Chip-8 에뮬레이터 작성
에뮬레이터란 무엇입니까?
에뮬레이터의 개념은 모든 운영 체제에서 동일합니다. 기본적으로 한 시스템의 지침을 다른 시스템으로 변환하려고 합니다. 번역 과정은 크게 세 부분으로 이루어집니다.
이 세 단계는 시스템의 주요 구성 요소인 CPU에서 발생합니다. 첫 번째 단계는 프로그램에서 작업 코드를 읽고 CPU가 이 코드를 해독한 다음 그에 따라 실행하는 것입니다.
칩-8
우주 침략자들
흥분하기 전에 시스템이 어떻게 작동하고 작동하는지 이해해야 합니다. 2진수 및 16진수 변환에 익숙해지십시오. 프로그램을 디버깅할 때 hex 뷰어가 유용할 수 있습니다.
CPU 및 메모리
Chip-8은 각각 최대 8비트(1바이트)의 정보를 취하는 16개의 CPU 레지스터가 있는 간단한 시스템입니다. 프로그램 카운터, I 레지스터, opcode 자리 표시자 및 스택 포인터는 모두 16비트(2바이트)의 크기를 갖습니다. 메모리는 4Kb 메모리로, 처음 512Kb는 인터프리터용으로 예약되어 있어 Chip-8용으로 작성된 대부분의 프로그램은 위치 512에서 시작합니다. 최소 16레벨 스택 포인터가 필요하며 이는 프로그램 카운터 레지스터.
타이머
60에서 0까지 카운트다운하는 두 개의 타이머가 있습니다. 지연 타이머는 프로그램 이벤트에 사용되며 값을 설정하고 읽을 수 있습니다. 그리고 0에 도달할 때마다 경고음을 재생하는 사운드 타이머. 모든 작업 실행 후 두 타이머 모두 1씩 뺍니다.
입력
Chip-8은 일반적으로 다음에 매핑되는 16개의 입력 키(0x0-0xF)를 사용합니다.
1 2 3 C 1 2 3 4
4 5 6 D --\ Q W E R
7 8 9 E --/ A S D F
A 0 B F Z X C V
일반적으로 '2', '4', '8' 및 '6'은 방향에 사용됩니다.
제도법
Chip-8에는 32x64 픽셀의 흑백 디스플레이가 있습니다. 스프라이트를 사용하여 화면에 그래픽을 그립니다. "스프라이트는 원하는 그림의 이진 표현인 바이트 그룹입니다."최대 15바이트를 차지할 수 있습니다. Chip-8은 0에서 F까지의 16진수를 나타내는 미리 정의된 스프라이트 세트를 제공합니다. 예를 들면 다음과 같습니다.
"1" | Binary | Hex
------+----------+-----
* | 00100000 | 0x20
** | 01100000 | 0x60
* | 00100000 | 0x20
* | 00100000 | 0x20
*** | 01110000 | 0x70
"F" | Binary | Hex
------+----------+-----
**** | 11110000 | 0xF0
* | 10000000 | 0x80
**** | 11110000 | 0xF0
* | 10000000 | 0x80
* | 10000000 | 0x80
이러한 스프라이트는 메모리의 예약된 인터프리터 영역 0-512에 저장되어야 합니다.
구현
큰 그림부터 시작하십시오. 컴퓨터는 어떻게 작동합니까? 컴퓨터를 부팅하면 구성 요소 및 장치 초기화가 시작됩니다. 여기에는 입력, 출력, 그래픽, CPU 등이 포함됩니다. 그런 다음 시스템을 로드하고 명령 실행을 순차적으로 시작합니다. 메인 루프는 다음과 같아야 합니다.
#include // Chip-8 system
#include // Input
#include // Graphics
int main(int argc, char **argv) {
initChip8();
initInput();
initGraphics();
loadROM("INVADERS");
while(systeIsRunning) {
// Execute instruction
executeOP();
// Refresh display if flag is set
if (drawFlag)
drawGraphics();
// Play beep if flag is set
if (playSound)
playBeep();
// Set input and set keys states
setInput();
}
return 0;
}
Chip-8은 명령을 로드하고 실행하는 방법을 구현해야 합니다.
void initChip8() {
// initialize system
// memory
// registers
// stack
// graphics
}
void loadROM(file) {
// read file into memory
// starting from location 512Kb
// or 0x200 in hex
}
void executeOP() {
// fetch opcode
opcode = (memory[pc] << 8) + memory[pc + 1];
// decode opcode
switch (opcode & 0xF000) {
// execute opcode
case 0x0:
if (opcode == 0x00E0)
clearDisplay();
elseif (opcode == 0x00EE)
// return from subroutine
case 0x1:
.
.
.
case 0xF:
}
// timers
if (delay_timer > 0)
--delay_timer;
if (sound_timer > 0) {
if (sound_timer == 1)
playSound();
--sound_timer;
}
}
입력 및 그래픽은 사용할 라이브러리에 따라 다릅니다. 나는 크로스 플랫폼이고 매우 잘 알려져 있고 많은 문서가 있기 때문에 이 두 가지를 위해 SDL2을 사용했습니다. 내 Chip-8 구현here을 참조할 수 있습니다.
다음은?
음, 저는 이 프로젝트에서 정말 많은 것을 배웠습니다. 다음으로 ncurses을 사용하여 터미널 기반 UI를 갖도록 이 프로젝트를 확장하려고 합니다. 아니면 NES와 같은 더 복잡한 시스템에서 작업할 수 있습니까?
참조
Reference
이 문제에 관하여(Chip-8 에뮬레이터 작성), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/aymanbagabas/writing-a-chip-8-emulator-2dma텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)