Bios Modding Document

Practical BIOS Editing
by Polygon
of
Rebels Haven Computer Forum
December 31, 2007

Table of Contents
1) Where do I Start?
● What do I Need to Mod a BIOS?-Award
● Here's What's Needed for AMI BIOS
2) "Hot Flashing"
3) Is My Mod BIOS Good to Flash?
4) Using Modbin6
● Moving Items With Modbin6
● Creating a New Item Group
● Modbin6 Actual Results
● [Press Enter]
● Modbin6 as a ROM Editor
● Modbin6 2.04.01
5) Using CBROMxxx
6) Making BIOS Items Selectable
● Adding a Little More Room for Labels
● Adding More Bytes!
7) "Little Endian" Notation
8) AMD Athlon 64 DDR ROM Patcher
9) AMD AM2 DDR2 ROM Patcher
10) Building Your Own Award ISA Option ROM
11) Building Your Own Award Substitute PCI Option ROM
12) Building Your Own Award PCI Opton ROM Using Code Injection
● Code Injection: Brief Method
13) The _item.bin Module and it's Interaction with _en_code.bin
● BIOS Without _Item.bin
● Item Help
● [Press Enter]
14) Editing System.Bin)Original.tmp)
15) Adding a New Item to an Award BIOS
● Another Use for Advanced Technique
● Adding a New Item to a BIOS with no _item.bin Module
16) Updating the Integrated Memtest Module
● Updating memsetup.rom Module
17) Using AMIBCP8 for Windows
18) Using MMTool for AMI BIOS
19) The AMIBIOS BIOS Module Manipulation Utility
20) A AMI PCI Substitute ROM
21) Hacking the uATX VGA BIOS ROM Module
● The "NiBiTor"
22) Intel Conroe DDR2 ROM Patcher
23) Final Words…

Where do I start? What do I need to Mod a BIOS?
Start by understanding what a BIOS is, and what is in a BIOS.
A BIOS is a program that sets register settings in a computer system, that enable it to boot up and
run properly. The file we download and loosely call a BIOS, is in reality the programming medium for
the real BIOS program that is onboard. It is this binary that writes to the volatile memory chip called
CMOS, the settings that we select. Upon boot up, the onboard BIOS program reads the settings from
the CMOS Chip, and sets the system accordingly. The BIOS file we download, is saved in a non-
volatile EEPROM chip that is on the motherboard. Award is up to AWARD6.0 and modern AMI BIOS is
called AMIBIOS8. I will continue the convention of calling the download, a BIOS.
Both AMI and AWARD BIOS are made up of 10-20 binary files called Modules or ROM Modules. Most
are compressed, but a few Modules reside as uncompressed. The BIOS download of a few years back,
were 256K. Modern day BIOS are 512Kb or 1024Kb in size. I suspect in the future, they will grow
even larger.
This screen shot shows the modules in the 256k AN35/N BIOS of just a few years ago, 2004:

Today's most modern P35, DDR3 BIOS, 2007, barely has enough room in 1Meg!:

Using CBROM, we can see the ROM Modules that make up this AWARD BIOS:
0. System BIOS is the main bios program and is the work horse of the BIOS.
1. XGROUP CODE is a extension module as the System BIOS is 128k max.
2. CPU micro code is the info on the CPU's the board supports.
3. ACPI table is all the ACPI information.
4. YGROUP ROM is another extension module
5. Group ROM holds all the text labels for the BIOS
6. SETUP0 holds the format for the BIOS GUI and addresses to the GROUP ROM.
7. OEM0 CODE is a small program file.
8. PCI ROM[A] is the RAID module in this BIOS.
9. PCI ROM[B] is the LAN Boot module in this BIOS.
10. VGA ROM is the VGA BIOS for this boards on-board Video.
11. OEM1 CODE is another small program file.
12. GV3 is Dual Core support module.
13. LOGO is the splash screen we see upon boot up.
All these modules are compressed in this BIOS and usually are in others.

Using MMTool, we can see the ROM Module that make up this AMI BIOS:
The ROM Modules in a AMI BIOS have different names, but by the process of elimination,
most can be identified. The 1B Single Arch Link BIOS is what we call the System BIOS in
the AWARD BIOS. The Multi Language Module is similar to the GROUP Module in the AWARD
BIOS.
While both AWARD and AMI BIOS do the same job, they are very different animals, but we
won't get into that here. The vast majority of information posted relates to AWARD BIOS as
they are the most widespread and have the most software tools for them.

What Do I Need to Mod a BIOS?
Modding a BIOS requires the right programs, or you not going to have success.
Here's what's needed for AWARD BIOS:
1) First needed are the BIOS modding programs. I use Modbin6, CBROM, and a little
program called BIOS Information Tool(bit.exe). "bit.exe" is not working correctly on
newer modern day BIOS, but it still has some use. All 3 programs are discussed, and
linked, in separate topics(Stickys), so I'll assume you'll go find them rather then me
repeat everything here.
2) Anything serious is going to require a Hex Editor program. I use HexWorkshop4.2.
Later on, Flat Assembler(FASM) and IDA Pro 4.3 Disassembler will be needed for more
sophisticated modifications. All programs are linked in the BIOS Editing Tools Collection.
3) I've been modding using 32Bit and 64Bit systems in the Command Prompt of
Windows2000 without problem. WinXP seems to work also, but I only tried it once. I also
have been using 64 Bit Conroe systems running Win2000 without issue. The newer BIOS
require newer mod programs, and they are Win32 programs, meaning they will only work
in Windows Command Prompt. As a safety precaution, turn off any program running in
the background like MBM5. Anything the interrupts the CPU while processing a Mod, may
corrupt the BIOS. I discovered this while Video editing, that video files were getting
corrupted. I assume it can happen to a BIOS also…
4) An extra system to perform a "Hot Flash" on. Best would be the exact same board as
your modding a BIOS for. Many boards use the same or equivalent BIOS chip and only a /
F switch is required when using an AWARD flasher to perform a flash on a different board
then the BIOS is for. A "BIOS Saver" is another item that would help getting up and
running again if the BIOS or flash went wrong. I'm not sure if it is still available. A good
option if you don't have a spare system is, to order a few spare BIOS chips from: http://
badflash.com before you start. That way you can do a "Hot Flash" on your test system.

Here's What's Needed for AMI BIOS:
1) First needed are the BIOS modding programs. I use MMTool_312, AMIBCP313, and a
little program called AMIBIOS BIOS Module Manipulation Utility. All 3 programs are linked
in the BIOS Editing Tools Collection. sticky, an some are discussed in separate topics(and
stickys)
2) Items 2-4 above also apply to AMI BIOS, other then use of the AWARD flasher.
Start out by reading the Stickys and all modding topics here and on other BIOS modding
forums linked in a sticky. Go back and read them over until it makes sense and you can
perform the modifications. Read Pinczakko's Guide to Award BIOS Reverse Engineering
and Pinczakko's Guide to Award BIOS Patching several times. I still go through those
articles and pick up something each time. I "practiced" on BIOS's, taking them apart,
making changes, re-inserting ROM Modules, etc. Then looking at them with Modbin or
MMTool, would tell me if the Mod worked. Usually if the BIOS is corrupt or not flashable,
those programs won't open the newly modded BIOS. I also took apart other peoples
modded BIOS's to see what that author did.
BIOS Modding is something that takes a while to grasp, and only an undying interest and
drive, will lead you to a successful understanding of BIOS modding. This is not something
you are going to learn overnight…
Remember you are using these programs entirely at your own
risk. The information presented may not work for you. If you
are not comfortable modifying BIOS's and flashing them, do not
attempt to modify them.

Hot Flashing a BIOS
You modded a BIOS, flashed it, and now the system is dead… .. You've cleared the CMOS several times, let the
system sit for a while, but it's still a dead duck. "Hot Flashing" may be the only way to get the system back up
and running…
"Hot Flashing" means preparing a known good system ready to be flashed in the DOS "Real Mode". Then swap
the "good" BIOS EEPROM with the "bad" one while the power is on. Then flash the "bad" chip with the desired
BIOS, and then turn the system off and swap the now good BIOS chip, back into the dead system. Sounds easy,
right!
First off, the medium that your using to get into the DOS "Real Mode", must already contain the desired BIOS
and flash utility. You copy those on in advance. This requires a 3.5" drive or a bootable CD.
Second, if the 2 systems are not exactly the same, the /F switch must be used in order that the flashing utility
ignores the fact that the BIOS being flashed, is not for that board. So the command line would look like:
c:\ awdflash xxxxx.bin /F
When doing a "Hot Flash" on a different board, one must make sure the BIOS EEPROM chip is the same or at
least compatible with the other system. I have checked 6 of my boards(nF3, 2-nF4, ATI482, 6100, nF550) and
they all have the same chip, but made by different manufacturers. The other way to do it if you don't have a 2nd
system, is buy a spare BIOS chip in advance. Also, do not use any switches other then the /F switch when hot
flashing on a different board then the BIOS is for.
If a Hot Flash isn't for you or you need a spare BIOS chip, http://badflash.com can help you out. They supply pre-
programmed chips or blank chips. Your choice…
After having to do 15-20 Hot Flashes in the last 2 weeks, I found that a spare drive that is formatted on a
Win98SE system as a Boot Disc, to be invaluable…
I have a 450Meg HDD left over from the "Old Days" that I formatted as a boot disk. On that drive I loaded BIOS's
for each system that I use to test mod BIOS's on… Each board(6100-939 for example) has it own directory that
is named for that board…
When it's time to Hot Flash, I plug the drive in as a Master on the working system, bootup and get ready to flash
from the "C" drive after navigating to the correct directory in DOS. I then swap in the bad BIOS chip, and flash
using the "/F" switch…
One more tip about Hot Flashing, with the power removed, remove the BIOS chip from both systems, once or
twice, to loosen the spring clips… I've been using a small paper clip that is totally straightened out and has the
very ends bent at a right angle. The little bent end just fits in the openings at the corners of the BIOS chip. The
paper clip is then bent into a "U" shape to use for removing the BIOS chip… One must be very careful when
removing the chip with power on…

Here's a commercial chip extractor on the left and my paperclip version:
I've found that many of the boards I have bought in the last 2 years use the exact same BIOS chip. The numbers
are slightly different if made by different chip makers, but a quick check of cross reference lists, shows they are
the same. Most today are 4meg, 33Mhz chips and have part numbers like: 49FL004T-33JC… Some of the AM2
boards and some of Conroe boards use 8Meg BIOS chips. They will look like: 49FL008T-33JC…
Lifted from another thread on setting up one's HDD for easy flashing:
1) I have a Win98SE system that has a 3½" Floppy drive, to make boot disks. I also have a formatted HDD that
is a Win98SE boot disk. I load my BIOS to be flashed on it and do the flash in DOS "Real Mode" by just letting the
system boot up. Re "DOS Real Mode", Google, if you don't know what that is. Bootdisk.com has a wealth of
information on making boot disks on both 3½" Floppies and CD's.
2) I format a Hard Drive on a Win98SE machine and also select "Copy System Files"… The drive must already
have an "active" partition that was enabled either with "Fdisk" or a Partition Manager… . When finished, the drive
now is a "Boot Disc"… Installing the drive in a system and booting, the DOS Prompt of Win98SE would come
up…
I then copy Win2000, the mainboard CD, and several other programs that I always use into a "Temp" folder…
I then install the drive in the test system and load Win2000 by executing "winnt" that is in the i386 folder of the
copied-to-the-drive, Win2000 installation CD. The install goes fine and your license and key number are entered
normally. Now if the system ever wants a file from the install CD, it's on the system already…
After the OS is installed, and the mainboard drivers are installed, upon boot up, Windows stops and asks which

