On Thu, Jun 03, 2004 at 03:32:58PM -0500, Richard Smith wrote:
Peter Stuge wrote:
On Thu, Jun 03, 2004 at 03:56:29AM -0500, Richard Smith wrote:
timer. In numerious locations my Vbios is writing a 0x00 to IO 0x43 and then does 2 reads from 0x40. So its latching the value of counter 0 and then reading it out.
Right, it also sets counter mode 0, zero detection interrupt. Are there any hints of the code actually using the interrupt anywhere?
Um... I don't know. What would I look for?
Someone writing a segment/offset pair to 0000:0020. (I.e. installing an interrupt handler for IRQ0/INT8.)
I don't thing so but that does explain why linux whines about "too many timer interrutps" occurring.
Yes, if the io accesses are let through the emulator to the real hardware, that's certainly the reason.
You could probably test this, I did some quick testing and it looks like Linux sets the timer divisor so that timer 0 runs at 1kHz. Verify this (grep 0: /proc/interrupts && sleep && grep) followed by a timed run of testbios. If there are extra interrupts on IRQ 0, the real hardware was touched.
[..]
Looking at the delay routine is just confusing.
I agree.
There's a comment that says 4 bx counts equals .4290 * 4 or 2uS. So that tells me the VBios thinks the system timer must be running at 2.386 Mhz rather than the 1.19318 Mhz my PC hardware book claims.
1193180Hz doesn't change, that's the 4.77MHz clock divided by four, your hardware book is correct. I used Ralf Brown's interrupt/port list to refresh my own memory.
All this tells me that I don't understand timer access in a modern system. The code as written just dosen't seem like it would work on a 4.77 Mhz XT.
It may not neccessarily do so. The M1 is a PCI bus chip, right? I can easily imagine that ATI didn't make the video BIOS XT compatible for a graphics controller targeted at newer/mobile/embedded systems.
[..snip..]
This will only skip the jump (and do the BX decrement) if ax is zero. For ax to be zero the result of the 2's complement subtraction must be zero or the when the 2 reads are the same number. But I just don't see how this would happen repeatably at .6us per ISA IO.
Hmm. Let's have another look at the code.
Ok. Pseudocode:
procedure delay(someunit) { bx=someunit dx=read_timer() do { ax=read_timer() ax=-(ax-dx) if(ax==0) bx=bx-(bx mod 2)-2 } while(ax<bx) }
It doesn't make a whole lot of sense, but eventually the loop will end, since -(the_original_timer-current_timer) always gets compared with the requested delay. If the (16bit) timer wraps, bx is decreased but that's not really neccessary for the loop to ever end.
Conclusion; it not a very precise delay, it's just a suitably short delay. :)
Ate the timer reads really and ISA IO?
At least they used to be, port accesses on 486/Pentium took forever and that's when I last did stuff like this and payed any attention to how long it took. :)
I guess if those reads are happening much faster then it would work. Where does the timer live now? int the northbridge perhpas? Thats could be the issue. If the northbridge responded to the IO it would happen at cpu clock rates and all would be well.
Sure, it's part of the northbridge, but all sorts of buses are there, I'd just put the timer where it has always been, on an ISA bus, to minimize breakage. Although, lately I guess ISA isn't included in chipsets, at least externally. LPC is handy for things like this and of course runs a lot faster at 33MHz.
//Peter