Using the 8254 Timer-Counter - PowerPoint PPT Presentation

About This Presentation
Title:

Using the 8254 Timer-Counter

Description:

... timer-ticks' into seconds ... For Channel 0 (the timer-tick' interrupt) the Latch is programmed ... and DIV to convert ticks' into seconds', like this: ... – PowerPoint PPT presentation

Number of Views:388
Avg rating:3.0/5.0
Slides: 23
Provided by: ProfessorA
Learn more at: https://www.cs.usfca.edu
Category:
Tags: counter | tick | timer | using

less

Transcript and Presenter's Notes

Title: Using the 8254 Timer-Counter


1
Using the 8254 Timer-Counter
  • Understanding the role of the systems 8254
    programmable Interval-Timer/Counter

2
Displaying Time-Of-Day
  • Algorithm steps
  • Get the count of timer-interrupts so far today
  • Convert these timer-ticks into seconds
  • Breakdown the total number of seconds today into
    Hours, Minutes, Seconds, and AM/PM
  • Convert numerical values into digit-strings
  • Output these results to the video terminal

3
Wheres the tick counter?
main memory
Number of timer-tick interrupts so far
today (longword at 0x0046C)
0x00500
ROM-BIOS DATA AREA
tick_count
0040006C
0x00400
Interrupt Vector Table (for real-mode)
0x00000
4
Getting the tick count
  • The ROM-BIOS interrupt-handler for the timer
    interrupt stores the tick-count as a 32-bit
    integer located at address 0x046C (its in the
    ROM-BIOS DATA AREA)
  • In real-mode, we can get it like this

xor ax, ax address segment zero mov ax,
fs using FS register mov fs0x046C,
eax copy tick-count to EAX mov eax,
total_ticks save in a local variable
segment-override prefix (segment used would be
ds)
5
Converting ticks to seconds
total_ticks_today
total_seconds_today
number of ticks-per-second
The number of ticks-per-second is based upon
the way the PCs timing hardware has been
programmed
6
The 8254 PIT
  • The 8254 Programmable Interval-timer is used by
    the PC system for (1) generating timer-tick
    interrupts (rate is 18.2 per sec), (2) performing
    dynamic memory-refresh (reads ram once every 15
    microseconds), and (3) generates beeps of PC
    speaker
  • When the speaker-function isnt needed, the 8254
    is available for other purposes

7
Input/Output frequencies
  • The input-pulses to each Timer-channel is a long
    established PC standard, based on the design of
    the chrystal oscillator chip 1,193,182
    pulses-per-second (Hertz)
  • The frequency of the output-pulses from any
    Timer-channel is determined by how that channels
    Latch was programmed

8
Three timer/counter channels
8284 PCLK
1193182 Hz
Channel 0
CLK0
OUT0
Interrupt IRQ0
GATE0
Port 0x61, bit 4
Channel 1
CLK1
OUT1
DRAM refresh
GATE1
Port 0x61, bit 5
CLK2
Channel 2
OUT2
GATE2
speaker
AND
Port 0x61, bit 0
8254 PIT
5 V
Port 0x61, bit 1
9
Counter decrements when pulsed
COUNT REGISTER
CLK
LSB
MSB
OUT
LSB
MSB
LATCH REGISTER
GATE
STATUS
TIMER/COUNTER CHANNEL
10
8254 Command-Port
7 6 5 4
3 2 1 0
CHANNEL
OUTPUT MODE
COMMAND
binary / BCD
Output Mode 000 one-shot level 001
retriggerable 010 rate-generator 011
square-wave 100 software strobe 101
hardware strobe
Counting Mode 0 binary 1 BCD
Channel-ID 00 chn 0 01 chn 1 10 chn 2
Command-ID 00 Latch 01 LSB r/w 10 MSB
r/w 11 LSB-MSB r/w
Commands are sent to the 8254 via io/port 0x43
11
Programming a PIT channel
  • Step 1 send command to PIT (port 0x43)
  • Step 2 read or write the channels Latch
  • via port 0x40 for channel 0
  • via port 0x41 for channel 1
  • via port 0x42 for channel 2

