Честно - я его откуда-то скопипастил в лихих 90стых, поэтому не вникал. Но много где его юзал в своих програмульках, они работали нормально. Поэтому объяснить как это работает затрудняюсь, но это точно работает на реалах.
Вид для печати
Видимо, я не совсем понимаю, как работает aad
AAD : AL = AH*x + AL ;AH = 0
И все флаги от результата AX- (SF, ZF, PF, OF, CF, AF)
Хорошо, флаги я забыл сделать, но AL=AH*x+AL именно так я и сделал. Разве что старший байт после умножения я отбросил, но ты пишешь AH=0...
---------- Post added at 17:21 ---------- Previous post was at 17:20 ----------
Есть такой вот тест, но он явно не пройдёт у меня :)
Ну я не знаю как так может быть. Вот в тесте печатает hex числа от 0 до FE.
Некоторые сорцы из эмулей:
Код:case 0xD5: /*AAD*/
tempws=FETCH();
AL=(AH*tempws)+AL;
AH=0;
setznp16(AX);
cycles-=60;
break;
Код:/* OP D5: AAD imm8 */
static
unsigned op_d5 (e8086_t *c)
{
unsigned short s1, s2, d;
unsigned short mul;
mul = c->pq[1];
s1 = e86_get_ah (c);
s2 = e86_get_al (c);
d = mul * s1 + s2;
e86_set_ax (c, d & 0xff);
e86_set_flg_szp_16 (c, d);
e86_set_clk (c, 60);
return (2);
}
Код:case 0xD5: /* D5 AAD I0 */
oper1 = getmem8 (segregs[regcs], ip);
StepIP (1);
regs.byteregs[regal] = (regs.byteregs[regah] * oper1 + regs.byteregs[regal]) & 255;
regs.byteregs[regah] = 0;
flag_szp16 (regs.byteregs[regah] * oper1 + regs.byteregs[regal]);
sf = 0;
break;
Проблема оказалась в команде aaa, забыл ah обновить. Теперь пишет как и положено - 005D.
Обновил эмулятор.
Гуд, будем копать дальше :) На всякий случай собрал тест AAD, должен выводить 3FFF. DosBox кстати неправильно работает -)
Ваш эмуль тоже не проходит тест. PCem так же не проходит. На моем Поиске выдает 3FFF, как и положено.
Также не учитывается еще одна особенность 8088/86, а именно:
Уйдет на выполнение @Not_8086. Разница в том, что 86 в стек записывает уже отнятое значение сегмента стека SP-2, а 286 и дальше - нет:Код:push sp ; save SP on stack to look at
pop bx ; get SP saved on stack
cmp bx,sp ; if 8086/8088, these values will differ
jz short @Not_8086 ; nope, must be other CPU type
ret
@Not_8086:
Из-за этого вполне может не выдавать Info о системе pctools, например...Код:; 8086/80186 80286+
; { {
; SP = SP - 2 TEMP = SP
; SS:SP = SP SP = SP - 2
; } SS:SP = TEMP
; }
Так же интересно, почему если в качестве биос подсунуть некий тест, эмуль вообще падает по ексепшену. Тест div.bin, там устанавливается вектор прерывания int 00h, далее в коде происходит деление на ноль. Должно сгенерироваться int 0, но где-то тут наверно происходит крах системы -) В то же время, подобный тест sub.bin отрабатывает без ошибок. Правда в нем нет никаких обработчиков прерываний. Файлы res_div.bin и res_sub.bin содержат эталонные значения, с которыми можно сравнить содержимое памяти начиная с 0000:0000. В случае sub.bin все верно, ну кроме старших бит во флагах, но это так и должно быть. А вот с div.bin непонятно, так как эмуль падает.
С умножением похоже нелады во флагах после операций. И это не только старшие биты. Запускать вместо BIOS, потом сравнить память с res_mul.bin Флаги это важно, возможно checkit из-за этого падает с math-error