Operating System do you want to boot off of… When you select "previous", you end up at a Real Mode DOS
prompt. Now you can flash BIOS after BIOS that you saved in a special directory, and on the next boot, select
Win2000 for the test runs… A full discussion on the topic is here…
Originally posted by flycaster51:
quote:
Question, must the two boards have the same chipset? Does the /F switch force the flash even if the
chipsets are different?
Yes it does. The chipset has nothing to do with the flash, but I'll qualify that at the end…
I have flashed Conroe BIOS on AM2 boards and every other combo one can think of with no problem using the "/
F" switch. All different chipsets. Doesn't matter. And, out of all the 30 or so boards I have tested in the last 3
years, there were only 2 different BIOS chips. 4Meg and 8Meg. Different manufacturers, but the chips are
equivalent. There are cross reference PDF's on the net and it's pretty easy to see if they are the same. My 2nd
post goes into that a little.
Now the chipset thing. The new nVidia 680i Reference Board uses a slightly more advanced BIOS chip and when
flashed using the nVidia flasher, it looks for the chipset! It seems to carry the MAC address with the BIOS. If you
take a new AWARD flasher, and execute it with the "/?" switch, at the end is says it supports nVidia blah-blah-
blah chipset something or another.
I tried using the nVidia flasher on a AM2 board to flash the 680i BIOS and it complained the chipset was wrong! I
used a AWARD flasher with "/F" and while it flashed, it would not POST on the 680i! On the 680i if the "/F" is
used, AWD870(the latest) halts and does not finish the flash… .. A 680i BIOS chip can only be Hot Flashed on the
680i board, it seems. But either nVidia or AWARD flasher will work. Today, one must always have a spare BIOS
chip if your doing lots of flashes and experimenting. That is why I linked badflash.com…
So, new systems bring new issues, but aside from that issue, the chipset doesn't seen to matter with the Hot
Flash…
I want to point out that my reply is relative to S939 systems and newer only. Before S939, I haven't looked at,
and probably won't…
I bought some blank SST49LF004B-33-4C-NHE BIOS chips and have found some quirks that are worth
mentioning. The "E" at the end means the chip is made with lead-free materials.
1) A blank BIOS chip cannot be flashed with the /F switch. The flasher just freezes.
2) A blank BIOS chip must be first flashed with a BIOS that is for the host system. Then the desired BIOS for
another system can be flashed using the /F switch.
3) The PM49FL004T-33JCE appears to be the newest chip and is backwards compatible to the others on the list.
The SST49LF004B-33-4C-NHE appears not to be forward compatible, but the SST49LF040B-33-4C-NHE probably
is.
4) Newer boards won't flash certain older BIOS chips.
Remember you are using this information entirely at your own risk. The information
presented may not work for you. If you are not comfortable modifying BIOS's and flashing
them, do not attempt to modify them. You must be able to recover from a "bad" flash.

Is My BIOS Good to Flash?
A few members that are interested in BIOS modding have asked "How Do I Know the BIOS Will
Work?"
In a word, you don't! You must be prepared to do a "Hot Flash" or use a "BIOS Saver" if it's still
available…
A minor verification that can be performed is to re-open the modded BIOS with Modbin6. If
anything is wrong, Modbin6 will display non-alphanumeric characters in the "Edit Setup Screen"
window and/or in other windows. If anything major is wrong, Modbin6 will crash. These are sure
signs that whatever was done, is no good and may render a dead computer if flashed… . Also, not
all BIOS's can be modified with Modbin6. Again, the sure sign to leave well enough alone is, seeing
strange characters in the "Edit Setup Screen" window even before trying the Mod.
If the BIOS is corrupt, you MAY see something like this when escaping out of one of the message
windows:
But like everything, there are exceptions to any rule. Brand new motherboards using 680i, P35, P965, etc chipset,
have BIOS that are corrupted when saved in Modbin6. These will re-open and appear to be OK, but in fact are
corrupt because the latest version of Modbin6 was written before those new BIOS were designed. They have
modules and requirements Modbin6 was not designed for. We need a new updated Modbin6 version.

Using Modbin6
Post questions in the Modbin Discussion Thread
Modbin6 should be run in the "Command Prompt" of Win2000 or XP. It probably will work in Vista also. The subject BIOS
and Modbin6 should be in a directory by themselves when using Modbin6. Depending on the other files names and
extensions that might be in your working directory, the apparent corruption can occur, so don't include any other file not
necessary.
Modbin6 allows you, at a minimum, to:
1) Unhide(or hide) BIOS Items.
2) Edit the POST Screen message.
3) Edit the names of BIOS Items and settings.
4) Move any Item or multiple Items.
5) Change the Defaults of any Item.
6) Create a new group and move a Item(s) to it.
Upon saving a modified BIOS, Modbin6 will take care of fixing the BIOS checksum if necessary.
If the un-zipped BIOS file does not have a ".bin" extension, at the command prompt, type and enter: Modbin6 xxxxx.yyy
where xxxxx.yyy represents the actual BIOS file name and extension. Or simply edit the file name to end in ".bin" as all
BIOS files are binary files. Create a separate directory and place the BIOS .bin files and Modbin6 in it and nothing else. I
use a single letter for the directory so then when in the Command Prompt, I have to do a minimum of typing.
The latest available Modbin6 that works for the latest AWARD BIOS, is Linked here:
Modbin6 Version 2.01.02
The command set can be displayed using the /? switch.
The 1st example is how a BIOS file is normally opened.
The 2nd example of "-d" usage, is unknown at this time.
The 3ed example of using "-m" followed by a string, is a way to change the BIOS message. The string must be in
quotations if it is more then 1 word:

If more then 1 binary bios file is in the working directory, or you didn't specify a file name
at the command line, a prompt will come up asking you to select one:
The main window of Modbin6, shows 8 choices:

Selecting "File" and pressing "enter", brings up the Load/Save dialog box:
Selecting "Change BIOS Message", allows one to display anything at the start of POST.
A maximum of 79 characters is the limit:

Selecting "Change BIOS Option", opens a dialog box to select BIOS timing or BIOS option:
Selecting "Change BIOS Option", opens a dialog box to select BIOS timing or BIOS option:
Change BIOS Option, Change BIOS Timing usage, is unknown to me at this time:

Change BIOS Option, Change BIOS Timing usage is unknown to me at this time:
Here we're going to use the menu functions. Pressing "Alt+F" or "Alt+T" or "Alt+H" cause
a dialog box to open. "Alt+F" opens the "File" dropdown box:

"Alt+T" opens the "Tools" dropdown box:
Selecting the "Chipset Register Defaults" opens what appears to be access to all the chipset registers.
The exact capability of this window is unknown right now:

"Alt+H" opens the "Help" dropdown box:
One of the most useful things Modbin6 can do, is to change default BIOS Item settings, or unhide "hidden" settings.
"Hidden" settings are "grayed" out. When selected, various settings become available after pressing "enter":

Here we're going to change Trp from 2T to 4T. 2T is too tight for a default and at 4T, it will match Trcd which is already 4T.
Upon pressing "enter", a window opens and when selected, the setting can be changed using the +/- keys.

If when selected, "enter" is pressed, the available settings are displayed. Also the nomenclature
for the setting could be changed if desired at this point:
Here we have changed both the BIOS default and Setup default Trp to be 4T as a default. All that is left to do is save the
changes. Note that a new file name is required, else the mod BIOS may not be saved:

Here we're going to "unhide" the 183 Divider from a MSI Neo4 Platinum BIOS:
Upon pressing "enter" after selecting the "Max Memlock" Item, a window opens and displays the BIOS default of 200:

Upon pressing "enter", the available settings are displayed. Note that the 183 setting is "Non-Selectable":
Here we have changed the 183 Divider setting to "Selectable" by using the down arrow, and pressing the + key when the
status was selected. Note that both the "BIOS default" and the "Setup default" must be changed. Sometimes changing
one, changes the other. Remember to save the BIOS file as a new name, or it may not be changed. It's a good idea to
save the file from the "Setup Screen Structure Tree" by pressing "Alt+f", and then selecting "save" or "save as":

Note that some BIOS's don't allow changing the "select ability" from Modbin6. See this topic for other methods.
Here we're going to move a BIOS Item that the BIOS Engineer put in a poor spot. This BIOS has the "Cool N' Quiet"
option under Power Management. I'm going to move it to be above the "Spread Spectrum" option as for Overclocking, we
always turn them off…
I've selected the Item to be moved and pressed the space bar. This highlights the option. Note that if we want to move 2
or more Items at the same time, we just highlight them before pressing "insert" where we want them:
Here I've selected where I want the Item to be moved to. This process will place the Item above the Item I've selected:

Pressing the "Insert" key does exactly that. The "Cool N' Quiet" Item is now above the "Spread Spectrum" Item and much
easier to find. It's a good idea to save the file from the "Setup Screen Structure Tree" by pressing "Alt+f", and then
selecting "save" or "save as":
Update: Notes About Moving Items Around With Modbin6
Having performed many Mods that involve moving Items around, I'm noticing several oddities with this process.
1) First, there seems to be no fool-proof sequence that does not corrupt the BIOS or at the very least, screw-up the BIOS
display. This can be seen in Modbin6. Items will be moved to odd-ball areas, all by themselves, or Modbin6 will not open
the BIOS anymore!
2) A sequence of "moves" that works on one BIOS, may not work on another BIOS. I'm even having trouble repeating a
series of 4-6 moves on the same BIOS!
3) Sometimes a whole branch and the sub-items can be moved all at once, and sometimes they can't. And it depends on
where your moving them to!
4) Usually a group of Items that can be disabled by another Item, will not tolerate any Item movement or any additional
Items being placed amongst them. Even under a heading that has both linked and un-linked, if a new Item is added to the
group of un-linked, there is no assurance that the BIOS won't corrupt.
5) In creating a new heading with "alt-C", once those Items are in place, there is no coming back, so be sure they are
where you want them to be.
In general, I've found that it is best to try the moves early on in the mod process, and keep backups of every successful
move. The key seems to be moving one Item at-a-time, but even that is not foolproof! Look thru the Setup Screen in
Modbin6 to make sure everything is in the correct position. If it is, make a backup. Like other BIOS Mod techniques, it's a
lot of trial and error, and can take lots of time.
Edit:
A better way to move items, is change their "Position Code" to that of where you want the Item. Several Items can have
the exact same "Position Code". Thanks to luk1999 whose suggestion works perfectly!

Here is a area of interest:
If I move too many items around, that area looks like this: Here is a area of interest:
If I move too many items around, that area looks like this:

And under this heading, we now have things that don't belong:
Edit: I mistakenly flashed a BIOS that had the display screwed up as above by making to many
moves Modbin6 didn't like. The BIOS works perfectly and when running on the system, everything
is in the correct place…
Edit, Edit: A few days later I can't get the exact same BIOS to mess up the display no matter how
many moves I make. I believe, at least with respect to this issue, it's a Modbin6 issue and not
real. If the BIOS can be opened with Modbin6, the chances are excellent the BIOS is not corrupt.
More as I investigate this new issue…

Using Modbin6: Creating a New Item Group
Another useful operation that can be performed with Modbin, is moving BIOS Items around to
produce a better layout of the BIOS. Grouping of common usage items, makes a easier BIOS to
use. Many BIOS Items control other BIOS Items' ability to be used by allowing them to be
selected or not. Moving a BIOS Item that is linked to another, usually corrupts the BIOS. Also,
moving a BIOS "Branch" may corrupt the BIOS. A "Branch" is a Item that has 1 or more Items
under it. To move all the Items under a Branch, we move them 1-at-a-time, adding and/or
subtracting Items until we achieve the desired layout.
Similar to moving a BIOS Item, we can create a new branch for grouping of similar Items. In this
example, I'm going to group all the Spread Spectrums under 1 heading. There are 2 more in this
BIOS, but because they are under a heading that can be Enabled or Disabled, I'm leaving them
out.
Here I've highlighted the 2 Items to be moved by pressing the Space bar after selecting them:

Here I've navigated down to a unused heading:
To create the new branch, we press "Alt+C" and the branch is created, but with no title:

Navigating up to the title-less heading, we press enter twice and
we're in the edit mode and label the heading:

Oddly enough, the new heading is darkened out and we have to select it and
press "+" to make it visible in the BIOS.
After that we press the space bar to highlight the branch for a move:
Here we have navigated up to where we want the new branch to be, and we pressed insert.
Note that like a individual Item, the branch is inserted above the cursor position:

