Home

IBM 5150  -  10/27/82 BIOS  -  Problem of less than 4 banks of RAM


IBM documentation on the IBM 5150 does not indicate a requirement for 4 banks of motherboard RAM. However, with the 10/27/82 revision BIOS fitted to either the 16KB-64KB or 64KB-256KB versions of the 5150 motherboard, it will be found that 4 banks are required, else problems result.

If chip U33 on the 5150 motherboard has "1501476" printed on it, then the BIOS is the 10/27/82 revision.

The problems are the result of two bugs.
The first bug affects only the 64KB-256KB version of the 5150 motherboard.
The second bug affects both the 16KB-64KB and 64KB-256KB versions of the 5150 motherboard.


------------------------------------------------------------------------------------------

Bug #1

This is a bug in the 10/27/82 revision of the 5150 BIOS, and this particular bug affects only the 64KB-256KB version of the 5150 motherboard.

The bug appears to come about because much code was copied from the early BIOS, as used on 16KB-64KB motherboards (4 banks of 16 KB RAM), and inadequate testing done to verify that the code worked fully (repeat: fully) on the 64KB-256KB motherboard (4 banks of 64 KB RAM).


Reference

BIOS source listing in the APR84 edition of the 5150 Technical Reference


Symptoms

When less than 4 banks of motherboard RAM are selected, the bug results in the BIOS reporting much less RAM than it should.

Motherboard banks
selected via SW1
RAM in
expansion cards
SW2
setting
RAM total
reported by BIOS
     Comment
0   (64 KB)  
N/A
  64 KB
16 KB
 BAD - Should be 64 KB      (1 x 64 KB bank)
0/1   (128 KB)
N/A
128 KB
32 KB
 BAD - Should be 128 KB    (2 x 64 KB bank)
0/1/2   (192 KB)
N/A
192 KB
48 KB
 BAD - Should be 192 KB    (3 x 64 KB bank)
0/1/2/3   (256 KB)
  0 KB
256 KB
256 KB
 GOOD         (4 x 64 KB bank)
0/1/2/3   (256 KB)
64 KB
320 KB
320 KB
 GOOD         ([4 x 64 KB bank] + 64 KB)
0/1/2/3   (256 KB)
128 KB
384 KB
384 KB
 GOOD         ([4 x 64 KB bank] + 128 KB)

IBM DOS 3.3 has a problem with that. When I set my 5150 to banks 0/1/2, and I try to boot from either hard drive (IBM DOS 3.3) or boot floppy (IBM DOS 3.3), the floppy drive A: light comes on and stays on.


Where did I get the 'RAM total reported by BIOS' figures above?

The 5150 BIOS/POST stores the total amount of RAM (in KB) that it detected into the BIOS Data Area (BDA), specifically the word (little endian) at 0040:0013.
One way to read that amount is to:
1. Get into BASIC by removing any hard drive, and then boot without a boot floppy, then
2. In BASIC, enter the following:
   def seg = &h40
   print peek(&h14)*256 + peek(&h13)


Where in the code is the bug?

The block of code causing the problem is on page 5-42 of the reference, specifically lines 934 to 951. That block calculates the total KB amount of RAM (motherboard + expansion cards) and then stores the amount in the BDA.

You can see that the block I'm referring to is divided in to 2 sections: "DETERMINE RAM SIZE ON PLANAR BOARD" and "DETERMINE I0 CHANNEL RAM SIZE". Those descriptions are correct for a 16KB-64KB motherboard, but not a 64KB-256KB motherboard.

DETERMINE RAM SIZE ON PLANAR BOARD

Lines 935 to 941. This section of the block examines switches 3 and 4 on SW1. Irrespective of whether the 10/27/82 BIOS is on a 16KB-64KB motherboard or on a 64KB-256KB motherboard, the output of that section is always the same:
SW1-3 on / SW1-4 on (i.e. bank 0) - results in register BX containing 16 (0010h).
SW1-3 off / SW1-4 on (i.e. banks 0/1) - results in register BX containing 32 (0020h).
SW1-3 on / SW1-4 off (i.e. banks 0/1/2) - results in register BX containing 48 (0030h).
SW1-3 off / SW1-4 off (i.e. banks 0/1/2/3) - results in register BX containing 64 (0040h).

DETERMINE I0 CHANNEL RAM SIZE

Lines 945 to 951.

The first thing that this bit of code does (at line 945) is fetches the "IO_RAM_SIZE" value was calculated (based on SW-2 setting) and stored earlier (page 3-37). IO_RAM_SIZE contains the amount of RAM past 64 KB. On a 16KB-64KB motherboard, that corresponds to the amount of IO RAM (RAM on IO expansion cards), and so on that motherboard, "IO_RAM_SIZE" is an accurate description. But on a 64KB-256KB motherboard, "IO_RAM_SIZE" is an incorrect description. It is best to think of "IO_RAM_SIZE" as RAM past 64 KB.

Putting it altogether (lines 935 to 951), we end up with:

Motherboard banks
selected via SW1
RAM in
expansion cards
SW2
setting
BX
register
BX = 0040h ?
IO_RAM_SIZE
(KB RAM past 64)
 Calculated RAM total (MEMORY_SIZE)
0   (64 KB)  
N/A
  64 KB
16  (0010h)
No
not relevant
 16 + 0 = 16 KB        ( BX + 0 , because BX not 0040h )