12
Standard BIOS programming
  • For Channel 0 (the timer-tick interrupt) the
    Latch is programmed during system startup with a
    value of zero
  • But the Timer interprets zero as 65,536
  • So the frequency of the output-pulses from
    Timer-channel 0 is equal to this quotient
  • output-frequency input-frequency /
    frequency-divisor
  • 1193182 / 65536 (approximately 18.2)

13
Consequently
  • To compute total_seconds from total_ticks
  • total_seconds total_ticks / ticks_per_second
  • total_ticks / (1193182 / 65536)
  • ( total_ticks 65536 ) / 1193183
  • We can use the Pentiums integer-arithmetic
    instructions MUL (multiply) and DIV (divide)

14
How MUL works
Before executing the MUL instruction
EAX
multiplicand (32-bits)
reg (or mem)
multiplier (32-bits)
32-bit operands
mull reg_or_mem
Heres the instruction
After executing the MUL instruction
product (64-bits)
EDX
EAX
64-bit product
15
How DIV works
Before executing the DIV instruction
dividend (64-bits)
EDX
EAX
64-bit dividend
reg (or mem)
divisor (32-bits)
32-bit operand
divl reg_or_mem
Heres the instruction
After executing the DIV instruction
two results (32-bits)
EDX
EAX
32-bit remainder
32-bit quotient
16
Implementing the conversion
  • So use MUL and DIV to convert ticks into
    seconds, like this

total_seconds ( total_ticks FREQ_DIVISOR
) / PULSES_PER_SEC mov total_ticks,
eax mov FREQ_DIVISOR, ecx mul ecx mov PULS
ES_PER_SEC, ecx div ecx mov eax,
total_seconds Now integer-quotient is in EAX,
and integer-remainder is in EDX
17
Time-Of-Day Format
HHMMSS am/pm
hours
seconds
morning or afternoon
minutes
So we need to compute four numerical values from
the total_seconds integer
18
Our four time-parameters
  • We use these arithmetical ideas
  • total_minutes ( total_seconds / 60 ) ss (
    total_seconds 60 )
  • total_hours (total_minutes / 60 ) mm (
    total_minutes 60 )
  • total_halfdays (total_hours / 12 ) hh
    (total_hours 12 )
  • Total_days ( total_halfdays / 2 ) xm
    total_halfdays 2

19
A subtle refinement
  • Our total_seconds value was gotten with an
    integer-division operation, so theres likely to
    be some round-off error
  • How can we be sure we use the closest integer
    to the actual quotient?
  • We should remember the rounding rule!
  • When remainder is equal or greater than 1/2 of
    divisor, quotient gets incremented

20
How to implement rounding?
  • There is more than one way to do it i.e., the
    amateurs way or the experts way
  • Knowledge of the Pentiums architecture and
    instruction-set can assist
  • The obvious method
  • if ( 2 remainder gt divisor ) quotient
  • But this uses a multiply and a conditional
    jump-instruction (inefficient!)

21
Avoiding inefficiency
  • Replace the multiply with an addition
  • Use subtract and add-with-carry instead of
    using compare and conditionally-jump

Recall quotient was in EAX, remainder was in
EDX, divisor was in ECX add edx, edx
doubles the remainder sub ecx, edx computes
2quotient divisor now carry-flag is clear
in case 2quotient gt divisor cmc
complement the carry-flag bit now carry-flag
is set in case 2quotient gt divisor adc 0,
eax add the carry-flag to the quotient So
this achieves the same effect as the rounding
rule, but wit no jump!
22
In-class exercise
  • Can you enhance our timeoday.s demo to make it
    more dramatic (and later useful) by creating a
    loop within its main routine, so it continues
    to read and display the time (until the user
    presses a key)
  • HINTS Use an INT-0x16 keyboard service to peek
    into the keyboard-queue, and omit the \n
    (newline) control-code from the report
    message-string
Write a Comment
User Comments (0)
About PowerShow.com