If the BIOS is corrupt, you may see something like this when escaping out of one of
the message windows, or the BIOS will just not open with Modbin6 any more:
Update: Actual Results With Modbin6
I modded a BIOS with the "Spread Spectrums" branch that was created with "Alt+C" and it flashed fine. Only issues are:
1) The new branch should be added to a unused Item branch. If added to a existing Item, it screws things up.
2) The top entry is grayed out if you do not turn it "on" by selecting the sub-items 1-at-a-time and pressing the "+" key.
Then the branch itself must be turned "on" the same way.
3) Regular branches have [Press Enter] to the right of the branch title. It's unknown how to add that. In the "_EN_CODE.
BIN" module where "Spread Spectrums" is now located, the "00h" to the right of it can be moved over to make more
room for a longer title. But this does not work with regular existing branches. Probably a better way is to use a existing
branch and moving the sub-items in and out 1-at-a-time. That way the [Press Enter] is already there.
I'll update this as I continue to try different things.
Update: 8/20/07
From our work outlined in the Hacking The _ITEM.BIN Module And It's Interaction With _EN_CODE.BIN topic, I have found
a way to add the [Press Enter] on new branches!

Here I have selected 4 Items to put under a unused branch:
For this test, I selected the top unused branch:

Pressing "alt+C" inserts the 4 Items under that branch, but without a heading label:
I've gone in and labeled it "Spread Spectrums" and enabled it as it was disabled by default:

[Press Enter]
Now for the [Press Enter] I found an existing branch and disabled it to be able to locate it's sequence. I've found some
very interesting things in it's sequence. First off. it only has 1 mask. Secondly, it has 00h for the number of selections, but
has a selection label address that ultimately points to the "Press Enter" label in it's _EN_CODE.BIN module:
I edited the new "Spread Spectrums" branch sequence to have 00h selections and have it's label address pointer point to
where "Press Enter" is located in the _en_code.bin module.
Success! We now can make an unused branch look just like every other branch The branch can be moved to a logical
place at this point, if desired.

tilt Display lint [PCI Slot] Item Help
but Contipration Data [lisabledl
Menu Level )
hanxs Controlled by [Auto(ESCD)]
x IRQ Resources Press Enter
MClAJ Palette Snoop [Disabled]
** PCI Express relative items «*
Mucha payload Size [4096]
► spread spectrums [Press Eater]
CPU Spread Spectrum [Center] Item Help
PCI! Spread Spectrum [Disabled]
SATA Spread Spectrum [Disabled] Menu Level
lR Spread Spectra [Disabled]

Using Modbin6 as a ROM Module Editor
Here's a neat little trick I stumbled across when trying to mod a BIOS that Modbin would corrupt upon saving.
Use Modbin6 as a Module Editor. What, you say! OK, here it is. Go into the BIOS using Modbin6 and make the changes
like unhiding, changing default settings, and changing to selectable as many Items/Options as desired. Save the BIOS. It
will be corrupt if it's one of those new "un-Modbin-able" BIOS. Usually the boot block or something is screwed up is why it
is now corrupt. But the internal ROM Modules are fine
Now take the corrupt modded BIOS and extract the _ITEM.BIN and _EN_CODE.BIN modules. These hold the selectability,
hidden/unhidden and default settings.
Now take an unmodded BIOS and release the _ITEM.BIN and _EN_CODE.BIN modules using the latest CBROM program.
Copy the modded _ITEM.BIN and _EN_CODE.BIN modules to the directory where your releasing those unmodded
versions, and inject the modded ones. And your done! CBROM fixes the checksum.
One issue I did run into was that a certain BIOS wanted the ROM modules to be in the exact order they were originally.
You see, injecting a single module, puts it in, last in line, but at the correct address. OK, so release them all up to and
including the _ITEM.BIN and _EN_CODE.BIN modules. Now inject them back in, in the original order. The /D switch with
CBROM displays the order when used with a unmodded BIOS.
Here's the way to do those tough BIOS Mods:
1) In a separate directory, Modbin6 the desired options in the BIOS of interest. Do the minimum needed.
2) Extract _en_code.bin and _item.bin using CBRom 1.55
3) In a different directory, extract and then release, each module starting at the last module, until the _en_code.bin and
_item.bin are reached, but don't extract those 2 modules. Just release them. Save a copy of this BIOS shell in case we
need to redo the mod.
4) Copy the _en_code.bin and _item.bin into the second directory from the 1st directory. These contain the Mods.
5) Insert the modules back into the BIOS using CBRom 1.55 in the exact reverse order that they were released. I make a
copy of the results of: CBRom bios.bin /D to use for reference.
6) Flash the BIOS and make sure all options are saved when selected. I have found a BIOS where the voltage settings
weren't saved when certain mods were made. If the BIOS does not work properly, redo step 1 & 2 with less mods until
the BIOS works. This can take dozens of try's and ten's of hours.
Edit: I found out later that CBROM 1.82 allowed the _ITEM.BIN and _EN_CODE.BIN to be released and replaced without
any other module manipulation.

Modbin6 v2.04.01
Modbin6 v2.04.01 has the ability to modify the latest BIOS without corruption.
See follow-on posts.I got a chance to play with Modbin6 v2.04.01 dated 2/17/2007.
Everything looks about the same as the previous versions, other then the black background
and the "stars" in the "Setup Screen" Here's some screen shots:

Command Prompt - -1111 XJ
MODBIN6 2.04.01 (02/14) Copyright<c) 2007, Phoenix Technologies Ltd.
F T II
File A! S Function:
Change BIOS Message 1 Z This option allows you to edit BIOS kernel
1 1 re lt ae d ft eaures, ildi ncung :
Edit CT/OEM Reg. I 1 * BIOS Timing: Edit time table of
Edit Cyrix CPU Reg. peripheral input/output time out.
Edit Setup Screen 1 I * BIOS Option: Edit numeral BIOS features,
Display BIOS Message I I e.g.: floppy speed, password etc.
Plug in Utility 1 I * Installed Option: Edit default value of
installed option the BIOS check for.
Press [ENTER] to open option box…
I Option :
1 0 BIOS Tii mng
BIOS Option
r! '
8 3/8_11 1 1
t1. -Move Cursor ESC-Abort ENTER-Accept
W
MODBIN6 2.04.01 (02/14) Copyright<c> 2007, Phoenix Technologies Ltd.
I: 11
File Al 0 Function:
9 Change BIOS Message 1 0 This option allows you to edit chipset or
9 Change BIOS Option I I OEM dependent features, including:
9 * Register Default: Edit default value of
: Edit Cyrix CPU Reg. I I location of chipset/OEM Register.
9 Edit Setup Screen I * Auto Table: Edit auto-programming chipset 0
Display BIOS Message 0! 1 /OEM register according to CPU speed,
Plug in Utility s I I single & double bank of cache.

  • Pre-defined PM time-out Setting: Edit

management.
Press ENTER] to open option box…
Option :
Register Default
Auto Table
TI Pre-defined PM Time-out getting
4/8_:
t44+-Move Cursor ESC-Abort ENTER-Accept

MODBIN6 2.04.01 (02/14) (c) 2007, Phoenix Technologies Ltd.
•i i Function:
i i This option allows you to edit chipset or
OEM dependent features, includi ng.,
* Register Default: Edit default value of
Edit Cyrix CPU Reg. ! location of chipset/OEM Register.
Edit Setup Screen * Auto Table: Edit auto-programming chipset
Display BIOS Message 01 CPU speed,
Plug in Utility Iche.
H' :uto Table i f tting: Edit
ii !redefined PM Time-out Setting fined in Power
1 : PCI C:onf igurat ion
fi :box…
I I Option :
I I Register Default
a:I I Auto Table
Vi i Pre-defined PM Time-out getting
H
t44*
Move Cursor ESC-Abort ENTER-Accept
Command Prompt
MODBIN6 2.04.01 (02/14) Copyright(c> 2007, Phoenix Technologies Ltd.
T f!
File Ai Function:
Change BIOS Message i This option allows you to toggle the
Change BIOS Option i performance of CPU internal cache but it
Edit CT/OEM Reg. i depends on your hardware design.
Edit Setup Screen
Display BIOS Message
Plug in Utility i ?? Function disabled ?LI
Di ii
7i
t44+-Moue Cursor ESC-Abort ENTER-Accept

M0 - ❑ x
MODBIN6 2.04.81 (02/14) Copyright(c) 288?, Phoenix Technologies Ltd.
File A Function: i
Change BIOS Message I This function allows you to re-arrange the I
Change BIOS Option I way the setup screen appears in your BIOS.
Edit CT/OEM Beg. In the setup screen structure tree, you can
Edit C rix CPU Beg. 9 employ the providing tools to rename the
item name, disable item function, change
splay BIOS Message item sequence or mark a group heading the 0
Plug in Utility way you like.
Press [ENTER] to open setup screen stucture
tree…
Q
6/8_
t44<—Moue Cursor ESC-Abort ENTER-Accept

One thing I don't like is you can't tell if a Item is hidden unless you go into it. The coloring never changes with hide/
unhide settings.

When we go to save, we notice the same message that the latest CBROM issues. "-Adding MEMINIT.BIN 100%" This
module has something to do with memory mapping I believe. It is extracted and re-inserted by both CBROM and Modbin
recent versions.

The temp files now include several that CBROM 1.82 generates. The file "P35BA521.bin" is the BIOS I modified during this
session.
If both Modbin 2.04.01 and CBROM 1.82 are going to be used on a BIOS, Modbin must be used first. If CBROM is used
first, Modbin will(may) crash when trying to save the modified BIOS.
Remember you are using these programs entirely at your own risk. The information
presented may not work for you. If you are not comfortable modifying BIOS's and
flashing them, do not attempt to modify them.

Using CBROMxxx(AWARD Only)
The CBROM Discussion thread is here…
CBROM2xx is to be used in the DOS "Real Mode", which means a Win98 Boot disk is required. I successfully use the "Command
Prompt" of Win2000, as CBROM32 will only work in the "Command Prompt" of Win98, Win2K, and XP. This is CBROM v1.40 and
newer.
CBROMxxx allows you to change:
1) Extract ROM Modules(Extract).
2) Delete ROM Modules(Release).
3) Insert ROM Modules(ROMFile).
CBROM32 will fix the BIOS checksum when inserting a module, but it will not fix the checksum of the module. Not all modules
require a checksum.
If the un-zipped BIOS file does not have a ".bin" extension, you can simply edit the file name to end in .bin, but it's not
necessary… . If a ROM module type being operated on has more then in the BIOS, a prompt will appear for you to chose the
desired one.
The latest CBROMxxx versions that work for the latest AWARD BIOS, are linked here:
CBROM215
CBROM217A
CBROM219
CBROM220
CBROM32_140
CBROM32_149
CBROM_155
CBROM_1.55.1
CBROM 1.82
Be aware that CBROM 1.40, 1.49, 1.55, 1.55.1, and 1.82 are all Win32 programs and do not work in pure, real mode DOS, only
a Command Prompt Window.
The command set can be displayed using the /? switch:

The ROMs contained in the BIOS can be displayed using the /D switch:
CBROM32_140 has a slightly different command set as this screen shot shows:

Anyhow, the last few versions all work the same. So operating on a module like "_EN_CODE.BIN" with CBROM32, the switch to
use is /group. Execute at the command prompt the following, depending on what your doing:
Delete rom or "release":
cbrom32 xxxx.bin /group release
Extract rom:
cbrom32 xxxx.bin /group extract
Add rom:
cbrom32 xxxx.bin /group _EN_CODE.BIN
When adding a module to a BIOS, CBROM generates a file called "bios.rom". That is the added module in compressed form. We
will find this file useful later on when modifing the system bios module.
Note that you don't need to perform a "save", as the file being worked on is on the drive and changed immediately. Also open
the newly modded BIOS in Modbin6, make a minor change, and save. Modbin will fix any checksum issues when it saves.
Latest CBROMxxx Versions
The version of CBROM32 1.49, add's "/CALS" and "/NVMM" support.

