Определение флага переноса и переполнения в эмуляции 6502 в Java?

Я делаю эмулятор 6502, и я застрял (или я думаю, что я, по крайней мере) уже в начале (реализация операции АЦП). Проблема в том, что я должен определить, есть ли перенос или переполнение. Дело в том, что я не могу понять разницу между ними в моей реализации. Я знаю, что перенос происходит, когда после операции присутствует 9-й бит, и я знаю, что переполнение происходит, когда результат больше 255. Разве это не делает определение переноса и флага переполнения одним и тем же?

if(result > 255) { 
    carry = 1;
    overflow = 1;
} else { 
    carry = 0; 
    overflow = 0;
}

Разве это не правильно? А если нет, то что правильно и почему?


person ZimZim    schedule 30.05.2013    source источник
comment
comment
Спасибо. Я пробежался глазами, так как сейчас нет времени читать подробно, и вот что я понял. В принципе, я был прав насчет переноски. Если результат выше 255, то есть перенос. Когда есть сложение и число отрицательное, или есть вычитание и число положительное, происходит переполнение (при использовании 8-битных байтов со знаком). Это правильно, или я что-то пропустил? В любом случае, спасибо, завтра посмотрю подробнее.   -  person ZimZim    schedule 31.05.2013
comment
ИМО, если у вас нет времени читать его подробно, то у вас нет времени программировать эмулятор. Эмулятор — это все о деталях, это утомительно и отнимает много времени, нет большого пути.   -  person arcy    schedule 31.05.2013
comment
Не волнуйтесь. Было около полуночи, когда я задал этот вопрос и получил ваш ответ, т.е. я просто просмотрел статью перед сном. У меня есть время, тем более, что приближаются летние каникулы, но да, я только что упомянул об этом, потому что собирался слезть с ПК.   -  person ZimZim    schedule 31.05.2013
comment
см. также Объяснение флага переполнения (V)   -  person Core    schedule 01.06.2013


Ответы (1)


Флаг переполнения указывает, когда знак числа изменился неправильно. Таким образом, если вы добавите два положительных числа и получите отрицательный результат, произойдет переполнение. Существует также переполнение, если вы добавите два отрицательных числа и получите положительный результат.

Вы не можете получить переполнение при добавлении двух чисел с разными знаками, потому что диапазон не позволяет этого. Наименьший положительный плюс наибольший отрицательный равен 0 + (-128), что вполне подходит — 0 плюс все, что умещается в 8 бит, очевидно, уместится в 8 бит. Наименьшее отрицательное плюс наибольшее положительное равно -1 + 127 = 126. Что подходит.

(EDIT: и даже с переносом, 0 + -128 + 1 = -127, что подходит, и -1 + 127 + 1 = 127, что подходит)

Таким образом, переполнение устанавливается, если два входа с одинаковым знаком дают результат с другим знаком. Иначе понятно.

Вы можете выразить это как простую побитовую операцию над битами знака. Предположим, у вас есть a + b = c.

a ^ b

будет иметь 1 в бите знака, если знаки были разными. Вы хотите знать обратное этому. Так:

~(a ^ b)

дает 1 в бите знака, если знаки были одинаковыми. Это первая часть теста. Предположим, что a и b имеют один и тот же знак, вы можете проверить c против любого из них. На этот раз вы хотите проверить разницу, так что просто:

a ^ c

Вам нужно, чтобы проверенный бит был установлен в обеих частях теста, поэтому вы можете объединить их с двоичным файлом и (оставив много скобок для ссылки на словесное рассуждение):

(~(a ^ b))&(a ^ c)

Вам нужен только бит знака, поэтому замаскируйте его:

(~(a ^ b))&(a ^ c)&0x80

Это будет оцениваться как 0x00, если флаг переполнения должен быть очищен, и 0x80, если он должен быть установлен. Так что просто переместите это на место.

(кстати: хотя на 6502 множество инструкций устанавливает флаги и только одна выставляет регистр состояния, поэтому эмуляторы часто хранят флаги отдельно в любой удобной форме и составляют регистр состояния по требованию, и в этом случае вы не будете заморачиваться сдвигом и составлением , вы бы просто сохранили этот результат)

person Tommy    schedule 31.05.2013