Trying to turn on leds in windows or real mode(at bootstrap)

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.
Post Reply
MarcoAlves

Trying to turn on leds in windows or real mode(at bootstrap)

Post by MarcoAlves »

Hi all.

I'd read a lot of about 8042 microcontroller. This because I'm making my
own bootloader and I need understand on how to enable a20 gate. But,
before I try to enable the a20 gate, I'm trying something more simple,
IMHO, i.e., trying to turn on all led indicators.

But I have few questions:
Is the 8042 INSIDE the keyboard case?
When I make a comand to 60h, the command is received by 8042?
When I make a command to 64h, the command is received by motherboard onboard microcontroller?

reference: http://www.arl.wustl.edu/~lockwood/clas ... HEADING1-5

Also, the following code is my attempt to turn on leds in windows or
real mode (in my bootloader). It doesn't works. Can someone help me?

In the case of testing the code in my boot loader, I just include the
code via inc directive after my "Hello Word" message.

I already read other articles in the forum about enable keyboard leds and already try them, but without success.

note: I have a notebook. But I think that this does not change anything.

Code: Select all

; Turn on all leds of the keyboard.

ORG 0x100 ; Remove it in case of it is placed in bootloader.

turnOnLeds:
        ;This subroutine will turn on led indicators in the keyboard controller.
        ;Takes no arguments. Returns 0 in AX register on success, -1 on failure.
        ;Written for use in 16-bit code.

; Status Register
STATUS_PORT equ 0x64
KBD_OUT_BUF equ 0x60

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Symbolic constants definition

; Status Register Bits Names
SR_BIT0_OUTPUT_BUFFER    equ 0 ; 0->has no data for system; 1->has data for system
SR_BIT1_INPUT_BUFFER     equ 1 ; 0->has no data for 8042; 1-> has data for 8042
SR_BIT2_SYSTEM_FLAG      equ 2 ; system flag (set to 0 after power on reset)
SR_BIT3_COMMAND_DATA     equ 3 ; type of information in input register. 1->command; 0->data
SR_BIT4_ENABLED_DISABLED equ 4 ; 1->keyboard enabled; 2-> keyboard disabled (via switch)
SR_BIT5_TRANSMIT_TIMEOUT equ 5 ; 1->transmit timeout
SR_BIT6_RECEIVE_TIMEOUT  equ 6 ; 1-> receive timeout
SR_BIT7_PARITY           equ 7 ; 1-> even parity; 0->odd parity

; Keyboard Commands
KB_LED_CMD equ 0xED

; Keyboard Led Indicators
KB_CAPS_LOCK    equ 001b
KB_NUM_LOCK     equ 010b
KB_SCROLL_LOCK  equ 101b
;KB_ALL_LEDS     equ KB_CAPS_LOCK | KB_NUM_LOCK | KB_SCROLL_LOCK
KB_ALL_LEDS     equ 111b
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

pusha                           ; Pushes the contents of the general-purpuse registers
                                ; onto the stack following order: AX, CX, DX, BX, BP, SP
                                ; (original value), BP, SI and DI. The value pushed for
                                ; the SP register is its value before prior to pushing
                                ; the first register.

cli                             ; Disable interrupts

; Wait for the keyboard controller to be ready for a command
xor ax,ax                       ; Clear ax
.commandWait1:
in   al,STATUS_PORT              ; Reads the 8042 status register
bt   ax,SR_BIT1_INPUT_BUFFER     ; Test if command buffer is full
jc   .commandWait1               ; Input buffer is full. Try again.

mov  al,KB_LED_CMD               ; Tell 8042 we wanna change the LEDs
out  KBD_OUT_BUF,al              ; Send the command

.wait:
xor  ax,ax
in   al,STATUS_PORT
bt   ax,SR_BIT1_INPUT_BUFFER     ; Test if command came through
jc   .wait

xor  ax,ax
mov  al,KB_ALL_LEDS              ; Tell 8042 the option byte
out  KBD_OUT_BUF,al              ; Set all LED's to ON

sti                             ; Re-enable interrupts

popa                            ; Pops words from the stack into the general-purpose
                                ; registers. The registers are loaded in the following
                                ; order: DI, SI, BP, BX, DX, CX and AX. The value on
                                ; the stack for the SP register is ignored. Instead,
                                ; the SP register is incremented after each register
                                ; is loaded.

ret

;------------------------------------------------------------;
; keyboard wait                                              ;
; Wait for the keyboard controller to be ready for a command ;
;------------------------------------------------------------;
;.kbd_wait:
;jmp  $+2
;in   al,STATUS_PORT
;test al,1
;jz   .ok
;jmp  $+2
;in   al,KBD_OUT_BUF
;jmp  .kbd_wait

;.ok:
;test al,2
;jnz  .kbd_wait
;ret
Thx in advance.

