For 8088 and up, that mapping could be done within the CPU since 8088 and up has 24 bit addressing.
You are mistaken, and probably mean 80386.
The 8088 was the same cpu (and timeframe) as the original 8086, and had a 1M address space (in fact, it was the 8088 that was used in the original IBM PC.)
The 80286 had 24bit (physical) addresses, but it had a really awful MMU organization that made it hard to use. (IIRC, "segment numbers" were put IN THE MIDDLE of an address, right about the time that everyone was agreeing that segments were dead and pages were the future.)
You are right on the 1MB address space (2^20), the nightmares!!! It was all segmented in 64KB linear address spaces and it was a real PITA.
But even so, the 640KB limit could be changed to 704KB if there was memory present between the video card and the ram. I still have the code to switch it (not my code might be borlands or masm sample)
PAGE ,132
TITLE 704K - set memory to 704K bytes
COMMENT *
Increase memory to 704K bytes by changing
BIOS data word at 40:13 hex
Set new memory to zero
April 14,1987
*
INCLUDE mylib.equ
IF1
INCLUDE mylib.mac
ENDIF
old_siz EQU 640 ;old mem size
new_siz EQU 704 ;new mem size
new_seg EQU 0A000h ;704K segment
; BIOS data area
bios_d SEGMENT AT 40h
ORG 13h
mem_siz LABEL WORD ;memory size
bios_d ENDS
code SEGMENT
ASSUME CS:code, DS:code, ES:bios_d
ORG 100h
strt:
@head ' MEM704,04.14.87 '
; point to memory size in BIOS data area
MOV AX,bios_d ;zero
MOV ES,AX
MOV SI,OFFSET mem_siz
; check if already run
CMP WORD PTR ES:[SI],new_siz
JNE ok
@go_dos ;quit
; check for memory at A000 hex
ok:
MOV BX,ES ;save ES
MOV AX,new_seg
MOV ES,AX ;ES=A000
XOR DI,DI ;offset
MOV ES:[DI],AH ;55 hex
CMP AH,ES:[DI] ;ok?
JNZ no_mem ;no
MOV ES:[DI],AL ;AA hex
CMP AL,ES:[DI] ;ok?
JNZ no_mem ;no
; set memory size for 704K bytes
MOV CX,ES ;save ES
MOV ES,BX ;ES=40
MOV WORD PTR ES:[SI],new_siz
MOV ES,CX ;ES=A000
; fill new memory with zeros
XOR AX,AX ;zero word
MOV DI,AX ;zero location
MOV CX,8000h ;32K words
REP STOSW ;do it
@write <' Memory now 704K bytes',cr,lf>
INT 19h ;reboot system
; no memoty at A000 hex, terminate without change
no_mem:
@write 'no memory at A000 hex, aborting'
@go_dos
code ENDS
END strt
Edit: but that was IBM's implementation not sure if you could change the memory architecture to increase the number of segments, will have to look it up if the segments could be changed to go from 20 bit address space to 24 bits, but the PC used 20 bits total after segmentation.
Edit answer: after a short research, it couldn't go past 20 bits address space so 1MB was the limit with the rom living on the higher area. (and yes, I have the complete disassemble of the original IBM Rom in some binder in my office)
Edit2: apparently that code came from Byte Magazine but it mentions 1986 mine says 1987.
https://archive.org/stream/198610ByteMagazineVol1111InsideTheIBMPC/198610%20Byte%20Magazine%20Vol%2011-11%20Inside%20the%20IBM%20PC_djvu.txt#BYTE 1 986 Extra Edition • Inside the IBM PCsIsn't google wonderful that you can look for code that is older than the internet?
But back to topic, unless you don't have physical address pins that you can segment and combine with the standard address spaces using multiplexers to get to the right banks you can't go over the limit.
And that doesn't take into account code and data prefetching because the fabric of the processor might not allow you to use some io pins to multiplex external chip selects to increase memory but I have not look at the datasheet to see if the XMega has prefetching built in and what the implications are for the toolchain etc.