Oulun yliopisto - Etusivulle University of Oulu in English

ee.oulu.fi

Electrical and Information Engineering

University of Oulu > Faculty of Technology > Electrical and Information Engineering


tklab - courses 

[This page is CSS2 enabled. Your browser might not fully support it]

Spring 2004 - Exercise 2: Read Mouse Status and Blink Keyboard Leds

$RCSfile: exercise2.html,v $ $Revision: 1.4 $ $Date: 2004/04/21 11:06:06 $

Table of Contents

Description and Requirements of the Assignment

This assignment is the second voluntary exercise from which you may get an extra point for your test score for the spring exam. You may want to take a look at the work-in-progress introductory document about C before continuing with this assignment.

Your task is to implement a program, based on ex2-base.c, that uses the getmousestatus() function to see which button of the mouse the user has pressed and then blink (or light up) the keyboard leds according to the following table:

Button		Pressed			Released
======================================================
left		CapsLock Lit		CapsLock Dark
right		NumLock Lit		NumLock Dark
both		CapsLock Blinks		All Dark

The getmousestatus() function uses the bios interrupt 33,3 to acquire mouse status. The returned unsigned char value contains the BX register value. You should use the setleds() function provided to change led status.

INT 33,3 - Get Mouse Position and Button Status

 AX = 03

 on return:
 CX = horizontal (X) position  (0..639)
 DX = vertical (Y) position  (0..199)
 BX = button status:

         |F-8|7|6|5|4|3|2|1|0|  Button Status
           |  | | | | | | | +---- left button (1 = pressed)
           |  | | | | | | +----- right button (1 = pressed)
           +--+-+-+-+-+-+------ unused

 - values returned in CX, DX are the same regardless of video mode

User must be able to exit the program by pressing the key 'q' from the keyboard. No other user interaction must be required by the program during execution, with the exception of mouse button presses. An appropriate led blink rate is 2Hz. Use the PIT (8254) to produce a delay for the blinking (usage of dos.h delay() is not allowed!).

Led Status Command Byte (use this for setleds()!)

            |7-3|2|1|0| Keyboard Status Led Command Byte
              |  | | +--- Scroll-Lock led  (0=off, 1=on)
              |  | +---- Num-Lock led  (0=off, 1=on)
              |  +----- Caps-Lock led  (0=off, 1=on)
              +------- reserved (must be zero)
	      

