In this article I shall refer to numbers in two ways.
One way is to specify the number in decimal, just by stating it. Eg: 1024.
The other way is to specify the number in hexadecimal. I shall use the convention of preceding every hex number with 0x. Eg: 0xF = 15.
Other writers use the convention of appending an 'h' or an 'H' to hex numbers. Thus FH = Fh = 15.
1 Kb = 1 Kilobyte = 1024 bytes. 1 Mb = 1 Megabyte = 1024 * 1 Kb = 1,048,576 bytes. 1 Gb = 1 Gigabyte = 1024 * 1 Mb = heaps.
Floppy disk sizes (that is, available space):
360 Kb = 362,496 bytes. 720 Kb = 730,112 bytes. 1.2 Mb = 1,213,592 bytes. 1.44 Mb = 1,457,664 bytes.
What does this number really mean? Well, the Segment and Offset parts are added by shifting the Segment left one (hex) digit and then adding the Offset, thus:
0x9FFF0 + 0x 000F = 0x9FFFF = 655,359
Now, 0 to 655,359 is the same as 1 to 655,360. That is, 1 to 640 Kb. Lo and behold! The infamous 640 Kb DOS memory limit consists of memory addresses from 0 to 655,359, that is, 0 to 0x9FFF:000F.
Another example: 1 Mb of memory occupies addresses from 0 to 0xFFFF:000F. That is, since 1 Mb = 1,048,576, 0 to
0xFFFF0 + 0x 000F = 0xFFFFF = 1,048,575
Note also that a memory address can be written in many equivalent ways. 0x000F:0045 = 0x0010:0035 = 0x0011:0025 = 0x0013:0005.
Let's see what these mean:
0x00130 + 0x 0005 = 0x00135 = 309
0x000F0 + 0x 0045 = 0x00135 = 309
That is, all represent physical address 309. By convention, when the Offset part is from 0 to 0xF the address is said to be Normalized. Thus 0x0013:0005 is Normalized, whereas the other forms aren't.
0xFFFF = 65535 0xFF = 255
Since 0xFF = 255, then 0 to 0xFF = 0 to 255. Now, in 0 to 255 there are 256 different values, which is precisely how many different values can be represented in 8 bits. And 8 bits is a byte!
So all values from 0 to 0xFF can be stored in 1 byte, and all values from 0 to 0xFFFF can be stored in 2 bytes (1 word on some machines. Some machines use 4 bytes per word).
Consequently, it takes 2 bytes to hold a Segment part and 2 bytes to hold an Offset part.
Finally then, it takes 4 bytes to hold a complete memory address of the form Segment:Offset.
1 Mb = 0x10000:0000
1 Mb-1 = 0xFFFF:000F End System BIOS area 960 Kb 0xF000:0000 | = 128 Kb 896 Kb 0xE000:0000 Start System BIOS area
896 Kb-1 = 0xDFFF:000F End Expansion card BIOS area 832 Kb 0xD000:0000 | = 128 Kb 768 Kb 0xC000:0000 Start Expansion card BIOS area
768 Kb-1 = 0xBFFF:000F End Video RAM 704 Kb 0xB000:0000 | = 128 Kb 640 Kb 0xA000:0000 Start Video RAM
640 Kb-1 = 0x9FFF:000F End DOS RAM 576 Kb 0x9000:0000 | 512 Kb 0x8000:0000 | 448 Kb 0x7000:0000 | 384 Kb 0x6000:0000 | 320 Kb 0x5000:0000 | = 640 Kb 256 Kb 0x4000:0000 | 192 Kb 0x3000:0000 | 128 Kb 0x2000:0000 | 64 Kb 0x1000:0000 | 0 Kb 0x0000:0000 Start DOS RAM
When such a chip is put in a PC it is read-only because the design of the PC ensures such high currents do not appear on the chip's input lines, except during a catastrophe!
In contradistinction to the English saying 'crash-and-burn', this programming technique is called 'burn-and-crash'. First you burn the program into the chip. Then you run the program and it crashes...
This BIOS is a feature of Intel microprocessors, rather than of DOS. See p 68 of The MS-DOS Encyclopedia.
When the computer starts running the microprocessor automatically begins executing code at 0xFFFF:0000. It does this by setting the Code Segment (CS) register to segment 0xFFFF, and the Instruction Pointer (IP) register to 0x0000.
Thus CS:IP points to (contains) 0xFFFF:0000, and it is from this address that the CPU takes the next instruction to be executed.
This instruction is usually a jump to the BIOS's initialization code, after which the code scans bootable drives looking for a copy of DOS (or some other operating system) to load and run.
ROM BIOS Extensions are sometimes called Supplementary ROM support.
These ROM BIOS Extensions are executed at boot time because the one true ROM BIOS scans memory addresses from 0xC000:0000 to 0xE800:0000 (or, says the MS-DOS Encyclopedia, from 0xA000:0000 to 0xF000:0000) in 2 Kb jumps, looking for signature bytes. These bytes, 0x55 0xAA I believe, indicate code is lurking at that address, waiting to be executed.
When the BIOS code sees the signature it jumps to that address (or maybe just beyond it), and the code is executed. This gives the ROM BIOS Extension the chance the strut its stuff. Most likely it will do two things: (1) Execute initialization code, and (2) store into DOS's Interrupt Table the address of its Strategy Routine - that is the code to which DOS is to jump when an interrupt of the appropriate type occurs.
You can look for this signature using Debug as follows. The '-' below is Debug's prompt. The 'd' means dump (i.e. display) memory starting from the given address. The 'q' means quit. Each line is terminated with an <Enter>. This process is quite safe.
Warning. Hex numbers in Debug do not have 0x signs.
C:\>debug -d C000:0 -d C800:0 -q
The output looks like:
C000:0000 55 AA ... C000:0010 AB CD ...
This means Segment 0xC000 is being dumped. The first line consists of bytes whose Offsets are 0x0000 to 0x000F (0 to 15). The second consists of bytes 0x0010 to 0x001F (16 to 31).
Debug always puts a '-' in the middle of the line.
Alternately, run the Norton utility SI - System Information.
Another example: At 0xFFFF:000E is the machine ID byte. If you examine this byte you might find one of these values:
Value Machine 0xFF PC 0xFE XT 0xFD PC jr 0xFC AT 0xFB XT/2 0xFA PS/2 model 30 0xF9 Convertible 0xF8 PS/2 model 80
C:\>debug -d FFFF:0 -q
The output looks like:
FFFF:0000 EA 5B E0 00 F0 30 31 2F-31 35 2F 38 38 FF FC 00 .[...01/15/88...
30 31 2F 31 35 2F 38 38 is just 01/15/88, i.e. a date in Month/Day/Year format.
Further, since this line is bytes 0x0000 to 0x000F, the second last is byte 0x000E, i.e. 0xFFFF:000E. You can see its value is 0xFC. Thus the machine is an AT.
Given a lot of other information which I'll skip, it is possible to determine the machine sub-model. Eg: there are three (3) types of XTs, not counting the PS/2 pseudo-XTs.
CMOS is only present in AT class machines. Earlier machines, PCs and XTs, don't have it.
This type of RAM consumes an extremely small amount of power. The data in it is preserved, when the machine's power is off, by torch-style batteries.
CMOS holds certain configuration data describing the machine's hardware, as well as the date and time.
CMOS normally consists of just 64 bytes.
Many AT class machines come with a program called SETUP which allows you to read and write the values in CMOS. In some machines this program is not on disk, but in ROM. During the POST the checksum of the CMOS is calculated, and if the calculated value does not match the value stored in CMOS the SETUP program is run, or at least a message appears giving you a choice of running it or ignoring the error.
Of course, given the format of the CMOS memory and the format of the read and write commands required, you can access this memory with your own program.
This Conventional Memory is directly addressable by an Intel microprocessor (running DOS, say, in Real Mode).
In fact, machines which are alleged to come with only 640 Kb of RAM will always comes with at least some memory in the range 640 Kb to 1 Mb. After all, they need Video RAM (at 0xA000:0000) to use a screen, and all 8086/8088-compatible microprocessors will have a BIOS (at 0xF000:0000).
DOS and other programs occupy the region 0 to 640 Kb.
If the machine has only 512 Kb, a gap exists from 512 Kb to 640 Kb. However, there will still be some memory above 640 Kb, as stated above.
In other words, memory need not be contiguous. There can be gaps in it, meaning there literally is no memory at certain addresses (address ranges).
In fact, IBM generously delivered my AT with a whopping 128 Kb of Conventional Memory! That's why I bought an Extended Memory card... The latter has 2 Mb on it, 512 Kb of which is used to 'backfill' Conventional Memory up to 640 Kb (128 + 512), while the other 1536 Kb (2048 - 512) is used for a RAM disk.
Remember, it takes 4 bytes to hold a memory address of the form Segment:Offset.
Each 4-byte address is called an interrupt vector, and is allocated to an interrupt of a specific type.
When an interrupt occurs, the CPU saves the state of the machine and jumps to the corresponding interrupt address. The code pointed to is a Strategy Routine which handles its own interrupt and returns. The CPU restores the state of the machine and continues executing the interrupted program.
Eg: every time a key is pressed or released, interrupt 0x09 is triggered. That is, the CPU jumps to the address stored in bytes 0x24 to 0x27.
Various programs (the BIOS, ROM BIOS Extensions and user programs) store addresses into this first 1 Kb. By doing so they announce they will handle interrupts of the type whose address they have changed to point to themselves. This process is called 'hooking an interrupt'.
Let's take the case of a non-BIOS program. Eg: we might write a program such that when a particular key is hit, the program 'pops-up'.
From the program's point of view, here's what happens:
1. The program is written in such a way that part of it is a Strategy Routine for a given interrupt. 2. The program is run by the user. 3. While running, the program determines the address in memory of its Strategy Routine. 4. The program stores this address in the interrupt vector table, at the address corresponding to key-stroke interrupts. 5. The program jumps into DOS via interrupt 0x21, and requests DOS that it, the program, Terminate-and-Stay-Resident (TSR). 6. Thereafter, whenever the user hits a key, the key-stroke interrupt is executed. The Strategy Routine examines the key-stroke and decides whether or not to pop-up.
In reality, we wouldn't hook interrupt 0x09, which is executed twice per key-stroke (press, release). We'd hook interrupt 0x16, which is executed every time a complete key-stroke is available in the BIOS's key-board buffer.
Since DOS was not designed to cleanly support such manoeuvres, such programming is fraught with difficulties...
It is memory beyond the 1 Mb boundary. That is, its physical address starts at 1 Mb. There can be up to 15 Mb of Extended Memory.
It is only addressed by a 286/386 processor running in Protected Mode. Since DOS runs in Real Mode, it (DOS) cannot directly address Extended Memory, let alone execute code residing in the latter. However, some software can access this memory.
In fact, there are several ways to access it.
1. Use a DOS program like VDISK or RAMDRIVE to treat the memory as a RAM disk. 2. Use certain DOS functions to transfer blocks of data between Conventional Memory and Extended Memory. 3. Use an Extended Memory Manager written to the Extended Memory Specification. These have names like HIMEM.SYS, 386^MAX, QEMM...
IBM ATs come with a diagnostic floppy. Booting from this enables you to store and change values in CMOS.
When specifying the amount of Extended Memory in your machine, you do it when the SETUP program asks for Expansion Memory.
Clear? I'm so glad.
By the way, this SETUP program has a menu choice for copying floppies. You must use it to copy the diagnostics floppy itself. If you use DISKCOPY to copy the diagnostics floppy, there are no error messages, but the resultant copy will not boot.
Access to it is via the EMS, a hardware and software combination to circumvent the 1 Mb addressing limit of the Intel processors operating in Real Mode. I'll refer to it as EMS Memory. The software is called an Expanded Memory Manager (EMM).
There can be up to 8 Mb of EMS Memory.
It's physical address doesn't sit beyond the 1 Mb boundary. In fact, it doesn't sit anywhere. This is explained in LIM 3.2 below.
EMS is now taken to mean EMS 4.0.
It allows programs to map (utilize) pages of Expanded Memory, each of 16 Kb. At most, 4 such pages can be mapped at once.
Mapping means the pages have their addresses fiddled so that they look like they reside in the address range 640 Kb to 1 Mb. This in turn means they are accessible by DOS, but cannot reside in the lower 640 Kb address range.
It allows programs to map up to 64 pages at a time. Pages can be mapped into the address range 0 Kb to 1 Mb.
Some PC memory expansion cards contain hardware support for EMS 4.0, as well as the memory chips themselves, and thus this memory is absolutely Expanded Memory. However, an EMS Manager can make some or all of it look like Extended Memory.
Some expansion cards don't have this hardware support, and thus the memory is absolutely Extended Memory. However, an EMS Manager can make some or all of it look like Expanded Memory.
Lastly, a few early expansion cards had hardware support for only 4 pages of Expanded Memory, not 64 pages, and thus don't fit the definition of EMS 4.0. At the worst they are misrepresented as being EMS 4.0 compatible. They aren't.
Now, does it matter? Yes, but first another detour.
These values do not include Expanded Memory with hardware support.
These values do include Extended Memory made to look like Expanded Memory by an EMS Manager.
Don't forget, at the time of the POST the EMS Manager has not yet started running. After the POST, DOS will be loaded and CONFIG.SYS will be processed. A command in CONFIG.SYS will load the EMS Manager.
Going back to the POST, memory will be of three types:
- Conventional Memory. - Expanded Memory forced to look like Expanded Memory by the presence of hardware support. - Extended Memory, i.e. everything else.
Eg: DOS might tell you Total Extended Memory is 0, because an XMS Manager is installed.
On the other hand, getting Physical Extended Memory from CMOS is not definitive, because an EMS Manager might be supplying extra Extended Memory out of Expanded Memory.
The 286/386/486 series can run in Real or Protected Mode.
Now, what do these Modes mean?
In short, very short, I'll just say: Be aware that in Protected Mode the microprocessor can execute certain privileged instructions not available in Real Mode. In other words the chip is more powerful in Protected Mode than in Real Mode.
This begs the question: Why manufacture a chip like this?
The simple answer is that many years ago when the 8086/8088s were being designed, chip fabrication technology was only good enough to allow Real Mode chips to be manufactured. Don't forget the design constraints of simplicity and an incredibly cheap retail price.
The real answer is that at first technology restricted the sophistication of the chip, for sure, but later new technology enabled a chip to be manufactured whose design (Real/Protected Mode) modelled the human brain (Conscious/Unconscious Mode).
Similarly, humans create institutions which also model the brain. Take democracy for example.
It is implemented with two Houses of Parliament:
State Real Protected Victoria Legislative Council Legislative Assembly Australia Senate House of Representatives England House of Lords House of Commons America Congress House of Representatives - Brain Conscious Unconscious Literature Dr. Jekyll Mr. Hyde (hide, get it?)
This arrangement contrasts nicely with that pertaining in a dictatorship...
0x0000:0000 to 0x9FFF:000F = 640 Kb of DOS RAM. 0xB800:0000 to 0xBFFF:000F = 32 Kb of Video RAM. 0xC000:0000 to 0xC9FF:000F = 32 Kb of Video (EGA/VGA) BIOS, that is, a ROM BIOS Extension. 0xCA00:0000 to 0xCFFF:000F = 32 Kb of Floppy controller card BIOS, that is, a ROM BIOS Extension.
Note 1: The Video BIOS and Floppy controller card BIOS are not really exactly 32 Kb long.
Note 2: Using Debug to dump memory, I see that printable text (displayed during booting) in the Floppy controller card BIOS actually starts at 0xC9EF:0378.
0x0000:0000 to 0x9FFF:000F = 640 Kb of DOS RAM. 0xB800:0000 to 0xBFFF:000F = 32 Kb of Video RAM. 0xC000:0000 to 0xC9FF:000F = 32 Kb of Video (VGA) BIOS.
Home page: http://savage.net.au/index.html
This version disguises my email address.
Australian Copyright © 2002 Ron Savage. All rights reserved.
All Programs of mine are 'OSI Certified Open Source Software'; you can redistribute them and/or modify them under the terms of The Artistic License, a copy of which is available at: http://www.opensource.org/licenses/index.html