Best regards,
Marco Alves.
viral

Re:Trying to turn on leds in windows or real mode(at bootstr

Post by viral »

I already read other articles in the forum about enable keyboard leds and already try them, but without success.
Can you show post from where you took the codes or inspired from. Here are my codes, they work well on desktop pc.

Code: Select all

void Keyboard :: waitForReady(void)
{
    volatile long i = 0x10000; //max tries for Ready
    while (i-- && (inportb(0x64) & 0x02));
}
void Keyboard :: sendData(unsigned char data)
{
       waitForReady();//MicroDelay((unsigned long) 10);
       outportb(0x60, data);
}
void updateLed(unsigned char led)
{
   console.sendData(0xED);
   console.sendData(led);         //update led status
}
note: I have a notebook. But I think that this does not change anything.
well I dont know about this.. never tried my OS in notebook..
User avatar
Pype.Clicker
Member
Member
Posts: 5964
Joined: Wed Oct 18, 2006 2:31 am
Location: In a galaxy, far, far away
Contact:

Re:Trying to turn on leds in windows or real mode(at bootstr

Post by Pype.Clicker »

MarcoAlves wrote: Hi all.

I'd read a lot of about 8042 microcontroller. This because I'm making my
own bootloader and I need understand on how to enable a20 gate. But,
before I try to enable the a20 gate, I'm trying something more simple,
IMHO, i.e., trying to turn on all led indicators.

But I have few questions:
Is the 8042 INSIDE the keyboard case?
When I make a comand to 60h, the command is received by 8042?
When I make a command to 64h, the command is received by motherboard onboard microcontroller?
Aah. The great mystery of 8042.

The keyboard controller is not in your keyboard case. i mean, not the 8042. there's another controller chip in the keyboard but it does rather dull job (of scanning keystrokes and transmitting scancodes through the wire) compared to the 8042.

No, the 8042 -- which replace another set of chips in the initial PC, including a 8255 parallel I/O controller -- is now a "logic block" inside of your chipset. That explain why it can have control over the A20 line, for instance. Now when you give it a command to turn on/off leds, what you actually do is triggering microcode on the emulating chip that will send proper command code over the keyboard cable to make the "dull chip" turn leds on.

I'm not surprised Windows doesn't let you toy with that: once windows run, it gets in control of hardware and -- at best -- makes DOS programs believe they're still in control (e.g. if you say "turn led on" and then check "are leds on", the fake hardware will say "okay: it's on", but the real led may not have lit).

About the A20 gate, we have code samples in the OSFAQ. Make sure you follow a good tutorial there, because there are plenty of methods, most working only on specific systems.
If you need to do experiments from a running Os rather than messing with your own system, probably creating a boot disk with MS-DOS or FreeDOS will be better than operating from Windows. For most of the tasks, an emulator will do great job too (it will for A20 gate, for instance, but i'm unsure for LEDs -- i mean you may not have a visual feedback).
blip

Re:Trying to turn on leds in windows or real mode(at bootstr

Post by blip »

(Eh Pype.Clicker posted while composing but I'll post what I've got anyway.)

The KBC is not integrated into the keyboard itself but instead the computer's motherboard, and the original 8042 didn't have an auxilliary interface for mice as KBCs today do. There are commands that you can send to the KBC or its peripherals, the keyboard and mouse, and similarly receive data back usually being signalled by an IRQ (you can turn them off if you want but almost always people want them on).

Sending data to port 64h sends the byte as a command to the KBC and sending to 60h by default sends it to the keyboard over the serial line. To send a byte to the mouse you have to send a certain command first to the KBC to tell it that the byte is for the auxillary device, the command must be sent before every byte you wish to send to it. You receive data through port 60h and KBC status through port 64h.

Astronomically by far the most typical configuration of computers using a keyboard and PS/2 mouse has the keyboard plugged into the "primary" port and the mouse in the auxilliary port. They have the same connector and same protocol but the only reason you can't use two PS/2 keyboards is that most OSes are hard-wired to look for the keyboard on the primary port and the mouse on the auxilliary port. Using a mouse in the primary port is tricky for some systems' hardware though because not all KBCs act like the 8042 + an auxilliary port. Some automatically perform scancode set translation within the KBC rather than telling the keyboard to switch scancode sets, and this translation would totally corrupt incoming mouse data. Here's something you might find interesting on the topic. Hot-swapping is also something else that can be done with more advanced tricks but the system wasn't designed for it and it can potentially cause damage, but personally I've never had a problem.
MarcoAlves

Re:Trying to turn on leds in windows or real mode(at bootstr

Post by MarcoAlves »

Hi.

I get it. It's amazing. And, I also made a code that enables the A20 gate! heeh.

I will put the code here soon.

Thx a lot!
Post Reply