8253/8254 PIT - Programmable Interval Timer

               
        Port 40h, 8253 Counter 0 Time of Day Clock (normally mode 3)
        Port 41h, 8253 Counter 1 RAM Refresh Counter (normally mode 2)
        Port 42h, 8253 Counter 2 Cassette and Speaker Functions
        Port 43h, 8253 Mode Control Register, data format:

        |7|6|5|4|3|2|1|0|  Mode Control Register
         | | | | | | | +---- 0=16 binary counter, 1=4 decade BCD counter
         | | | | +--------- counter mode bits
         | | +------------ read/write/latch format bits
         +--------------- counter select bits (also 8254 read back command)

      Bits
       76 Counter Select Bits
         00  select counter 0
         01  select counter 1
         10  select counter 2
         11  read back command (8254 only, illegal on 8253, see below)

      Bits
       54  Read/Write/Latch Format Bits
         00  latch present counter value
         01  read/write of MSB only
         10  read/write of LSB only
         11  read/write LSB, followed by write of MSB

      Bits
      321  Counter Mode Bits
        000  mode 0, interrupt on terminal count;  countdown, interrupt,
             then wait for a new mode or count; loading a new count in the
             middle of a count stops the countdown
        001  mode 1, programmable one-shot; countdown with optional
             restart; reloading the counter will not affect the countdown
             until after the following trigger
        010  mode 2, rate generator; generate one pulse after 'count' CLK
             cycles; output remains high until after the new countdown has
             begun; reloading the count mid-period does not take affect
             until after the period
        011  mode 3, square wave rate generator; generate one pulse after
             'count' CLK cycles; output remains high until 1/2 of the next
             countdown; it does this by decrementing by 2 until zero, at
             which time it lowers the output signal, reloads the counter
             and counts down again until interrupting at 0; reloading the
             count mid-period does not take affect until after the period
        100  mode 4, software triggered strobe; countdown with output high
             until counter zero;  at zero output goes low for one CLK
             period;  countdown is triggered by loading counter;  reloading
             counter takes effect on next CLK pulse
        101  mode 5, hardware triggered strobe; countdown after triggering
             with output high until counter zero; at zero output goes low
             for one CLK period

      Read Back Command Format  (8254 only)

        |7|6|5|4|3|2|1|0| Read Back Command (written to Mode Control Reg)
         | | | | | | | +--- must be zero
         | | | | | | +---- select counter 0
         | | | | | +----- select counter 1
         | | | | +------ select counter 2
         | | | +------- 0 = latch status of selected counters
         | | +-------- 0 = latch count of selected counters
         +----------- 11 = read back command

      Read Back Command Status (8254 only, read from counter register)

        |7|6|5|4|3|2|1|0|  Read Back Command Status
         | | | | | | | +--- 0=16 binary counter, 1=4 decade BCD counter
         | | | | +-------- counter mode bits (see Mode Control Reg above)
         | | +----------- read/write/latch format (see Mode Control Reg)
         | +------------ 1=null count (no count set), 0=count available
         +------------- state of OUT pin (1=high, 0=low)


        - the 8253 is used on the PC and XT, while the 8254 is used on the AT+
        - all counters are decrementing and fully independent
        - the PIT is tied to 3 clock lines all generating 1.19318 MHz.
        - the value of 1.19318MHz is derived from (4.77/4 MHz) and has it's
          roots based on NTSC frequencies
        - counters are 16 bit quantities which are decremented and then
          tested against zero.  Valid range is (0-65535).  To get a value
          of 65536 clocks you must specify 0 as the default count since
          65536 is a 17 bit value.
        - reading by latching the count doesn't disturb the countdown but
          reading the port directly does; except when using the 8254 Read
          Back Command
        - counter 0 is the time of day interrupt and is generated
          approximately 18.2 times per sec.  The value 18.2 is derived from
          the frequency 1.10318/65536 (the normal default count).
        - counter 1 is normally set to 18 (dec.) and signals the 8237 to do
          a RAM refresh approximately every 15.s
        - counter 2 is normally used to generate tones from the speaker
          but can be used as a regular counter when used in conjunction
          with the 8255
        - newly loaded counters don't take effect until after a an output
          pulse or input CLK cycle depending on the mode
        - the 8253 has a max input clock rate of 2.6MHz, the 8254 has max
          input clock rate of 10MHz

      Programming considerations:

          1.  load Mode Control Register
          2.  let bus settle (jmp $+2)
          3.  write counter value
          4.  if counter 0 is modified, an INT 8 handler must be written to
              call the original INT 8 handler every 18.2 seconds.  When it
              does call the original INT 8 handler it must NOT send and EOI
              to the 8259 for the timer interrupt, since the original INT 8
              handler will send the EOI also.

      Example code:

        countdown  equ  8000h ; approx 36 interrupts per second

           cli
           mov  al,00110110b  ; bit 7,6 = (00) timer counter 0
                              ; bit 5,4 = (11) write LSB then MSB
                              ; bit 3-1 = (011) generate square wave
                              ; bit 0 = (0) binary counter
           out  43h,al        ; prep PIT, counter 0, square wave & init count
           jmp  $+2
           mov  cx,countdown  ; default is 0x0000 (65536) (18.2 per sec)
                              ; interrupts when counter decrements to 0
           mov  al,cl         ; send LSB of timer count
           out  40h,al
           jmp  $+2
           mov  al,ch         ; send MSB of timer count
           out  40h,al
           jmp  $+2
           sti

(original datasheets from the HELPPC package)

Returning the Assigment

The exercise MUST be returned by sending a plain-text email to t k t 2 - i n b o x @ e e . o u l u . f i
You may attach one text file (the properly commented C source code). Word attachments etc. will be rejected. Remember to include your full name, date of birth and the year you started your studies. Deadline for returning this exercise is on wednesday 21.4.2004 at 16:00.

Example Solutions

Solution 1

This is just one possible solution. The main idea is that mouse status is checked every 50 milliseconds in order to improve the reactivity. It is possible to just run a blink cycle per one mouse poll, but delays are inevitable.

[This page is CSS2 enabled. Your browser might not fully support it]

 
  Webmaster