Meu, assim, pra acesso a memória externa no 8051 é utilizada a instrução MOVX. Aí tem os modos de endereçamento onde utiliza-se o DPTR para jogar o endereço do barramento ou então o conjunto Ri + P2. XDATA é uma diretiva, então ela não está contida em um cabeçalho, ela faz parte das palavras reservadas do compilador e serve para informar na hora da compilação que a variável em questão deve ser acessada com MOVX e não com MOV (que movimenta dados da RAM externa para o acumulador e tal.) O I/O mapeado em memória, como já falaram aqui, nada mais é do que implementar um decodificador de endereços que faz com que os sinais WR/RD sejam utilizados para acionador os sinais de controle de chips de I/O. Para o mcu, ele está utilizando MOVX e gerando o endereço e os sinais WR e RD. Qualquer livro de 8051, mais fuleiro que seja, tem lá um capitulo demonstrando isso. Um mapeamento clássico é jogar uns 74hc245 para entradas e 74hc574 para saídas. Tinha gente que utilizava o 8255, outros implementavam em um CPLD ou FPGA. A ST chegou a fabricar chipsets para 8051 que incluiam memória e alguns I/Os em um único chip.
Já vi fabricantes de CLP que utilizam 2 8051 com barramentos compartilhados deixando um dedicado pela varredura da porta da serial e barramento dos cartões e o outro rodando a aplicação, era uma da CPUs da série AL da altus...
Eu sempre sonhei em fazer um computador de 8 bits com o 8051, e sabe quando farei isso? Nunca! Pq é muito tempo investido pra retorno nenhum. É melhor estudar algo novo, mesmo por hobbiy.
A coisa mais tosca que já vi mapeada em um 8051?
Um conversor ADC com LM331 que tinha o sinal de saída feito uma AND com o clock do sistema, a saída da AND era jogada num 74hc393 que era jogado num 74hc574. A saída do contador era jogada no T0 do 8051. Então assim, tinha-se 24 bits de resolução! Não fui eu que projetei, só dava manutenção...