Отвечаю поздновато, но, возможно, ответ поможет.
Keil вполне корректно моделирует внешнюю память (по крайней мере uVision3, с которым я работал долго), причём как при обращении по 16-разрядным адресам, так и по 8-разрядным. При отладке следует иметь в виду, что если внешняя память подключена к 16-разрядной шине адреса (а Keil считает именно так для классического 8051), то физический адрес будет в любом случае 16-разрядным. Если использовать команды типа movx a,@DPTR, то этот адрес полностью находится в DPTR. Если же используются команды типа movx a,@R0, то младший байт адреса берётся из R0, а старший - из P2 (т.е.
текущее содержимое P2).
Следовательно, при выполнении команд
Код
mov P2,#20h
mov r0,#33h
movx a,@r0
байт считается из ячейки с адресом 2033h, а если потом сделать так:
Код
mov P2,#40h
movx a,@r0
то чтение произойдёт уже из ячейки 4033h.
Аналогично работает и запись в XRAM.
Таким образом, при просмотре ячеек в окне Memory Window нужно указывать адрес с учетом старшего байта, соответствующего
текущему содержимому P2.
Следует отметить что команды типа movx a,@DPTR не изменяют содержимое P2 (точнее - изменяют лишь на время своего выполнения, а затем восстанавливают).
Если в Вашем устройстве старшие разряды адреса не используются, то при симуляции их всё равно придётся учитывать (по крайней мере я не знаю, как объяснить Кейлу, что они не нужны).