3 ms·
Let's suppose your PC system ROM was 64 KiB F000:0000 to F000:FFFF (F0000 to FFFFF linear). If it wasn't a 286 or higher, then it couldn't simply use protected<
by 1letterunixname 4y ago
Let's suppose your PC system ROM was 64 KiB F000:0000 to F000:FFFF (F0000 to FFFFF linear). If it wasn't a 286 or higher, then it couldn't simply use protected<->real-mode virtual memory tricks to copy ROMs and remap memory pages. Instead, there would need to be a motherboard-assisted hardware mechanism to redirect the decoding of the top 4 bits matching 1111 from ROM to copy to and steal some RAM. It would probably be easiest to do this at boot (during POST) by temporarily mapping future shadow ROM (RAM) to RAM, copy the ROM->RAM, and then remap that RAM over the ROM. Let's borrow A000:0000 since we're in text mode 0x3 using 4 KiB of the EGA/VGA frame buffer at B800:0000 and assume there's no other adapter configured to use this area.
; copy 64 KiB from F000:0000 -> A000:0000
; registered not saved: AX CX SI DI
; registered saved: CS DS ES FLAGS
; 12 bytes of stack required
PUSH DS
PUSH ES
PUSHF
CLD ; technically, this isn't needed
; we're copying all 64 KiB and
; could wrap backwards
MOV AX, F000h
XOR SI, SI
MOV DS, AX
MOV AX, A000h
XOR DI, DI
MOV ES, AX
MOV CX, 8000h ; 64 KiB / (sizeof(word) == 2)
REP MOVSW ; DS:[SI] -> ES:[DI]
; 16 bits at a time until CX == 0
POPF
POP ES
POP DS
segment:offset addressing in real-mode
linear address = segment * 16 + offset
With the exception of some memory areas are mapped only by hardware decoding the segment but not the offset to where reads beyond offset FFF0 wrap around instead of pointing to adjacent memory.
AC00:FFFF (BBFFFh linearly) != B000:BFFF
There are variations of real mode on 286+ that use linear flat addressing outside of protected mode (it would be 16 MiB for 286 and 386SX, and 4 GiB max for 386+) by messing with the hidden masks of the segment registers by switching to protected mode temporarily. The downside is all of the system provided (ROM) real-mode interrupt handlers, OS, and drivers would need to be rewritten for this different addressing scheme. It's called unreal mode. Hypothetically, you could algorithmically transpile ROM code by parsing instructions and rewriting them. Real-mode interrupt handlers are stored in a table of 256 far pointers at 0000:0000 to 0000:03FFF.
- rep_lodsb 4y agoThe term Shadow RAM comes from the fact that it is at the same address as ROM, "shadowing" it. Compaq's implementation was somewhat complicated. The more typical solution, for example with the C&T chipset, was to have all RAM be contiguous, leaving some parts of it unusable since it would overlap with the area reserved for ROMs, video memory and possibly other hardware. If you only had 1 MB in total and wanted extended memory, there was the option to remap the extra 384K high, but then it could not be used to speed up ROM access. With more than 1 MB, that option wasn't provided by C&T since it made the memory mapping hardware simpler. A control register in the chipset is used to direct only write accesses to RAM, while reads would still go to the ROM - so the BIOS code can copy itself by reading and then writing the same address range (DS:SI = ES:DI). Setting a different value in the control register would then enable read access to the RAM, while also write-protecting it. Also, unreal mode requires a 386+. You couldn't switch the 286 back to real mode except via reset(*), and it wouldn't be able to use linear addresses anyway since the registers were still 16 bit :) What was possible is to use LOADALL (0F 05) in order to set up the segment descriptor caches to address high memory. This is similar to how after reset, the code segment has a base address of FF0000, at the top of the 286's 16 MiB address space. When a segment register is reloaded, the base address is again set to the 8086 compatible value (segment * 16). (*) there is an undocumented instruction (STOREALL, 0F 04) that is capable of leaving protected mode. However it also enters a special "real mode" that would later become SMM, in which the CPU uses alternate bus control pins. On the chips that you could buy from Intel/AMD, these only existed as unbonded test pads on the die.