Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Hi. I try to get the Real Time Clock to generate 1024 interrupts/second but the output I get can't be that... It's much lesser than 1024... This is the code I use to setup the RTC... Anything wrong with it?
Mov Al,0xA
Out 70h,Al
Jmp short $+2
In Al,71h
And Al,10100110b
Or Al,00100110b
Push Ax
Mov Al,0xA
Out 70h,Al
Jmp short $+2
Pop Ax
Out 71h,Al
Mov Al,0xB
Out 70h,Al
Jmp short $+2
In Al,71h
And Al,01010011b
Or Al,01010010b
Push Ax
Mov Al,0xB
Out 70h,Al
Jmp short $+2
Pop Ax
Out 71h,Al
in al, 70h ;Get current 70h
and al, 0eh ;Discard lower 5 bits because we are just allowed to use them
or al, 0ah ;Byte index we will get from cmos ram.
out 70h, al ;Send index to 70h
in al, 71h ;Get needed info from cmos.
What do these binary values correspond to? If you can write some comments on code I might try to help more.(I am also dealing with this subject nowadays ) I hope this helps, good luck...
I've written a datasheet which provides info on the CMOS chip (including RTC) at xinit.port5.com
What you need to do is:-
[0] Set bits 0-3 of Status Register A to 0110b
[0] Set bit 6 of Status Register B to 1
[0] Read status register C after every interrupt. Bit 6 of Status Register C will be set if the interrupt was the periodic interrupt (set at 1024Hz)
What do these binary values correspond to? If you can write some comments on code I might try to help more.(I am also dealing with this subject nowadays ) I hope this helps, good luck...
I set status A to x010 0110b.
x = Update In Progress flag (left unchanged)
010 = 32 MHz or something like that... default value
0110 = what to divide 010 with
The result is how many interrupts per second there should be...
Therx wrote:
I've written a datasheet which provides info on the CMOS chip (including RTC) at xinit.port5.com
What you need to do is:-
[0] Set bits 0-3 of Status Register A to 0110b
[0] Set bit 6 of Status Register B to 1
[0] Read status register C after every interrupt. Bit 6 of Status Register C will be set if the interrupt was the periodic interrupt (set at 1024Hz)
Hope this helps
Thanx but I already know that. And as you can see, I set bit 0-3 to 0110...
But surely if you are only resetting the speed you leave everything else the same so surely OR al, 0110b would suffice instead of the and and or instructions. Off the top of my head the following should all that's required to enable ONLY the periodic interrupt at 1024Hz.
mov al, 0x0A
out 0x70, al
mov al, 0110b
out 0x71, al
mov al, 0x0B
out 0x70, al
in al, 0x71
and al, 10001111b
or al, 01000000b
mov bl, 0x0B
out 0x70, bl
out 0x71, al
Therx wrote:
But surely if you are only resetting the speed you leave everything else the same so surely OR al, 0110b would suffice instead of the and and or instructions.
Or will only set the bits that is set. It will not touch the zeros... then al could become 0111b or something else unless I use and to zero the bits I want to have zeroed... (sorry for the loosy explanation... is so damn tired right now... and high on coffee...)
In Al,70h
And Al,10000000b
Add Al,0xB
Out 70h,Al
Jmp short $+2
In Al,71h
This seems to be the best code. It reads the NMI-info, zero all the other bits and add the port wanted etc...
And now back to the RTC... I did mistake the RTC-interrupt (IRQ8)with the timer interrupt (IRQ0) so now it has the speed I like... However, if I do anything else than increasing a counter, the code fails (the RTC-interrupt is called alot of times, and it looks like it doesn't return and then the kernel takes command and the RTC is never called again...)...
I wants to test if I should update the clock being displayed and that code worked before, when I used the timer interrupt... well back to coding...
Push Eax
Push Esi
Xor Eax,Eax
Mov Al,[LEDCounter]
And Al,00000011b
Mov Esi,LEDBitmap
Add Esi,Eax
Inc Al
Mov [LEDCounter],Al
Call WaitForThe8042_Command
Mov Al,0xED
Out 0x60,Al
Call WaitForThe8042_Command
Lodsb
Out 0x60,Al
Pop Esi
Pop Eax
WaitForThe8042_Command:
Push Eax
WaitForThe8042_Command_Wait:
In Al,0x64
Test Al,00000010b ; Check if the input buffer is full
Jnz WaitForThe8042_Command_Wait
Pop Eax
Ret
Peter, the code you have commented out: is this keyboard related code? Because of port 0x60 and port 0x64. What do you want to do with the keyboard leds?
command 0xed is as far as i remember to instruct the keyboard controller chip to set the leds. to do this you transmit the led-bitmap after having issued the command successfully.
Why do you want to do this in the rtc-interrupt code?
in al, 70h ;Get current 70h
and al, e0h ;Discard lower 5 bits because we are just allowed to use them
or al, 0ah ;Byte index we will get from cmos ram.
out 70h, al ;Send index to 70h
in al, 71h ;Get needed info from cmos.
beyond infinity:
Yupp the code is for setting the leds. I thought it would be cool to have flashing leds so I put the code there... I will not have it there later on... I just want to know why it don't work when the code is there so I know what I'm doing wrong...
Ozguxxx:
I understood that after struggling with it a while
But why only the 5 lower bits and not 7? NMI is enabled/disabled by setting/clearing bit 7...
beyond infinity wrote:
To tell this, I 'll have to examine the code at home.
One question:
what is the lodsb for? Doesn't it suffice to write the bitmap in LEDBitmap to the port to set the led's?
That is becuase I use LEDCounter as an index in a string containing four bytes with the appropriate bitmap for the LED. If the counter is zero, the first bitmap is chosen and sent etc...
I designed that routine because I got so tired of having alot of Cmp-commands to test for each possibility and then send the appropriate bitmap.
The idea to scroll throu a set of bitmaps is good.
I also see where you take care that the counter never gets larger than 3. I like those tricks.
these commands:
Test Al,00000010b ; Check if the input buffer is full
Jnz WaitForThe8042_Command_Wait -> shouldn't it be "JNE waitforthe8042_command"? because you compare for equality? Possible Endless loop?