Updated notes
This commit is contained in:
parent
843d1583fd
commit
ef63a126f5
2 changed files with 92 additions and 34 deletions
|
|
@ -2,43 +2,95 @@ Compaq DeskPro 386 Update
|
|||
---
|
||||
PCjs can now boot the [Compaq DeskPro 386/16 ROM BIOS](/devices/pc/bios/compaq/deskpro386/).
|
||||
|
||||
There's still a problem with the hard disk controller, which I haven't looked into yet, but
|
||||
it can be bypassed. Booting from a floppy works.
|
||||
There's still a problem with the hard disk controller, which I haven't looked into yet,
|
||||
but booting from a floppy works.
|
||||
|
||||
While working through issues with this ROM BIOS, I created some lightly-annotated
|
||||
[source code](/devices/pc/bios/compaq/deskpro386/1988-01-28.nasm) that can be re-assembled
|
||||
with [NASM](http://www.nasm.us/). The process of creating the initial source code is
|
||||
with [NASM](http://www.nasm.us/). The initial process of creating the source code is
|
||||
explained [here](/devices/pc/bios/compaq/deskpro386/#producing-rom-source-code).
|
||||
|
||||
During the debugging process, I also came across a real head-scratcher. Take a look at this code
|
||||
at F000:BCAF:
|
||||
At the top of the source code, I explain a few important details about ROM addresses that
|
||||
are worth recapping here:
|
||||
|
||||
> This 32Kb ROM image is ORG'ed at 0x8000, because most of its code is designed to run
|
||||
at real-mode addresses F000:8000 through F000:FFFF.
|
||||
|
||||
> And even though the 80386 resets with CS:IP set to F000:FFF0, the physical base address
|
||||
of CS is set to %FFFF0000, which means the ROM must also be mapped at physical addresses
|
||||
%FFFF8000 through %FFFFFFFF.
|
||||
|
||||
> Additionally, DeskPro 386 systems mirror this 32Kb ROM at real-mode address F000:0000
|
||||
through F000:7FFF. Once again, that region is mirrored at physical addresses %FFFF0000
|
||||
through %FFFF7FFFF.
|
||||
|
||||
> In other words, both 32Kb halves of the last 64Kb of both the first and last megabyte
|
||||
of the 80386's 32Gb address space are physically mapped to this ROM image.
|
||||
|
||||
> Finally, the DeskPro 386 has a "RAM Relocation" feature that allows 128Kb of RAM at
|
||||
%00FE0000 through %00FFFFFF to be mapped to %000E0000 through %000FFFFF, effectively
|
||||
replacing the ROM in the first megabyte with write-protected RAM; the top 64Kb of that
|
||||
RAM must first be initialized with the 64Kb at %000F0000 prior to remapping. It's also
|
||||
possible to copy external ROMs from %000C0000 through %000EFFFF into the bottom 64Kb of
|
||||
that RAM, but this is only done for ROMs known to contain relocatable code (eg, a Compaq
|
||||
Enhanced Video Graphics card).
|
||||
|
||||
> Every DeskPro 386 system must have a MINIMUM of 1Mb of RAM, of which either 256Kb,
|
||||
512Kb, or 640Kb can be physically mapped as conventional memory (at the bottom of the
|
||||
first megabyte), with the remainder (either 768Kb, 512Kb, or 384Kb) physically mapped
|
||||
to the top of the 16th megabyte (ending at address %00FFFFFF), the last 128Kb of which
|
||||
is used by the "RAM Relocation" feature. The remaining memory immediately below that
|
||||
128Kb (ie, below %00FE0000) can only be accessed by special system software, such as CEMM.
|
||||
|
||||
> Compaq refers to that remaining memory as "Compaq Built-in Memory".
|
||||
|
||||
So there you have it. Once the ROM has relocated itself to RAM at the top of the 16th
|
||||
megabyte, there are no less than THREE physical address ranges where ROM code and data
|
||||
structures can be accessed:
|
||||
|
||||
1. %000F0000 through %000FFFFF (aka real-mode adresses F000:0000 through F000:FFFF)
|
||||
2. %00FF0000 through %00FFFFFF (the relocated copy)
|
||||
3. %FFFF0000 through %FFFFFFFF (the physical alias of %000F0000 through %000FFFFF)
|
||||
|
||||
As you would expect, most of the ROM's code and data references are to first megabyte,
|
||||
since most of the code is designed to run in real-mode. But there are portions that
|
||||
run in protected-mode, and those portions are much less consistent about which address
|
||||
range to use -- no doubt, in part, because it makes no difference. The ROM does
|
||||
not run with paging enabled, so any physical address is as easy to access as any other.
|
||||
|
||||
Unless, of course, the A20 line is disabled. In that case, only the first range is
|
||||
accessible; the other two are not.
|
||||
|
||||
And unfortunately, I've come across a code path in the ROM that attempts to switch to
|
||||
protected-mode while the A20 line is still disabled, with the GDTR pointing to memory
|
||||
that requires A20. The result is an immediate crash. Here's the code:
|
||||
|
||||
;;
|
||||
;; Relocate the ROM and initialize conventional RAM
|
||||
;; Switch to protected-mode, relocate the ROM, switch back to real-mode, disable
|
||||
;; the A20 line, and then initialize all conventional RAM.
|
||||
;;
|
||||
call xc825 ; 0000BCAF E8730B
|
||||
|
||||
;;
|
||||
;; This function loads the GDTR with [00FF0730,0047], but since the previous call
|
||||
;; The next function loads the GDTR with [00FF0730,0047], but since the previous call
|
||||
;; disabled the A20 line, the first selector load crashes, because physical address
|
||||
;; %FF0730 requires A20.
|
||||
;;
|
||||
call xf480 ; 0000BCB2 E8CB37
|
||||
|
||||
The first call (to F000:C825) is to a long, fairly linear function that includes a call to F000:A478,
|
||||
a small function whose sole purpose is to issue an 8042 Keyboard Controller command that disables the A20
|
||||
line.
|
||||
The code at C825 is a long, fairly linear function that includes a call to A478, a small
|
||||
function whose sole purpose is to issue an 8042 Keyboard Controller command that disables
|
||||
the A20 line.
|
||||
|
||||
;;
|
||||
;; Disable A20
|
||||
;;
|
||||
call xa478 ; 0000C8B4 E8C1DB
|
||||
|
||||
After disabling A20, the function at F000:C825 then performs a series of `rep stosd` to zero all
|
||||
conventional (below 1Mb) RAM, and then it returns to the code at F000:BCB2, which in turn calls F000:F480.
|
||||
After disabling A20, the code at C825 then performs a series of `rep stosd` to zero all
|
||||
conventional (below 1Mb) RAM, and then it returns to BCB2, which in turn calls F480.
|
||||
|
||||
Here's the problem: the code at F000:F480 almost immediately attempts to enter protected-mode, which
|
||||
fails because A20 is disabled.
|
||||
The code at F480 almost immediately attempts to enter protected-mode:
|
||||
|
||||
;;
|
||||
;; When we arrive here, the A20 line has been disabled, so in theory, the GDT is
|
||||
|
|
@ -58,10 +110,10 @@ fails because A20 is disabled.
|
|||
mov cr0,eax ; 0000F4A4 0F2200
|
||||
jmp 0x28:xf4ac ; 0000F4A7 EAACF42800
|
||||
|
||||
I don't see how the above code can work. The JMP instruction will invariably fault, because the
|
||||
GDTR is pointing to memory that cannot be accessed when A20 is disabled.
|
||||
The JMP instruction will invariably fault, because the GDT is located in memory that cannot be
|
||||
accessed when A20 is disabled.
|
||||
|
||||
The code at F000:F498 is not called from any other place. It can only be reached by running the
|
||||
The code at F498 is not called from any other place. It can only be reached by running the
|
||||
preceding code which, among other things, disables A20. And there's only one branch between that
|
||||
code and the code that enters protected-mode that could possibly make any difference:
|
||||
|
||||
|
|
|
|||
|
|
@ -9,29 +9,34 @@
|
|||
;
|
||||
; Overview
|
||||
; --------
|
||||
; This 32Kb ROM image is ORG'ed at 0x8000, because it needs to run at real-mode
|
||||
; addresses F000:8000 through F000:FFFF, as well as protected-mode physical addresses
|
||||
; %FFFF8000 through %FFFFFFFF. Additionally, DeskPro 386 systems mirror this 32Kb ROM
|
||||
; at real-mode addresses F000:0000 through F000:7FFF, as well as protected-mode physical
|
||||
; addresses %FFFF0000 through %FFFF7FFF.
|
||||
; This 32Kb ROM image is ORG'ed at 0x8000, because most of its code is designed to run
|
||||
; at real-mode addresses F000:8000 through F000:FFFF.
|
||||
;
|
||||
; In other words, both 32Kb halves of the top 64Kb of both the first megabyte and the
|
||||
; 16th megabyte are physically mapped to this ROM image.
|
||||
; And even though the 80386 resets with CS:IP set to F000:FFF0, the physical base address
|
||||
; of CS is set to %FFFF0000, which means the ROM must also be mapped at physical addresses
|
||||
; %FFFF8000 through %FFFFFFFF.
|
||||
;
|
||||
; Additionally, DeskPro 386 systems mirror this 32Kb ROM at real-mode address F000:0000
|
||||
; through F000:7FFF. And that region is similarly mirrored at physical addresses %FFFF0000
|
||||
; through %FFFF7FFFF.
|
||||
;
|
||||
; In other words, both 32Kb halves of the last 64Kb of both the first and last megabyte
|
||||
; of the 80386's 32Gb address space are physically mapped to this ROM image.
|
||||
;
|
||||
; Finally, the DeskPro 386 has a "RAM Relocation" feature that allows 128Kb of RAM at
|
||||
; %FE0000 through %FFFFFF to be mapped to %0E0000 through %0FFFFF, effectively replacing
|
||||
; the ROM in the first megabyte with write-protected RAM; the top 64Kb of that RAM must
|
||||
; first be initialized with the 64Kb at %0F0000 prior to remapping. It's also possible
|
||||
; to copy external ROMs from %0C0000 through %0EFFFF into the bottom 64Kb of that RAM,
|
||||
; but this is only done for ROMs known to contain relocatable code (eg, a Compaq Enhanced
|
||||
; Video Graphics card).
|
||||
; %00FE0000 through %00FFFFFF to be mapped to %000E0000 through %000FFFFF, effectively
|
||||
; replacing the ROM in the first megabyte with write-protected RAM; the top 64Kb of that
|
||||
; RAM must first be initialized with the 64Kb at %000F0000 prior to remapping. It's also
|
||||
; possible to copy external ROMs from %000C0000 through %000EFFFF into the bottom 64Kb of
|
||||
; that RAM, but this is only done for ROMs known to contain relocatable code (eg, a Compaq
|
||||
; Enhanced Video Graphics card).
|
||||
;
|
||||
; Every DeskPro 386 system must have a MINIMUM of 1Mb of RAM, of which either 256Kb,
|
||||
; 512Kb, or 640Kb can be physically mapped as conventional memory (at the bottom of the
|
||||
; first megabyte), with the remainder (either 768Kb, 512Kb, or 384Kb) physically mapped
|
||||
; to the top of the 16th megabyte (ending at address %FFFFFF), the last 128Kb of which
|
||||
; to the top of the 16th megabyte (ending at address %00FFFFFF), the last 128Kb of which
|
||||
; is used by the "RAM Relocation" feature. The remaining memory immediately below that
|
||||
; 128Kb (ie, below %FE0000) can only be accessed by special system software, such as CEMM.
|
||||
; 128Kb (ie, below %00FE0000) can only be accessed by special system software, such as CEMM.
|
||||
;
|
||||
; Compaq refers to that remaining memory as "Compaq Built-in Memory".
|
||||
;
|
||||
|
|
@ -6626,12 +6631,13 @@ xbc71: call xa3e0 ; 0000BC71 E86CE7 '.l.'
|
|||
call xd6dd ; 0000BCAC E82E1A '...'
|
||||
|
||||
;;
|
||||
;; Relocate the ROM and initialize conventional RAM
|
||||
;; Switch to protected-mode, relocate the ROM, switch back to real-mode, disable
|
||||
;; the A20 line, and then initialize all conventional RAM.
|
||||
;;
|
||||
call xc825 ; 0000BCAF E8730B
|
||||
|
||||
;;
|
||||
;; This function loads the GDTR with [00FF0730,0047], but since the previous call
|
||||
;; The next function loads the GDTR with [00FF0730,0047], but since the previous call
|
||||
;; disabled the A20 line, the first selector load crashes, because physical address
|
||||
;; %FF0730 requires A20.
|
||||
;;
|
||||
|
|
|
|||
Loading…
Reference in a new issue