GBZ80: Что представляет собой "полуперенос"?
Процессор Game Boy Z80 имеет флаг половинного переноса, и я не могу найти много информации о том, когда его устанавливать / очищать.
До сих пор я понимаю, что любая 8-битная операция сложения, вычитания, сдвига или поворота (и, возможно, другие?) Устанавливает для нее бит 4 результата (?), И команда DAA каким-то образом устанавливает / использует это. То, что я не уверен, - то, как 16-разрядные инструкции влияют на это и влияет ли это на использование определенных регистров.
2 ответа
Это перенос с бита 3 на 4, точно так же, как обычные записи флага переноса переносятся с бита 7. Итак, например, чтобы получить половину бита переноса в добавлении:
((a&0xf) + (value&0xf))&0x10
Что дает 0x10, если половина переноса должна быть установлена, 0 в противном случае. Получение половины переноса от других соответствующих операций следует естественным образом - вопрос заключается в том, был ли переход от низкого клева к высокому.
Для сравнения: z80 имеет 4-битный ALU и выполняет 8-битные операции, выполняя две 4-битные операции. Таким образом, он получает половину переноса очень естественно, как промежуточный результат.
DAA заинтересован в флаге, потому что, если установлена половина переноса, то две цифры, которые составляют более 16, были добавлены в низком клеве; это правильно произвело перенос в верхний полубайт, но оставило нижний полубайт 6 ниже, чем должно быть, так как было еще шесть значений между 10, когда он должен был генерировать перенос, и 16, когда это было.
Для 16-битных операций перенос с бита 3 на 4 в старшем байте регистра устанавливает флаг. Другими словами, от 11 до 12.
(Обратите внимание, что вышеуказанные биты помечены 0-15, от наименее до наиболее значимого)
Смотрите здесь: http://www.z80.info/z80code.htm
16 bit arithmetic
If you want to add numbers that are more than the 0-255 that can
be stored in the A register, then the HL, IX or IY registers can
be used. Thus LD HL,1000H:LD BC,2000H:ADD HL,BC will give
A CZPSNH BC DE HL IX IY A' CZPSNH' BC' DE' HL' SP
00 000000 2000 0000 3000 0000 0000 00 000000 0000 0000 0000 0000
The flags are set as follows.
C or carry flag 1 if answer >65535 else 0
Z or zero flag not changed
P flag not changed
S or sign flag not changed
N flag 0
H or half carry flag 1 if carry from bit 11 to bit 12 else 0
Поскольку флаг полупереноса является одним из самых распространенных камней преткновения для разработчиков эмуляторов Game Boy, я позволю себе разместить ссылку на мой недавний вопрос по этой теме в качестве ответа:
Game Boy: флаг полупереноса и 16-битные инструкции (особенно код операции 0xE8)
Краткое изложение темы (ответ @gekkio):
Это зависит от инструкции, но флаги всегда обновляются на основе одних и тех же битовых позиций, если вы думаете в терминах 8-битных значений... это просто варьируется, говорим ли мы о старшем или младшем байте 16-битного ценность. Бит 11 - это просто 3-й бит старшего байта.
ADD SP, e
: H из бита 3, C из бита 7 (флаги из младшего байта op)LD HL, SP+e
: H из бита 3, C из бита 7 (флаги из младшего байта op)ADD HL, rr
: H из бита 11, C из бита 15 (флаги из старшего байта op)INC rr
: нет обновлений флагов (выполняется 16-битным устройством увеличения / уменьшения)DEC rr
: нет обновлений флагов (выполняется 16-битным устройством увеличения / уменьшения)