문제

저는 현재 오래된 GameBoy용 에뮬레이터를 개발 중이며 일부 기본 작업 코드를 구현하는 방법을 이해하는 데 몇 가지 문제에 직면하고 있습니다.

지금은 AND 연산을 구현하고 있습니다.처음 몇 개(0xA0 -> 0xA3;0xA6 및 0xA7)은 매우 간단하지만 레지스터 H, L에 대한 AND 연산은 약간 다릅니다.

다음 링크에서 z80 설명서를 다운로드할 수 있습니다.um0080.pdf (172페이지)

다음은 내가 의미하는 바(의사 코드 사용)와 기본적으로 내가 수행하는 작업을 보여주는 몇 가지 예입니다.

AND A,H(비트 이동에 유의)

(read HL register; >> 8) save in cache C
R->C = R->HL >> 8;

perform AND operation with cache
AND_H(R->C);
R->A &= R->C;

AND A,L(비트 마스킹 참고)

(read HL register; &0xFF) save in cache C
R->C = R->HL &0xFF;

나는 비트 연산을 모두 알고 있고 그것이 무엇을 하는지 알고 있지만, 왜 그렇게 해야 하는지는 알 수 없는 것 같습니다.나는 몇 가지 이론을 가지고 있습니다 (내가 틀렸다면 정정하십시오 :-)):

내가 이미 이해한 것은 H와 L 레지스터가 기본적으로 16비트 레지스터인 HL 레지스터라는 것입니다.CPU/버스는 8비트 작업만 처리할 수 있으므로 분할해야 합니다.또는 더 많은 논리 제안:레지스터가 하나뿐이므로 H와 L의 값은 레지스터에 마스크되어 있으며 단순히 서로 분리하면 됩니다(상위/하위 니블?).

나는 단지 좀 더 많은 배경 지식(이 모든 것이 내부적으로 어떻게 작동하는지)을 알고 싶기 때문에 누군가가 나에게 이것을 더 명확하게 해줄 수 있다면 깊이 감사할 것입니다. 그래서 내가 하고 있는 일을 아는 것이 나에게 매우 중요합니다.

도움이 되었습니까?

해결책

의견에서 지적했듯이, 발견한 구현이 H 및 L 레지스터를 16비트 엔터티 HL로 함께 저장한 다음 이를 오른쪽으로 이동하여 H로 분해하고 마스킹하여 L로 분해한다는 사실은 순전히 구현에 따른 것입니다.

원본 z80에는 4비트 ALU가 있습니다(9페이지 하단에서 시작하는 Shima의 설명 참조). 컴퓨터 역사 박물관 패널의 이 사본) 따라서 실제로는 (i) L과 누산기의 하위 4비트를 AND합니다.그런 다음 (ii) L과 누산기의 상위 4비트를 AND합니다.그러나 레지스터를 개별 8비트 엔터티로 노출하므로 내부 구현이 완전히 숨겨집니다.

HL은 16비트 양을 만들기 위해 함께 결합된 두 개의 레지스터이기 때문에 레지스터 쌍이라고 합니다.섀도우 및 인덱스 레지스터를 무시하면 원래 z80에는 실제로 HL, BC 및 DE라는 세 가지 레지스터가 있습니다.BC와 DE는 Gameboy의 CPU에서 간접 로딩(예: opcode 0x1a — LD A, (BC)) 및 16비트 산술(예: 0x09 ADD HL, BC)을 위한 대체 쌍으로 남아 있으며 몇 가지 다른 용도로 사용됩니다. z80.

SP와 PC는 일반적으로 분할할 수 없는 16비트 레지스터로 간주됩니다(물론 메모리에 저장하고 바이트를 개별적으로 다시 읽어서 분할할 수 있음). AF는 푸시 및 팝을 위해 존재하지만 F는 AF와 같은 특수한 경우입니다. 일반적으로 16비트 정수로는 특별히 유용하지 않습니다.

간략한 요약은 다음과 같습니다.opcode가 어떻게 작동하는지 이해하는 데 문제가 없습니다. 해야 구현된 것은 특정 작성자가 어떻게 구현했는지에 불과합니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top