Programmatically Adjusting the RAM Refresh Rate
I recently found this old gem I wrote back in high school while digging through and purging garbage from the old "My Documents" folder. As I alluded to in my "Reflecting on a Quarter Century Online," there was a book I stumbled across in the library that opened a new door on programming for me that revealed how a Pascal programmer (high school remember?) could access a PC's underlying hardware. Between that and some articles I found on the Internet, I reprogrammed the PIT chip on my old 386SX to get a performance boost!
MEM-RATE v1.11 allows you to adjust the setting of your 8253 PIT timer 1. DRAM chips relied on capacitors to keep a charge present and needed a periodic refresh in order to prevent data corruption. The Programmable Interval Timer Channel 1 drove the refresh logic to the memory chips. Setting the refresh rate too low can cause the capacitors to discharge resulting in the chips to losing their memory, which in turn induces an NMI MEMORY PARITY ERROR and crashing the machine. Most computers require at least a 5Khz refresh rate to maintain system integrity. (NOTE: This function became moot on modern hardware where the refresh was handled natively out-of-band.)
The advantage to adjusting your computer's refresh rate is improved system performance. The PIT interrupts the CPU in order to conduct the memory refresh. Therefore, the less your CPU is interrupted by the PIT, the more cycles are available for actual processing. The disadvantage to reducing the refresh rate arises in memory failure (only at LOW levels) and reduced hard disk performance. The HD's timers are intimately linked with this interrupt for motor timing. Although new rates will not affect HD data, it will slow down your access.
It is advised to obtain a total system benchmark utility and experiment with different refresh rates until you obtain the optimal performance balanced by DRAM stability and hard drive needs. Most standard BIOS systems default the PIT timer 0 to 66Khz. I was able to boost my 386 performance by 7% lowering the memory refresh to 25Khz with negligible HD speed loss.
Program MEM_Rate (Input, Output);
{ MEM-Rate v1.11
Copyright (c) 1997 Matthew Vea
All Rights Reserved
Adjusts the memory refresh timer for improved system performance. }
{$G+} {80286 Instructions Enabled}
Const
Max = 1193180; { Maximum Rate }
Var
Rate : LongInt; { Memory Refresh Rate }
Code : Integer; { Scratch Variable }
Begin
Writeln;
Writeln ('Memory Refresh Control v1.10');
Writeln ('Copyright (c) 1997 Matthew Vea');
Writeln;
If ParamCount < 1 Then
Writeln ('ERROR : Refresh Rate Not Specified')
Else
Begin
Val (ParamStr (1), Rate, Code);
Port [$43] := $76;
Port [$41] := Lo (Max DIV Rate);
Port [$41] := Hi (Max DIV Rate);
Writeln ('New Refresh Rate = ', Rate / 1000 :1:2, 'Khz');
End;
Writeln;
End.
The code above takes a user defined refresh rate as a command line parameter.
The next step is to configure the PIT directly via the Command/Mode port 0x43
and the Channel 1 data port 0x41
. A value of 0x76
(01110110
) is written into the command port. 01
is written to bits 7 and 6 to designate Channel 1. 11
is written to bits 5 and 4 to designate both hi and lo bytes will be written to the data port. 011
for bits 3, 2, and 1 are just a default instructing the PIT to use the Square Wave generator. Finally, 0
is written to bit 0 configuring the chip to treat data as 16bit binary instead of BCD.
After writing to the Command/Mode port, the new frequency can be programmed into the Channel 1 data port. I/O ports only allow 8 data bits and therefore 16 bits must be written sequentially as the low byte followed by the high byte. To program a frequency, the maximum clock rate 1193180
gets divided by the desired frequency and each portion of that 16 bit result gets written to the 0x41
data port. The number 1193180
comes from the native clock frequency at 1.19MHz (1193180Hz). Immediately upon writing the high byte to the data port, the configuration will take effect.