0/1   (128 KB)
N/A
128 KB
32  (0020h)
No
not relevant
 32 + 0 = 32 KB        ( BX + 0 , because BX not 0040h )
0/1/2   (192 KB)
N/A
192 KB
48  (0030h)
No
not relevant
 48 + 0 = 48 KB        ( BX + 0 , because BX not 0040h )
0/1/2/3   (256 KB)
  0 KB
256 KB
64  (0040h)
Yes
192  (00C0h)
 64 + 192 = 256 KB        ( BX + IO_RAM_SIZE )
0/1/2/3   (256 KB)
 64 KB
320 KB
64  (0040h)
Yes
256  (0100h)
 64 + 256 = 320 KB        ( BX + IO_RAM_SIZE )
0/1/2/3   (256 KB)
128 KB
384 KB
64  (0040h)
Yes
320  (0140h)
 64 + 320 = 384 KB        ( BX + IO_RAM_SIZE )




------------------------------------------------------------------------------------------

Bug #2

This is a bug in the 10/27/82 revision of the 5150 BIOS.
This particular bug affects both the 16KB-64KB 5150 motherboard (if the 10/27/82 BIOS is fitted) and the 64KB-256KB 5150 motherboard.


Reference

BIOS source listing in the APR84 edition of the 5150 Technical Reference


Symptoms

Mostly, when less than 4 banks of motherboard RAM are selected via SW1/SW2, a 201 error (RAM error) is seen on screen.

Why did I use "mostly"?
Here is an example. 64KB-256KB motherboard.
SW1 and SW2 set for 1 bank of RAM only (64K), and only 1 bank is physically fitted - 201 error seen.
SW1 and SW2 set for 1 bank of RAM only (64K), but 4 banks are physically fitted - 201 error not seen.


Why?

Because of a bug, if less than 4 banks of motherboard RAM are selected via SW1/SW2, then the portion of the POST that does a data test of the RAM thinks that there is a lot more RAM fitted than indicated by SW1/SW2.
Here are some examples for a 64KB-256KB motherboard:

Motherboard banks
selected via SW1
RAM in
expansion cards
SW2
setting
RAM test routine thinks this much RAM exists
     Comment
0   (64 KB)  
N/A
  64 KB
192 KB
 BAD  -  128K more than actually exists
0/1   (128 KB)
N/A
128 KB
384 KB
 BAD  -  256K more than actually exists
0/1/2   (192 KB)
N/A
192 KB
448 KB
 BAD  -  256K more than actually exists
0/1/2/3   (256 KB)
  0 KB
256 KB
256 KB
 GOOD
0/1/2/3   (256 KB)
64 KB
320 KB
320 KB
 GOOD
0/1/2/3   (256 KB)
128 KB
384 KB
384 KB
 GOOD


Where in the code is the bug?

The block of code causing the problem is on page 5-37 of the reference, specifically lines 525 to 539, which is the majority of the section named "DETERMINE I0 CHANNEL RAM SIZE". The block is calculating something known as "IO_RAM_SIZE", and as explained in BUG #1, IO_RAM_SIZE is the amount of RAM past 64 KB.

This block is a modified form of the one in the earlier BIOS. It is modified because this BIOS now reads switches #1 to #5 on SW2. The earlier revisions of BIOS only went as high as switch #4. In modifying the code, the programmer has introduced a bug. The bug results in wrong values of IO_RAM_SIZE being calculated when less than 4 banks of motherboard RAM are selected via SW1/SW2.

Here are some examples for a 64KB-256KB motherboard:

Motherboard banks
selected via SW1
RAM in
expansion cards
SW2
setting
IO_RAM_SIZE
(KB RAM past 64)
RAM test routine thinks this much RAM exists
     Comment
0   (64 KB)  
N/A
  64 KB
128 KB
128 + 64 = 192 KB
 BAD
0/1   (128 KB)
N/A
128 KB
320 KB
320 + 64 = 384 KB
 BAD
0/1/2   (192 KB)
N/A
192 KB
384 KB
384 + 64 = 448 KB
 BAD
0/1/2/3   (256 KB)
  0 KB
256 KB
192 KB
192 + 64 = 256 KB
 GOOD
0/1/2/3   (256 KB)
64 KB
320 KB
256 KB
256 + 64 = 320 KB
 GOOD
0/1/2/3   (256 KB)
128 KB
384 KB
320 KB
320 + 64 = 384 KB
 GOOD

By the way. It is relatively easy for you to see the IO_RAM_SIZE figure for yourself. That is bacause the 5150 BIOS/POST stores the IO_RAM_SIZE figure that it calculated into the BIOS Data Area (BDA), specifically the word (little endian) at 0040:0015.
One way to read that amount is to:
1. Get into BASIC by removing any hard drive, and then boot without a boot floppy, then
2. In BASIC, enter the following:
   def seg = &h40
   print peek(&h16)*256 + peek(&h15)


Where did the programmer go wrong?

If you examine the block of code (lines 525 to 539) carefully, you will discover that the block, by accident no doubt, requires that the upper nibble in register AH be zero before the block is executed.
A non-zero nibble corrupts the calculated value of IO_RAM_SIZE

So what's before the block that affects the upper nibble in register AH?
Another block, lines 511 to 521, in which register AH will end up as:

Motherboard banks
selected via SW1
AH
register
Non-zero
upper nibble?
0
  64 (40h)
Yes
0/1
128 (80h)
Yes
0/1/2
192 (C0h)
Yes
0/1/2/3
    0 (00h)
No