The version of CBROM 1.55.1, and add's "/CALS", "/efi0-9", "/minit" and "/NVMM" support.

Latest CBROMxxx Versions
Thanks to member JP, we have what has to be the very latest CBROM!
Discuss the use of CBROM 1.82 in the CBROMxxx Discussion Thread.
Here's the link: CBROM 1.82
Executing CBROM182 /? shows the command set:
Every switch below is added:

One of the things this version does that I have never seen before is, extract a certain module to a temp file and then add it back
in. It only seems to do it once even though we use CBROM182 several times on a particular BIOS. The modules name that is re-
installed(?) is slightly different from BIOS to BIOS, but it seems to have to do with the "memory module" module.
Remember you are using this information entirely at your own risk. The information presented may not
work for you. If you are not comfortable modifying BIOS's and flashing them, do not attempt to modify
them. You must be able to recover from a "bad" flash.

Thanks to our friend "Compiller" we have a new version of the ASUS CBROM!
It is linked here: ASUS CBROM115.zip
I'm not sure if this will work on non-ASUS BIOS.

Making BIOS Options "Selectable" and "Naming" Options
In order to keep this technique clear and easy to review, the thread is closed and discussion is taking place in this thread…
For some as yet unknown reason, some BIOS's don't allowing changing an option to "Selectable" in Modbin6. With the cursor highlighting "Non-
Selectable" title, the "Plus(+)" key is pressed, and the status changes to "Selectable". Problem is that after exiting and then re-entering, the
option is back to "Non-Selectable". Here is the Modbin6 window referred to:
This issue, and attempting to "Name" a blank option, has led me into hex-editing the "_EN_CODE.BIN" module contained in all AWARD BIOS.
Notice in the above screen shot that the "150Mhz" option has no title, and Modbin6 doesn't appear to be able to edit a title into that blank space.

First the issue of being "Selectable". At least half the BIOS I ever tried to work with, won't retain the "Selectable" setting when saving and
exiting. But, many do. For those that don't, I found that by setting the bit directly after the setting in the "_EN_CODE.BIN" module, the option
was then always "Selectable". I have highlighted the "offending" bit. When set to 01h the item is "Non-Selectable". When set to 00h the item is
"Selectable". The second screen shot below shows that "trailing" bit on another already selectable option.

The extraction(release) and replacement of the _EN_CODE.BIN BIOS module was performed with Cbrom32. See this topic…

Now to "Naming" the option…
We remember this screen shot from the above post with no "Name" or "Title" for the 150Mhz option:

Looking at the "_EN_CODE.BIN" BIOS module with the Hex-Editor, we find a "space for the "150Mhz" title, but nothing is there. I did try opening
that space by 6 Bits and inserted the "Name", but evidently the BIOS has only just so much room for this option, and it screwed up everything
else. Here's the "Space" highlighted:

The obvious solution to me was to enter the "150Mhz" title and leave something else blank. That way the total space allotment for this option
would remain the same. I chose the 216Mhz(DDR233) as the setting to eliminate. Here's what the new "_EN_CODE.BIN module looks like with
the 150Mhz option now having a title. (Note that the cursor is not on the 300Mhz line, but 4 lines lower then where I'm referring to):

Looking back at the BIOS with Modbin6, the option is now "Selectable" and complete with a title:
Note that the removing and replacing of the "_EN_CODE.BIN" BIOS module requires use of the BIOS Tool "CBROM32.exe"
See Using CBROMxxx.EXE for details…

I looked at 2 different BIOS's. One had the ability to have options to be made "Selectable", and the other would not keep
or "hold" the selectable setting…
Again here are 2 non-selectable settings with the trailing "01" byte(I've switched to Hex Workshop):
Reviewing the "_EN_CODE.BIN" file from each BIOS, there was no obvious differences in the coding used. The "lock" on selectability must be in
some other BIOS module…
The Final Solution!
Note that I have switched to Hex Workshop as it's better suited for BIOS and Hex Editing, IMHO…
In looking at the whole problem of not having enough room to add the 150Mhz nomenclature to the BIOS, it became obvious that with only so
many bits of space available, it was time to save some space.
In the screen shot below of the 1C0 MSI Neo4 Platinum BIOS, I got rid of the "Mhz" after each entry and then had plenty of room to have all
available settings "selectable". I put spaces in front of every entry in an effort to fill the available space, but it now appears that the spaces could
go almost anywhere…

Here I've highlighted the whole group of bit's that were available for the "Maxmemlock" titles. Note that you must keep the exact same number
of entries. Adding 1 or leaving 1 out will cause the rest of the setup screen to be garbage and render the BIOS corrupt. Also note that the
apparent spaces for titles before "100Mhz" and after "250Mhz" would lead you to believe 66Mhz and 266Mhz are also options. Having tried both,
I can tell you that the "66" setting freezes the system, and the "250" setting isn't visible, no matter what the bits are set to:

In looking at an older MSI BIOS from 2002, I notice that many of the "Naming" and "Selectability" options are in the System BIOS and others
are in the _EN_CODE.BIN file. Newer BIOS apparently have all the names or labels in the _EN_CODE.BIN file.

Here I'm looking at the System BIOS which was generated by running Modbin6 on the target BIOS. It produces a file called "Original.bin" when
running Modbin6. It is the System BIOS available for modification. See Using Modbin6 topic.
I have highlighted a hidden option's trailing byte, that is the tell-tale 01h, immediately after the "name", meaning it's "non-selectable". Directly
above the highlight is another hidden option with 01h trailing the "name"… . In trying to modify the Original.Bin file and then saving, the options
are still "non-selectable" because the trailing bytes are still 01h. Modbin6 isn't saving the Original.Bin on this BIOS for some reason, but I'd be
willing to bet it works on some BIOS or with a different Modbin version. I was able to enable the options in Modbin6 by selecting them and
pressing the "+" key..

Adding A Little More Room For The Title or Labels!
In another thread, Hacking The _ITEM.BIN Module, member luk1999 uncovered information about the _EN_CODE.BIN Module which lead us to
be able to add a little space to the labeling in the _EN_CODE.BIN Module. Turns out that the "starts" are defined in the binary data that directly
follows a group.
Here's a segment from the _ITEM.BIN Module that is in a BIOS I've been working with. It's for the Biostar 6100-939. This is the mod BIOS with
the added Memclk settings of 120 and 140Mhz. I'm hoping to get it working. It's the sequence for the Memclk Item in the CU51M811 BIOS:

The top picture shows where the Item label starts. I'm pointing to the location bytes at the end of the group in the _EN_CODE module and Hex
Workshops location of that byte. The bottom picture has all the byte locations for the Items in this group up to the Item of interest highlighted.
There are 19 of them. Then circled in the middle picture is the location # of the Memclk in hex(13h), which is 19. For anyone following along,
the binary/hex files use "Little Endian" notation, meaning least significant bytes are first. So 45B7h is B745 in the file.

From the information learned in the Hacking the _ITEM.BIN topic, we can now clean up our added settings so that they look truly professional.
Here is a screen shot of the business end of the _EN_CODE.BIN module. In the top part, I have highlighted the entire section of code that labels
the Memclock Frequency settings. In the bottom part, is highlighted the address of the 1st letter of the labels, "A" of Auto. The hex entry before
the address for the "A", is the address for the "M" of Memclock Frequency. Remember that BIOS modules use "Little Endian" notation, meaning
least significant bytes are first. So 45B7h is B745 in the picture. The key to a nice BIOS presentation shown below, is the fact that all labels
occupy the same number of places. That is 4 in this case. Be aware that more spaces can not be added. We must use what is available. We
could have abbreviated the "Memclock Frequency" to gain room, just as long as the addresses were corrected. If a space or 2 in front of the "A"
would have helped, just changing the address of the "A" would take care of the spaces.

Here is the finished product. Never before seen BIOS settings in the Max Memclk Frequency Item:

Here is the bottom section of the selections:

Adding More Bytes!
Here's a little trick that may help in the future. For a variety of reasons, we may want different labeling on a Item's option settings, but can't fit
it in the space it's presently occupying.
Let's add the new labels to the end of the _EN_CODE.BIN module. Adding bytes at the end of the module, does not affect any of the addresses
that are already listed in the module. I'm sure at some point adding bytes will cause a problem, but my example added about 80 bytes and the
BIOS works fine. Here we have selected Tras as the test Item. The top of the screen shot shows the first address for the Item's title as 460Ah.
The bottom of the screen shot shows I have already changed the 2 addresses for the Item's title and the settings labels:

Here is the results. I changed many of the numbers to letters so I could see that the technique works. I had finished the row with a series of
nulls(00h) as that is what is between the stock labels. I then added my new labels and finished the task with a few spaces(2020h). Probably
nulls would have be fine also:

And entering the BIOS after flashing the Mod BIOS, we see my test pattern of letters then numbers:

Note that I didn't need to move both Item title and the settings labels. If only one needed to be moved, that would be fine. Also, I did nothing to
correct the checksum of the _EN_CODE.BIN module. From previous work here, it appears to be un-necessary.
Remember you are using this information entirely at your own risk. The information presented may not work for you.
If you are not comfortable modifying BIOS's and flashing them, do not attempt to modify them. You must be able to
recover from a "bad" flash.

"Little Endian" Notation
Intel(IBM Compatible) uses what is called "Little Endian" Notation. That means that the least significant digits are
displayed first. So, the decimal number 1428, which is 0594h in Hex, will be displayed as 9405h in the binary file.
Definitions:
Big Endian
Within a given multi-byte numeric representation, the most significant byte has the lowest address (the word is stored
"big-end-first"). This notation is also referred to as "Motorola type".
Little Endian
A given 16- or 32-bit word, bytes at lower addresses have lower significance (the word is stored "little-end-first"). This
notation is also referred to as "swapped bytes" or "Intel type".
In this _EN_CODE.BIN module is a perfect example of "Little Endian" notation. The very 1st address in the _EN_CODE.
bin main address list is 9405h, but it really points to 0594h in this BIOS module.

Tictac's AMD Athlon 64 DDR ROM Patcher Rev 3.0.1
Any questions, comments, etc on this code should be posted in the:
Building a ISA Option ROM Discussion Thread
Download Source Code
Or:
Building a PCI Option ROM Discussion Thread
Download Source Code
code:
;-------------------
; AMD Athlon 64 DDR ROM Patcher Rev 3.0
;
-------------------
;
; Source code writen by tictac
; Website : z6.invisionfree.com/tictac
; Note : Free to be distribute/mod , Use it at your own risk
;
;
-------------------
;
------CODE
DEFINITION
----------
;
-------------------
use16 ; 16bit mode
address equ 0CF8h ; address port
data equ 0CFCh ; data port
dtl_add equ 08000C288h ; DRAM Timing Low address
dth_add equ 08000C28Ch ; DRAM Timing High address
dcl_add equ 08000C290h ; DRAM Configuration Low address
dch_add equ 08000C294h ; DRAM Configuration High address
ddr_add equ 08000C298h ; DRAM Delay Line Register address
ROM_SIZE_IN_BLOCK = 1 ; 1 means ROM size is 1 block (512 bytes)
ROM_SIZE_IN_BYTE = ROM_SIZE_IN_BLOCK * 512
;
-------------
; DRAM Timing Low Address
;
-------------
; CAS Latency(dtl)
tcl equ dtl_add
tcl_data equ 0FFFFFFF8h ; CAS Latency (3bit)
tcl_2 equ 000000001h ; CAS 2
tcl_25 equ 000000005h ; CAS 2.5
tcl_3 equ 000000002h ; CAS 3
; Row Cycle Time(dtl)
trc equ dtl_add
trc_data equ 0FFFFFF0Fh ; Row Cycle Time (4bit)
trc_7 equ 000000000h ; 7 clock
trc_8 equ 000000010h ; 8 clock
trc_9 equ 000000020h ; 9 clock
trc_10 equ 000000030h ; 10clock
trc_11 equ 000000040h ; 11clock

trc_12 equ 000000050h ; 12clock
trc_13 equ 000000060h ; 13clock
trc_14 equ 000000070h ; 14clock
trc_15 equ 000000080h ; 15clock
trc_16 equ 000000090h ; 16clock
trc_17 equ 0000000A0h ; 17clock
trc_18 equ 0000000B0h ; 18clock
trc_19 equ 0000000C0h ; 19clock
trc_20 equ 0000000D0h ; 20clock
trc_21 equ 0000000E0h ; 21clock
trc_22 equ 0000000F0h ; 22clock
; Row Refresh Cycle Time(dtl)
trfc equ dtl_add
trfc_data equ 0FFFFF0FFh ; Row Refresh Cycle Time (4bit)
trfc_9 equ 000000000h ; 9 clock
trfc_10 equ 000000100h ; 10clock
trfc_11 equ 000000200h ; 11clock
trfc_12 equ 000000300h ; 12clock
trfc_13 equ 000000400h ; 13clock
trfc_14 equ 000000500h ; 14clock
trfc_15 equ 000000600h ; 15clock
trfc_16 equ 000000700h ; 16clock
trfc_17 equ 000000800h ; 17clock
trfc_18 equ 000000900h ; 18clock
trfc_19 equ 000000A00h ; 19clock
trfc_20 equ 000000B00h ; 20clock
trfc_21 equ 000000C00h ; 21clock
trfc_22 equ 000000D00h ; 22clock
trfc_23 equ 000000E00h ; 23clock
trfc_24 equ 000000F00h ; 24clock
; RAS to CAS Delay(dtl)
trcd equ dtl_add
trcd_data equ 0FFFF8FFFh ; RAS to CAS Delay (3bit)
trcd_2 equ 000002000h ; 2 clock
trcd_3 equ 000003000h ; 3 clock
trcd_4 equ 000004000h ; 4 clock
trcd_5 equ 000005000h ; 5 clock
trcd_6 equ 000006000h ; 6 clock
; RAS to RAS Delay(dtl)
trrd equ dtl_add
trrd_data equ 0FFF8FFFFh ; RAS to RAS Delay (3bit)
trrd_2 equ 000020000h ; 2 clock
trrd_3 equ 000030000h ; 3 clock
trrd_4 equ 000040000h ; 4 clock
; Min. RAS active time(dtl)
tras equ dtl_add
tras_data equ 0FF0FFFFFh ; Min. RAS active time (4bit)
tras_5 equ 000500000h ; 5 clock
tras_6 equ 000600000h ; 6 clock
tras_7 equ 000700000h ; 7 clock
tras_8 equ 000800000h ; 8 clock
tras_9 equ 000900000h ; 9 clock
tras_10 equ 000A00000h ; 10clock
tras_11 equ 000B00000h ; 11clock
tras_12 equ 000C00000h ; 12clock
tras_13 equ 000D00000h ; 13clock
tras_14 equ 000E00000h ; 14clock
tras_15 equ 000F00000h ; 15clock
; Row Precharge Time(dtl)
trp equ dtl_add
trp_data equ 0F8FFFFFFh ; Row Precharge Time (3bit)

trp_2 equ 002000000h ; 2 clock
trp_3 equ 003000000h ; 3 clock
trp_4 equ 004000000h ; 4 clock
trp_5 equ 005000000h ; 5 clock
trp_6 equ 006000000h ; 6 clock
; Write Recovery Time(dtl)
twr equ dtl_add
twr_data equ 0EFFFFFFFh ; Write Recovery Time (1bit)
twr_2 equ 000000000h ; 2 clock
twr_3 equ 010000000h ; 3 clock
;-------------
; DRAM Timing High Address
;
-------------
; Write to read delay(dth)
twtr equ dth_add
twtr_data equ 0FFFFFFFEh ; Write to read delay (1bit)
twtr_1 equ 000000001h ; 1 clock
twtr_2 equ 000000002h ; 2 clock
; Read to write delay(dth)
trwt equ dth_add
trwt_data equ 0FFFFFF8Fh ; Read to write delay (3bit)
trwt_1 equ 000000000h ; 1 clock
trwt_2 equ 000000010h ; 2 clock
trwt_3 equ 000000020h ; 3 clock
trwt_4 equ 000000030h ; 4 clock
trwt_5 equ 000000040h ; 5 clock
trwt_6 equ 000000050h ; 6 clock
; Refresh Rate(dth)
tref equ dth_add
tref_data equ 0FFFFE0FFh ; Refresh Rate (5bit)
tref_100_156 equ 000000000h ; 100MHz 15.6us
tref_133_156 equ 000000100h ; 133MHz 15.6us
tref_166_156 equ 000000200h ; 166MHz 15.6us
tref_200_156 equ 000000300h ; 200MHz 15.6us
tref_100_78 equ 000000800h ; 100MHz 7.8us
tref_133_78 equ 000000900h ; 133MHz 7.8us
tref_166_78 equ 000000A00h ; 166MHz 7.8us
tref_200_78 equ 000000B00h ; 200MHz 7.8us
tref_100_39 equ 000001000h ; 100MHz 3.9us
tref_133_39 equ 000001100h ; 133MHz 3.9us
tref_166_39 equ 000001200h ; 166MHz 3.9us
tref_200_39 equ 000001300h ; 200MHz 3.9us
; Write CAS latency(dth)
twcl equ dth_add
twcl_data equ 0FF8FFFFFh ; Write CAS latency (3bit)
twcl_1 equ 000000000h ; 1 clock
twcl_2 equ 000100000h ; 2 clock
;
-------------
; DRAM Configuration Low Address
;
-------------
; DLL Disabled(dcl)
dll equ dcl_add
dll_data equ 0FFFFFFFEh ; DLL disabled (1bit)
dll_enable equ 000000000h ; Enabled(default)
dll_disable equ 000000001h ; Disabled
; Dimm Drive Strength(dcl)
dds equ dcl_add

dds_data equ 0FFFFFFFDh ; Dimm Drive Strength (1bit)
dds_normal equ 000000000h ; Normal(Default)
dds_weak equ 000000002h ; Weak (Beware)
; Read/Write Qued Bypass(dcl)
rwqbp equ dcl_add
rwqbp_data equ 0FFFF3FFFh ; Read/Write Qued Bypass (2bit)
rwqbp_2x equ 000000000h ; 2x
rwqbp_4x equ 000004000h ; 4x
rwqbp_8x equ 000008000h ; 8x
rwqbp_16x equ 00000C000h ; 16x
; Bypass Max(dcl)
bpm equ dcl_add
bpm_data equ 0F1FFFFFFh ; Bypass Max (3bit)
bpm_0x equ 000000000h ; 0x (Disabled)
bpm_1x equ 002000000h ; 1x
bpm_2x equ 004000000h ; 2x
bpm_3x equ 006000000h ; 3x
bpm_4x equ 008000000h ; 4x
bpm_5x equ 00A000000h ; 5x
bpm_6x equ 00C000000h ; 6x
bpm_7x equ 00E000000h ; 7x
; Command Rate(dcl)
rc equ dcl_add
cr_data equ 0EFFFFFFFh ; Command Rate (1bit)
cr_1t equ 000000000h ; 1T
cr_2t equ 010000000h ; 2T
;-------------
; DRAM Configuration High Address
;
-------------
; Maximum Async Latency(dch)
async equ dch_add
async_data equ 0FFFFFFF0h ; Maximum Async Latency (4bit)
async_0 equ 000000000h ; 0 ns
async_1 equ 000000001h ; 1 ns
async_2 equ 000000002h ; 2 ns
async_3 equ 000000003h ; 3 ns
async_4 equ 000000004h ; 4 ns
async_5 equ 000000005h ; 5 ns
async_6 equ 000000006h ; 6 ns
async_7 equ 000000007h ; 7 ns
async_8 equ 000000008h ; 8 ns
async_9 equ 000000009h ; 9 ns
async_10 equ 00000000Ah ; 10ns
async_11 equ 00000000Bh ; 11ns
async_12 equ 00000000Ch ; 12ns
async_13 equ 00000000Dh ; 13ns
async_14 equ 00000000Eh ; 14ns
async_15 equ 00000000Fh ; 15ns
; Read Preamble(dch)
rp equ dch_add
rp_data equ 0FFFFF0FFh ; Read Preamble (4bit)
rp_20 equ 000000000h ; 2.0ns
rp_25 equ 000000100h ; 2.5ns
rp_30 equ 000000200h ; 3.0ns
rp_35 equ 000000300h ; 3.5ns
rp_40 equ 000000400h ; 4.0ns
rp_45 equ 000000500h ; 4.5ns
rp_50 equ 000000600h ; 5.0ns
rp_55 equ 000000700h ; 5.5ns
rp_60 equ 000000800h ; 6.0ns

rp_65 equ 000000900h ; 6.5ns
rp_70 equ 000000A00h ; 7.0ns
rp_75 equ 000000B00h ; 7.5ns
rp_80 equ 000000C00h ; 8.0ns
rp_85 equ 000000D00h ; 8.5ns
rp_90 equ 000000E00h ; 9.0ns
rp_95 equ 000000F00h ; 9.5ns
; Idle Cycle Limit(dch)
icl equ dch_add
icl_data equ 0FFF8FFFFh ; Idle Cycle Limit (3bit)
icl_0 equ 000000000h ; 0 clock
icl_4 equ 000010000h ; 4 clock
icl_8 equ 000020000h ; 8 clock
icl_16 equ 000030000h ; 16clock
icl_32 equ 000040000h ; 32clock
icl_64 equ 000050000h ; 64clock
icl_128 equ 000060000h ; 128clock
icl_256 equ 000070000h ; 256clock
; Dynamic idle cycle counter enable(dch)
dicc equ dch_add
dicc_data equ 0FFF7FFFFh ; Dynamic idle cycle limit (1bit)
dicc_disable equ 000000000h ; disabled
dicc_enable equ 000080000h ; enabled
; Memory Clock Frequency(dch)
mcf equ dch_add
mcf_data equ 0FF8FFFFFh ; Memory Clock Frequency (3bit)
mcf_100 equ 000000000h ; 100MHz
mcf_133 equ 000200000h ; 133MHz
mcf_166 equ 000500000h ; 166MHz
mcf_200 equ 000700000h ; 200MHz (1:1)
;-------------
; DRAM DQS Delay Line Register
;
-------------
; DQS Slew Value(ddr)
dqs equ ddr_add
dqs_data equ 0FF00FFFFh ; Delay Line Adjust (8bit)
dqs_1 equ 000010000h ; 1
dqs_2 equ 000020000h ; 2
dqs_3 equ 000030000h ; 3
dqs_4 equ 000040000h ; 4
dqs_5 equ 000050000h ; 5
dqs_6 equ 000060000h ; 6
dqs_7 equ 000070000h ; 7
dqs_8 equ 000080000h ; 8
dqs_9 equ 000090000h ; 9
dqs_10 equ 0000A0000h ; 10
dqs_255 equ 000FF0000h ; 255
; DQS Slew Control(ddr)
dqsc equ ddr_add
dqsc_data equ 0FCFFFFFFh ; Adjust DQS (1bit) & (1bit)
dqsc_slow equ 001000000h ; Slower DQS
dqsc_fast equ 002000000h ; Faster DQS
;
-------------------
;
-----ROM
Header------------
;
-------------------
ROMStart:
db 0x055, 0x0AA ; ROM Header 55,AA -> Bootable rom

db (ROMEnd - ROMStart)/512 ; ROM Size in 512byte
jmp MAIN
db 0 ; checksum, to be filled in later
;-------------------
;
-----SUB-
ROUTINE-------------
;-------------------
macro MTT 0,1,2
{
mov eax,0 ; copy register address
mov ebx,1 ; copy register data
mov dx,address ; set port address
out dx,eax ; send address through the port
mov dx,data ; set port data
in eax,dx
and eax,2 ; set data in eax
or eax,ebx ; increase data
out dx,eax ; send data through port data
}
macro SAVE ; Save all register that will be affected by our code
{
pushfd
push eax
push ebx
push bx
push dx
push si
push ds
push bp
}
macro RETURN ; Restore register contents
{
pop bp
pop ds
pop si
pop dx
pop bx
pop ebx
pop eax
popfd
retf ; return far to system bios routine
}
;
-------------------
;
-------MAIN-
ROUTINE
----------
;-------------------
times (256)-($-$$) db 0 ; locate Main routine at 100h
MAIN:
SAVE
;
--------------------
; Patch A64 Memory Timing
MTT async,async_7,async_data ; Set max async latency to 7ns
;
-------------------—-
RETURN
times (ROM_SIZE_IN_BYTE-$) db 0
; The last byte (512th) will be the patch_byte for the checksum
; patch_byte is calculated and automagically inserted below
PREV_CHKSUM = 0
repeat $
load CHKSUM byte from %-1
CHKSUM = (PREV_CHKSUM + CHKSUM) mod 0x100

PREV_CHKSUM = CHKSUM
end repeat
store byte (0x100 - CHKSUM) at ($-1) ; store the patch_byte
ROMEnd:
;-------—CODE
END
-----------
; How to set you memory timing?
; Just type MTT<space>timing name,timing value,timing data
; Exp : async memory to 7.0ns would be -> MTT async,async_7,async_data
; Press F9 to compile it with flat assembler
;
;--------------------
All available Memory Clock settings:
code:
; Memory Clock Frequency(dch)
mcf equ dch_add
mcf_data equ 0FF8FFFFFh ; Memory Clock Frequency (3bit)
mcf_100 equ 000000000h ; 100MHz
mcf_120 equ 000100000h ; 120MHz
mcf_133 equ 000200000h ; 133MHz
mcf_140 equ 000300000h ; 140MHz
mcf_150 equ 000400000h ; 150MHz
mcf_166 equ 000500000h ; 166MHz
mcf_180 equ 000600000h ; 180MHz
mcf_200 equ 000700000h ; 200MHz (1:1)
EDIT: Note that the 120Mhz divider may not work on all systems and hang at POST.
Sometimes it is ok to inject it on ethernet PCI ROM but ethernet wont be useable…
Just change the ROM header with PCI
Device & Vendor ID must match available ethernet device
PCI ROM Header
example : nForce2 NIC
code:

;-------------------
;
-----PCI ROM
Header------------
;
-------------------
ROM_SIZE_IN_BLOCK = 1 ; 1 means ROM size is 1 block (512 bytes)
ROM_SIZE_IN_BYTE = ROM_SIZE_IN_BLOCK * 512
VENDOR_ID equ 10DEh ; PCI Vendor ID (must match yout
ethernet vendor id)
; exp: 10DE = nVidia
DEVICE_ID equ 01E0h ; PCI Device ID (must match yout
ethernet devicie id)
; exp: 01E0h = nforce2 NIC
ROMStart:
db 0x055, 0x0AA ; ROM Header 55,AA -> Bootable rom
db (ROMEnd - ROMStart)/512 ; ROM Size in 512byte
jmp MAIN
db 0 ; checksum, to be filled in later
TIMES 18h-($-$$) DB 0 ; padding zeros to offset 18h
DW PCIHDR ; pointer to PCI Header
DW PNPHDR ; pointer to PnP Expansion Header
PCIHDR: DB 'PCIR' ; PCI data structure signature
DW VENDOR_ID ; vendor ID (must match real PCI
device)
DW DEVICE_ID ; device ID (must match real PCI
device)
DW 0 ; pointer to vital product data (0=none)
DW 24 ; PCI data structure length [B]
DB 0 ; PCI data structure revision (0=PCI 2.1)
DB 2,0,0 ; PCI device class code (2=network ctrlr,
0=eth.)
DW ROM_SIZE_IN_BLOCK ; ROM size in 512B blocks
DW 0 ; revision level of code
DB 0 ; code type (0=x86 compitable)
DB 80h ; last image indicator
DW 0 ; reserved
PNPHDR: DB '$PnP' ; PnP data structure signature
DB 1 ; PnP structure revision
DB 2 ; PnP structure length (in 16B blocks)
DW 0 ; offset to next header (0-none)
DB 0 ; reserved
DB 33h ; PnP structure checksum
DD 0 ; device identifier
DW 0 ; pointer to manufacturer string
DW 0 ; pointer to productname string
DB 2,0,0 ; device class code (2=network ctrlr,
0=eth.)
DB 64h ; device indicators (64h - shadowable,cacheable,not
only for boot,IPL device)
DW 0 ; boot connection vector (0-none)
DW 0 ; disconnect vector (0-none)
DW 0 ; bootstrap entry vector (0-none)
DW 0 ; reserved
DW 0 ; static resource info vector (0-none)
;
-------------------

Fixed error in Twtr and Command Rate; added ECC Enable.
code:
;-------------------
; AMD Athlon 64 DDR ROM Patcher Rev 3.0.1 (7/5/2007)
;
-------------------
;
; Source code writen by tictac
; Website : z6.invisionfree.com/tictac
; Note : Free to be distribute/mod , Use it at your own risk
;
;
-------------------
;
------CODE
DEFINITION
----------
;
-------------------
use16 ; 16bit mode
address equ 0CF8h ; address port
data equ 0CFCh ; data port
dtl_add equ 08000C288h ; DRAM Timing Low address
dth_add equ 08000C28Ch ; DRAM Timing High address
dcl_add equ 08000C290h ; DRAM Configuration Low address
dch_add equ 08000C294h ; DRAM Configuration High address
ddr_add equ 08000C298h ; DRAM Delay Line Register address
ROM_SIZE_IN_BLOCK = 1 ; 1 means ROM size is 1 block (512 bytes)
ROM_SIZE_IN_BYTE = ROM_SIZE_IN_BLOCK * 512
;
-------------
; DRAM Timing Low Address
;
-------------
; CAS Latency(dtl)
tcl equ dtl_add
tcl_data equ 0FFFFFFF8h ; CAS Latency (3bit)
tcl_2 equ 000000001h ; CAS 2
tcl_25 equ 000000005h ; CAS 2.5
tcl_3 equ 000000002h ; CAS 3
; Row Cycle Time(dtl)
trc equ dtl_add
trc_data equ 0FFFFFF0Fh ; Row Cycle Time (4bit)
trc_7 equ 000000000h ; 7 clock
trc_8 equ 000000010h ; 8 clock
trc_9 equ 000000020h ; 9 clock
trc_10 equ 000000030h ; 10clock
trc_11 equ 000000040h ; 11clock
trc_12 equ 000000050h ; 12clock
trc_13 equ 000000060h ; 13clock
trc_14 equ 000000070h ; 14clock
trc_15 equ 000000080h ; 15clock
trc_16 equ 000000090h ; 16clock
trc_17 equ 0000000A0h ; 17clock
trc_18 equ 0000000B0h ; 18clock
trc_19 equ 0000000C0h ; 19clock
trc_20 equ 0000000D0h ; 20clock
trc_21 equ 0000000E0h ; 21clock

trc_22 equ 0000000F0h ; 22clock
; Row Refresh Cycle Time(dtl)
trfc equ dtl_add
trfc_data equ 0FFFFF0FFh ; Row Refresh Cycle Time (4bit)
trfc_9 equ 000000000h ; 9 clock
trfc_10 equ 000000100h ; 10clock
trfc_11 equ 000000200h ; 11clock
trfc_12 equ 000000300h ; 12clock
trfc_13 equ 000000400h ; 13clock
trfc_14 equ 000000500h ; 14clock
trfc_15 equ 000000600h ; 15clock
trfc_16 equ 000000700h ; 16clock
trfc_17 equ 000000800h ; 17clock
trfc_18 equ 000000900h ; 18clock
trfc_19 equ 000000A00h ; 19clock
trfc_20 equ 000000B00h ; 20clock
trfc_21 equ 000000C00h ; 21clock
trfc_22 equ 000000D00h ; 22clock
trfc_23 equ 000000E00h ; 23clock
trfc_24 equ 000000F00h ; 24clock
; RAS to CAS Delay(dtl)
trcd equ dtl_add
trcd_data equ 0FFFF8FFFh ; RAS to CAS Delay (3bit)
trcd_2 equ 000002000h ; 2 clock
trcd_3 equ 000003000h ; 3 clock
trcd_4 equ 000004000h ; 4 clock
trcd_5 equ 000005000h ; 5 clock
trcd_6 equ 000006000h ; 6 clock
; RAS to RAS Delay(dtl)
trrd equ dtl_add
trrd_data equ 0FFF8FFFFh ; RAS to RAS Delay (3bit)
trrd_2 equ 000020000h ; 2 clock
trrd_3 equ 000030000h ; 3 clock
trrd_4 equ 000040000h ; 4 clock
; Min. RAS active time(dtl)
tras equ dtl_add
tras_data equ 0FF0FFFFFh ; Min. RAS active time (4bit)
tras_5 equ 000500000h ; 5 clock
tras_6 equ 000600000h ; 6 clock
tras_7 equ 000700000h ; 7 clock
tras_8 equ 000800000h ; 8 clock
tras_9 equ 000900000h ; 9 clock
tras_10 equ 000A00000h ; 10clock
tras_11 equ 000B00000h ; 11clock
tras_12 equ 000C00000h ; 12clock
tras_13 equ 000D00000h ; 13clock
tras_14 equ 000E00000h ; 14clock
tras_15 equ 000F00000h ; 15clock
; Row Precharge Time(dtl)
trp equ dtl_add
trp_data equ 0F8FFFFFFh ; Row Precharge Time (3bit)
trp_2 equ 002000000h ; 2 clock
trp_3 equ 003000000h ; 3 clock
trp_4 equ 004000000h ; 4 clock
trp_5 equ 005000000h ; 5 clock
trp_6 equ 006000000h ; 6 clock
; Write Recovery Time(dtl)
twr equ dtl_add
twr_data equ 0EFFFFFFFh ; Write Recovery Time (1bit)
twr_2 equ 000000000h ; 2 clock

twr_3 equ 010000000h ; 3 clock
;-------------
; DRAM Timing High Address
;
-------------
; Write to read delay(dth)
twtr equ dth_add
twtr_data equ 0FFFFFFFEh ; Write to read delay (1bit)
twtr_1 equ 000000000h ; 1 clock
twtr_2 equ 000000001h ; 2 clock
; Read to write delay(dth)
trwt equ dth_add
trwt_data equ 0FFFFFF8Fh ; Read to write delay (3bit)
trwt_1 equ 000000000h ; 1 clock
trwt_2 equ 000000010h ; 2 clock
trwt_3 equ 000000020h ; 3 clock
trwt_4 equ 000000030h ; 4 clock
trwt_5 equ 000000040h ; 5 clock
trwt_6 equ 000000050h ; 6 clock
; Refresh Rate(dth)
tref equ dth_add
tref_data equ 0FFFFE0FFh ; Refresh Rate (5bit)
tref_100_156 equ 000000000h ; 100MHz 15.6us
tref_133_156 equ 000000100h ; 133MHz 15.6us
tref_166_156 equ 000000200h ; 166MHz 15.6us
tref_200_156 equ 000000300h ; 200MHz 15.6us
tref_100_78 equ 000000800h ; 100MHz 7.8us
tref_133_78 equ 000000900h ; 133MHz 7.8us
tref_166_78 equ 000000A00h ; 166MHz 7.8us
tref_200_78 equ 000000B00h ; 200MHz 7.8us
tref_100_39 equ 000001000h ; 100MHz 3.9us
tref_133_39 equ 000001100h ; 133MHz 3.9us
tref_166_39 equ 000001200h ; 166MHz 3.9us
tref_200_39 equ 000001300h ; 200MHz 3.9us
; Write CAS latency(dth)
twcl equ dth_add
twcl_data equ 0FF8FFFFFh ; Write CAS latency (3bit)
twcl_1 equ 000000000h ; 1 clock
twcl_2 equ 000100000h ; 2 clock
;
-------------
; DRAM Configuration Low Address
;
-------------
; DLL Disabled(dcl)
dll equ dcl_add
dll_data equ 0FFFFFFFEh ; DLL disabled (1bit)
dll_enable equ 000000000h ; Enabled(default)
dll_disable equ 000000001h ; Disabled
; Dimm Drive Strength(dcl)
dds equ dcl_add
dds_data equ 0FFFFFFFDh ; Dimm Drive Strength (1bit)
dds_normal equ 000000000h ; Normal(Default)
dds_weak equ 000000002h ; Weak (Beware)
; Read/Write Qued Bypass(dcl)
rwqbp equ dcl_add
rwqbp_data equ 0FFFF3FFFh ; Read/Write Qued Bypass (2bit)
rwqbp_2x equ 000000000h ; 2x
rwqbp_4x equ 000004000h ; 4x
rwqbp_8x equ 000008000h ; 8x

rwqbp_16x equ 00000C000h ; 16x
; Bypass Max(dcl)
bpm equ dcl_add
bpm_data equ 0F1FFFFFFh ; Bypass Max (3bit)
bpm_0x equ 000000000h ; 0x (Disabled)
bpm_1x equ 002000000h ; 1x
bpm_2x equ 004000000h ; 2x
bpm_3x equ 006000000h ; 3x
bpm_4x equ 008000000h ; 4x
bpm_5x equ 00A000000h ; 5x
bpm_6x equ 00C000000h ; 6x
bpm_7x equ 00E000000h ; 7x
; Command Rate(dcl)
cr equ dcl_add
cr_data equ 0EFFFFFFFh ; Command Rate (1bit)
cr_1t equ 000000000h ; 1T
cr_2t equ 010000000h ; 2T
; ECC Enable(dcl)
ecc equ dcl_add
ecc_data equ 0FFFDFFFFh ; Command Rate (1bit)
ecc_d equ 000000000h ; Disable
ecc_e equ 000020000h ; Enable
;-------------
; DRAM Configuration High Address
;
-------------
; Maximum Async Latency(dch)
async equ dch_add
async_data equ 0FFFFFFF0h ; Maximum Async Latency (4bit)
async_0 equ 000000000h ; 0 ns
async_1 equ 000000001h ; 1 ns
async_2 equ 000000002h ; 2 ns
async_3 equ 000000003h ; 3 ns
async_4 equ 000000004h ; 4 ns
async_5 equ 000000005h ; 5 ns
async_6 equ 000000006h ; 6 ns
async_7 equ 000000007h ; 7 ns
async_8 equ 000000008h ; 8 ns
async_9 equ 000000009h ; 9 ns
async_10 equ 00000000Ah ; 10ns
async_11 equ 00000000Bh ; 11ns
async_12 equ 00000000Ch ; 12ns
async_13 equ 00000000Dh ; 13ns
async_14 equ 00000000Eh ; 14ns
async_15 equ 00000000Fh ; 15ns
; Read Preamble(dch)
rp equ dch_add
rp_data equ 0FFFFF0FFh ; Read Preamble (4bit)
rp_20 equ 000000000h ; 2.0ns
rp_25 equ 000000100h ; 2.5ns
rp_30 equ 000000200h ; 3.0ns
rp_35 equ 000000300h ; 3.5ns
rp_40 equ 000000400h ; 4.0ns
rp_45 equ 000000500h ; 4.5ns
rp_50 equ 000000600h ; 5.0ns
rp_55 equ 000000700h ; 5.5ns
rp_60 equ 000000800h ; 6.0ns
rp_65 equ 000000900h ; 6.5ns
rp_70 equ 000000A00h ; 7.0ns
rp_75 equ 000000B00h ; 7.5ns
rp_80 equ 000000C00h ; 8.0ns
rp_85 equ 000000D00h ; 8.5ns

rp_90 equ 000000E00h ; 9.0ns
rp_95 equ 000000F00h ; 9.5ns
; Idle Cycle Limit(dch)
icl equ dch_add
icl_data equ 0FFF8FFFFh ; Idle Cycle Limit (3bit)
icl_0 equ 000000000h ; 0 clock
icl_4 equ 000010000h ; 4 clock
icl_8 equ 000020000h ; 8 clock
icl_16 equ 000030000h ; 16clock
icl_32 equ 000040000h ; 32clock
icl_64 equ 000050000h ; 64clock
icl_128 equ 000060000h ; 128clock
icl_256 equ 000070000h ; 256clock
; Dynamic idle cycle counter enable(dch)
dicc equ dch_add
dicc_data equ 0FFF7FFFFh ; Dynamic idle cycle limit (1bit)
dicc_disable equ 000000000h ; disabled
dicc_enable equ 000080000h ; enabled
; Memory Clock Frequency(dch)
mcf equ dch_add
mcf_data equ 0FF8FFFFFh ; Memory Clock Frequency (3bit)
mcf_100 equ 000000000h ; 100MHz
mcf_120 equ 000100000h ; 120MHz
mcf_133 equ 000200000h ; 133MHz
mcf_140 equ 000300000h ; 140MHz
mcf_150 equ 000400000h ; 150MHz
mcf_166 equ 000500000h ; 166MHz
mcf_180 equ 000600000h ; 180MHz
mcf_200 equ 000700000h ; 200MHz (1:1)
;-------------
; DRAM DQS Delay Line Register
;
-------------
; DQS Slew Value(ddr)
dqs equ ddr_add
dqs_data equ 0FF00FFFFh ; Delay Line Adjust (8bit)
dqs_1 equ 000010000h ; 1
dqs_2 equ 000020000h ; 2
dqs_3 equ 000030000h ; 3
dqs_4 equ 000040000h ; 4
dqs_5 equ 000050000h ; 5
dqs_6 equ 000060000h ; 6
dqs_7 equ 000070000h ; 7
dqs_8 equ 000080000h ; 8
dqs_9 equ 000090000h ; 9
dqs_10 equ 0000A0000h ; 10
dqs_255 equ 000FF0000h ; 255
; DQS Slew Control(ddr)
dqsc equ ddr_add
dqsc_data equ 0FCFFFFFFh ; Adjust DQS (1bit) & (1bit)
dqsc_slow equ 001000000h ; Slower DQS
dqsc_fast equ 002000000h ; Faster DQS
;
-------------------
;
-----ROM
Header------------
;
-------------------
ROMStart:
db 0x055, 0x0AA ; ROM Header 55,AA -> Bootable rom
db (ROMEnd - ROMStart)/512 ; ROM Size in 512byte

jmp MAIN
db 0 ; checksum, to be filled in later
;-------------------
;
-----SUB-
ROUTINE-------------
;-------------------
macro MTT 0,1,2
{
mov eax,0 ; copy register address
mov ebx,1 ; copy register data
mov dx,address ; set port address
out dx,eax ; send address through the port
mov dx,data ; set port data
in eax,dx
and eax,2 ; set data in eax
or eax,ebx ; increase data
out dx,eax ; send data through port data
}
macro SAVE ; Save all register that will be affected by our code
{
pushfd
push eax
push ebx
push bx
push dx
push si
push ds
push bp
}
macro RETURN ; Restore register contents
{
pop bp
pop ds
pop si
pop dx
pop bx
pop ebx
pop eax
popfd
retf ; return far to system bios routine
}
;
-------------------
;
-------MAIN-
ROUTINE
----------
;-------------------
times (256)-($-$$) db 0 ; locate Main routine at 100h
MAIN:
SAVE
;
--------------------
; Patch A64 Memory Timing
MTT async,async_7,async_data ; Set max async latency to 7ns
;
-------------------—-
RETURN
times (ROM_SIZE_IN_BYTE-$) db 0
; The last byte (512th) will be the patch_byte for the checksum
; patch_byte is calculated and automagically inserted below
PREV_CHKSUM = 0
repeat $
load CHKSUM byte from %-1
CHKSUM = (PREV_CHKSUM + CHKSUM) mod 0x100
PREV_CHKSUM = CHKSUM

end repeat
store byte (0x100 - CHKSUM) at ($-1) ; store the patch_byte
ROMEnd:
;-------—CODE
END
-----------
; How to set you memory timing?
; Just type MTT<space>timing name,timing value,timing data
; Exp : async memory to 7.0ns would be -> MTT async,async_7,async_data
; Press F9 to compile it with flat assembler
;
;--------------------
In doing a mod BIOS for a A64 system, Tref was not working correctly. This is what I found a while ago
using WPCREdit. This code, while different then the AMD data sheet, works correctly, at least according to
A64 Tweaker. I guess A64 Tweaker could be wrong! But here's what is working:
code:
; Refresh Rate(dth)
tref equ dth_add
tref_data equ 0FFFFE0FFh ; Refresh Rate (5bit)
tref_100_156 equ 000000000h ; 100MHz 15.6us
tref_133_156 equ 000000100h ; 133MHz 15.6us
tref_166_156 equ 000000200h ; 166MHz 15.6us
tref_200_156 equ 000000300h ; 200MHz 15.6us
tref_100_78 equ 000000400h ; 100MHz 7.8us
tref_133_78 equ 000000500h ; 133MHz 7.8us
tref_166_78 equ 000000600h ; 166MHz 7.8us
tref_200_78 equ 000000700h ; 200MHz 7.8us
tref_100_39 equ 000000800h ; 100MHz 3.9us
tref_133_39 equ 000000900h ; 133MHz 3.9us
tref_166_39 equ 000000A00h ; 166MHz 3.9us
tref_200_39 equ 000000B00h ; 200MHz 3.9us

AMD AM2 DDR2 ROM Patcher Version 1.0.5.1
Download Source Code.
I rewrote the AMD A64 ROM Patcher that tictac wrote to update it for the Socket AM2 processor. Here is
the AMD AM2 DDR2 ROM Patcher Beta Version and it is working well. I'm updating the code as I fix the
register data and configuration data.
The register data is here starting at page 101:
BIOS and Kernal Developer's Guide for AMD NPT Family 0Fh Processors(pdf file)
The following code is the most up-to-date. The follow-on verbiage after this code describes the steps I
took in re-writing the code and relearning Assembly. That is included for reference only.
code:
;-------------------
; AMD AM2 DDR2 ROM Patcher Beta 1.0.5.1 09/07/2007
;
-------------------
;
; Source code writen by tictac. Updated for AM2 by Polygon of www.rebelshavenforum.com
; Website : z6.invisionfree.com/tictac
; Note : Free to be distribute/mod , Use it at your own risk
;
;
-------------------
;
------CODE
DEFINITION
----------
;
-------------------
use16 ; 16bit mode
address equ 0CF8h ; address port
data equ 0CFCh ; data port
dtl_add equ 08000C288h ; DRAM Timing Low address
dth_add equ 08000C28Ch ; DRAM Timing High address
dcl_add equ 08000C290h ; DRAM Configuration Low address
dch_add equ 08000C294h ; DRAM Configuration High address
dcm_add equ 08000C2A0h ; DRAM Controller Miscellaneous Data address
ROM_SIZE_IN_BLOCK = 1 ; 1 means ROM size is 1 block (512 bytes)
ROM_SIZE_IN_BYTE = ROM_SIZE_IN_BLOCK * 512
;
-------------
; DRAM Timing Low Address 08000C288h
;
-------------
; CAS Latency(dtl)
tcl equ dtl_add
tcl_data equ 0FFFFFFF8h ; CAS Latency (3bit)
tcl_3 equ 000000002h ; CAS 3
tcl_4 equ 000000003h ; CAS 4
tcl_5 equ 000000004h ; CAS 5
tcl_6 equ 000000005h ; CAS 6
; RAS to CAS Delay(dtl)
trcd equ dtl_add
trcd_data equ 0FFFFFFCFh ; RAS to CAS Delay (2bit)
trcd_3 equ 000000000h ; 3 clock

trcd_4 equ 000000010h ; 4 clock
trcd_5 equ 000000020h ; 5 clock
trcd_6 equ 000000030h ; 6 clock
; Row Precharge Time(dtl)
trp equ dtl_add ;
trp_data equ 0FFFFFCFFh ; Row Precharge Time (2bit)
trp_3 equ 000000000h ; 3 clock
trp_4 equ 000000100h ; 4 clock
trp_5 equ 000000200h ; 5 clock
trp_6 equ 000000300h ; 6 clock
; Read Precharge Time(dtl)
trtp equ dtl_add ;
trtp_data equ 0FFFFF7FFh ; Read Precharge Time (1bit)
trtp_2 equ 000000000h ; 2/4 clock
trtp_3 equ 000000800h ; 3/5 clock
; Min. RAS active time(dtl)
tras equ dtl_add
tras_data equ 0FFFF0FFFh ; Min. RAS active time (4bit)
tras_5 equ 000002000h ; 5 clock
tras_6 equ 000003000h ; 6 clock
tras_7 equ 000004000h ; 7 clock
tras_8 equ 000005000h ; 8 clock
tras_9 equ 000006000h ; 9 clock
tras_10 equ 000007000h ; 10 clock
tras_11 equ 000008000h ; 11 clock
tras_12 equ 000009000h ; 12 clock
tras_13 equ 00000A000h ; 13 clock
tras_14 equ 00000B000h ; 14 clock
tras_15 equ 00000C000h ; 15 clock
tras_16 equ 00000D000h ; 16 clock
tras_17 equ 00000E000h ; 17 clock
tras_18 equ 00000F000h ; 18 clock
; Row Cycle Time(dtl)
trc equ dtl_add
trc_data equ 0FFF0FFFFh ; Row Cycle Time (4bit)
trc_11 equ 000000000h ; 11 clock
trc_12 equ 000010000h ; 12 clock
trc_13 equ 000020000h ; 13 clock
trc_14 equ 000030000h ; 14 clock
trc_15 equ 000040000h ; 15 clock
trc_16 equ 000050000h ; 16 clock
trc_17 equ 000060000h ; 17 clock
trc_18 equ 000070000h ; 18 clock
trc_19 equ 000080000h ; 19 clock
trc_20 equ 000090000h ; 20 clock
trc_21 equ 0000A0000h ; 21 clock
trc_22 equ 0000B0000h ; 22 clock
trc_23 equ 0000C0000h ; 23 clock
trc_24 equ 0000D0000h ; 24 clock
trc_25 equ 0000E0000h ; 25 clock
trc_26 equ 0000F0000h ; 26 clock
; Write Recovery Time(dtl)
twr equ dtl_add ;
twr_data equ 0FFCFFFFFh ; Write Recovery Time (2bit)
twr_3 equ 000000000h ; 3 clock
twr_4 equ 000100000h ; 4 clock
twr_5 equ 000200000h ; 5 clock
twr_6 equ 000300000h ; 6 clock
; RAS to RAS Delay Time(dtl)
trrd equ dtl_add ;

trrd_data equ 0FF3FFFFFh ; RAS to RAS Delay Time (2bit)
trrd_2 equ 000000000h ; 2 clock
trrd_3 equ 000400000h ; 3 clock
trrd_4 equ 000800000h ; 4 clock
trrd_5 equ 000C00000h ; 5 clock
;-------------
; DRAM Timing High Address
;
-------------
; Write to read delay(dth)
twtr equ dth_add ;
twtr_data equ 0FFFFFCFFh ; Write to read delay (2bit)
twtr_1 equ 000000100h ; 1 clock
twtr_2 equ 000000200h ; 2 clock
twtr_3 equ 000000300h ; 3 clock
; Twrrd Delay(dth)
tWrrd equ dth_add ;
tWrrd_data equ 0FFFFF3FFh ; Twrrd Delay (2bit)
tWrrd_0 equ 000000000h ; 0 clock
tWrrd_1 equ 000000400h ; 1 clock
tWrrd_2 equ 000000800h ; 2 clock
tWrrd_3 equ 000000C00h ; 3 clock
; Twrwr Delay(dth)
twrwr equ dth_add ;
twrwr_data equ 0FFFFCFFFh ; Twrwr Delay (2bit)
twrwr_1 equ 000000000h ; 1 clock
twrwr_2 equ 000001000h ; 2 clock
twrwr_3 equ 000002000h ; 3 clock
; Trdrd Delay(dth)
trdrd equ dth_add ;
trdrd_data equ 0FFFF3FFFh ; Trdrd Delay (2bit)
trdrd_2 equ 000000000h ; 2 clock
trdrd_3 equ 000004000h ; 3 clock
trdrd_4 equ 000008000h ; 4 clock
trdrd_5 equ 00000C000h ; 5 clock
; Refresh Rate(dth)
tref equ dth_add
tref_data equ 0FFFCFFFFh ; Refresh Rate (2bit)
tref_15.6 equ 000010000h ; 15.6us
tref_7.8 equ 000020000h ; 7.8us
tref_3.9 equ 000030000h ; 3.9us
; Trfc0(dth)
trfc0 equ dch_add
trfc0_data equ 0FF8FFFFFh ; Maximum Async Latency (3bit)
trfc0_75 equ 000000000h ; 75 ns
trfc0_105 equ 000100000h ; 105 ns
trfc0_127.5 equ 000200000h ; 127.5 ns
trfc0_195 equ 000300000h ; 195 ns
trfc0_327.5 equ 000400000h ; 327.5 ns
; Trfc1(dth)
trfc1 equ dch_add
trfc1_data equ 0FC7FFFFFh ; Maximum Async Latency (3bit)
trfc1_75 equ 000000000h ; 75 ns
trfc1_105 equ 000800000h ; 105 ns
trfc1_127.5 equ 001000000h ; 127.5 ns
trfc1_195 equ 001800000h ; 195 ns
trfc1_327.5 equ 002000000h ; 327.5 ns

; Trfc2(dth)
trfc2 equ dch_add
trfc2_data equ 0E3FFFFFFh ; Maximum Async Latency (3bit)
trfc2_75 equ 000000000h ; 75 ns
trfc2_105 equ 004000000h ; 105 ns
trfc2_127.5 equ 008000000h ; 127.5 ns
trfc2_195 equ 00C000000h ; 195 ns
trfc2_327.5 equ 010000000h ; 327.5 ns
; Trfc3(dth)
trfc3 equ dch_add
trfc3_data equ 01FFFFFFFh ; Maximum Async Latency (3bit)
trfc3_75 equ 000000000h ; 75 ns
trfc3_105 equ 020000000h ; 105 ns
trfc3_127.5 equ 040000000h ; 127.5 ns
trfc3_195 equ 060000000h ; 195 ns
trfc3_327.5 equ 080000000h ; 327.5 ns
;-------------
; DRAM Configuration Low Address
;
-------------
; Dimm Drive Strength(dcl)
dds equ dcl_add
dds_data equ 0FFFFFF7Fh ; Dimm Drive Strength (1bit)
dds_normal equ 000000000h ; NORMAL
dds_weak equ 000000080h ; WEAK
;
-------------
; DRAM Configuration High Address
;
-------------
; Memory Clock Frequency(dch)
mcf equ dch_add
mcf_data equ 0FFFFFFF8h ; Memory Clock Frequency (3bit)
mcf_200 equ 000000000h ; 400MHz
mcf_266 equ 000000001h ; 533MHz
mcf_333 equ 000000002h ; 667MHz
mcf_400 equ 000000003h ; 800MHz
; Maximum Async Latency(dch)
async equ dch_add
async_data equ 0FFFFFF0Fh ; Maximum Async Latency (4bit)
async_0 equ 000000000h ; 0 ns
async_1 equ 000000010h ; 1 ns
async_2 equ 000000020h ; 2 ns
async_3 equ 000000030h ; 3 ns
async_4 equ 000000040h ; 4 ns
async_5 equ 000000050h ; 5 ns
async_6 equ 000000060h ; 6 ns
async_7 equ 000000070h ; 7 ns
async_8 equ 000000080h ; 8 ns
async_9 equ 000000090h ; 9 ns
async_10 equ 0000000A0h ; 10ns
async_11 equ 0000000B0h ; 11ns
async_12 equ 0000000C0h ; 12ns
async_13 equ 0000000D0h ; 13ns
async_14 equ 0000000E0h ; 14ns
async_15 equ 0000000F0h ; 15ns
; Command Rate(dch)
cr equ dch_add
cr_data equ 0FFEFFFFFh ; Command Rate (1bit)
cr_1t equ 000000000h ; 1T
cr_2t equ 000100000h ; 2T

; Queue Bypass Max(dch)
qbp equ dch_add
qbp_data equ 0F0FFFFFFh ; Queue Bypass Max (4bit)
qbp_0 equ 000000000h ; 0 memclk cycles
qbp_1 equ 001000000h ; 1 memclk cycles
qbp_2 equ 002000000h ; 2 memclk cycles
qbp_3 equ 003000000h ; 3 memclk cycles
qbp_4 equ 004000000h ; 4 memclk cycles
qbp_5 equ 005000000h ; 5 memclk cycles
qbp_6 equ 006000000h ; 6 memclk cycles
qbp_7 equ 007000000h ; 7 memclk cycles
qbp_8 equ 008000000h ; 8 memclk cycles
qbp_9 equ 009000000h ; 9 memclk cycles
qbp_10 equ 00A000000h ; 10 memclk cycles
qbp_11 equ 00B000000h ; 11 memclk cycles
qbp_12 equ 00C000000h ; 12 memclk cycles
qbp_13 equ 00D000000h ; 13 memclk cycles
qbp_14 equ 00E000000h ; 14 memclk cycles
qbp_15 equ 00F000000h ; 15 memclk cycles
; Four Act Window(dch)
faw equ dch_add
faw_data equ 00FFFFFFFh ; Four Act Window (4bit)
faw_0x equ 000000000h ; No Tfaw Window Restriction
faw_8x equ 010000000h ; 8x
faw_9x equ 020000000h ; 9x
faw_10x equ 030000000h ; 10x
faw_11x equ 040000000h ; 11x
faw_12x equ 050000000h ; 12x
faw_13x equ 060000000h ; 13x
faw_14x equ 070000000h ; 14x
faw_15x equ 080000000h ; 15x
faw_16x equ 090000000h ; 16x
faw_17x equ 0A0000000h ; 17x
faw_18x equ 0B0000000h ; 18x
faw_19x equ 0C0000000h ; 19x
faw_20x equ 0D0000000h ; 20x
;-------------
; DRAM Controller Miscellaneous Data address
;
-------------
; R/W Queue Bypass Max(dcm)
rwqbp equ dch_add
rwqbp_data equ 0FFFFFFF3h ; R/W Queue Bypass Max (2bit)
rwqbp_0 equ 000000000h ; 2 memclk cycles
rwqbp_1 equ 000000004h ; 4 memclk cycles
rwqbp_2 equ 000000008h ; 8 memclk cycles
rwqbp_3 equ 00000000Ch ; 16 memclk cycles
; Dynamic Idle Cycle Enable(dcm)
dicl equ dcm_add
dicl_data equ 0FFFFFFDFh ; Dynamic Idle Cycle Enable (1bit)
dicl_0 equ 000000000h ; Disable
dicl_0 equ 000000020h ; Enable
; Idle Cycle Limit(dcm)
icl equ dcm_add
icl_data equ 0FFFFFE3Fh ; Idle Cycle Limit (3bit)
icl_0 equ 000000000h ; 0 clock
icl_4 equ 000000040h ; 4 clock
icl_8 equ 000000080h ; 8 clock
icl_16 equ 0000000C0h ; 16clock
icl_32 equ 000000100h ; 32clock
icl_64 equ 000000140h ; 64clock
icl_128 equ 000000180h ; 128clock

icl_256 equ 0000001C0h ; 256clock
;-------------------
;
-----ROM
Header------------
;
-------------------
ROMStart:
db 0x055, 0x0AA ; ROM Header 55,AA -> Bootable rom
db (ROMEnd - ROMStart)/512 ; ROM Size in 512byte
jmp MAIN
db

Unless otherwise stated, the content of this page is licensed under Creative Commons Attribution-ShareAlike 3.0 License