В настоящее время я разрабатываю эмулятор для старого старого GameBoy, и мне приходится сталкиваться с некоторыми проблемами, понимая, как некоторые базовые коды операций должны быть реализованы.
Сейчас я реализую операции AND; первые несколько (0xA0 → 0xA3; 0xA6 и 0xA7) довольно прямолинейны, но операции AND для регистров H, L немного отличаются.
Вы можете загрузить документацию z80 по этой ссылке: um0080.pdf (стр. 172)
Вот несколько примеров, чтобы показать, что я имею в виду (с псевдокодом) и в основном то, что я делаю:
И 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;
И A, L (обратите внимание на маскирование бит)
(read HL register; &0xFF) save in cache C
R->C = R->HL &0xFF;
Я знаю все бит-операции, и я знаю, что они делают, но, похоже, я не могу понять, почему нужно это делать. У меня есть некоторые теории (исправьте меня, если я ошибаюсь: -)):
Я уже понял, что регистры H и L являются в основном регистром HL, который является 16-битным регистром. Поскольку CPU/Bus может обрабатывать только 8-битные операции, его необходимо разделить; или более логическое предложение: поскольку его единственный регистр, значения H и L маскируются в регистре, и их просто нужно отделить друг от друга (более высокий/нижний полубайт?).
Я был бы глубоко благодарен, если бы кто-то мог сделать это более понятным для меня, потому что я просто хочу получить больше базовых знаний (как все это работает внутри), поэтому для меня очень важно, что я знаю, что я делаю.