UMBC CMSC 211 Fall 1999

CSEE | 211 | 211 F'99 | lectures | news | help

Parallel Ports LPT1 - LPT3 (Printer Output)

There can be three printers on a PC (four on a PS/2), however the number on a given system can be different from system to system. There is a reference to a parallel port, which refers to the plug where the printer cable attaches, and there are PC ports which are used to talk to a device. LPT1 uses PC ports 378h to 37Bh. Every printers port has its own adapter, which is controlled by by three registers, available through the corresponding I/O ports. The I/O ports belonging to a parallel port have sequentially increasing address, the first of swhich is referred to as the base address of a corresponding parallel port. The base address for LPT1 is stored in the BIOS data area at locatiion 0040h:0008h. If the value of the base address is zero, then the port is not installed. There is also a Configuration Word at 0040h:0010h, whose bits 14-15 holds the number of parallel ports installed.

The three parallel port registers are:

Levels of Access to the Printer

There are three levels of mastering the hardware:
Logical level MS-DOS service available through functions of interrupt 21h
Basic level BIOS service available through interrupt 17h
Low level Controlling the printer ports directly
The logical level is what high-level languages use to implement I/O. This allows the programmer to output strings and not worry about the details.

The basic level allows you to programmically check on the status of things and to provide a different type of control, instead of relying on the standard DOS functions.

The low level is the most powerful and most difficult. In the case of the printer, there is not too much different in low level and the basic level, except that there can be a slight improvement in speed.

Mouse Input

When the mouse is moved or when its keys are presed, signals are generated. They are accepted by the mouse driver and used for controlling a special screen pointer called the mouse cursor. Key presses must also include the information about which key was pressed.

Programs which support the mouse must be capable of receiving and interpreting the signals generated by the mouse. There are different types of mice, and each requires a unique driver.

All signals generated by a mouse could be processed in a user program, however very few applicaitons actually do this. Normally, the program uses the servcies of the mouse driver.

The Mouse Driver

Interrupt 33h is used for as the handler for the mouse service functions. Old versions of the operating system did not have an interrupt handler for this and the interrupt table pointed to 0000h:0000h.

Make sure that if you are programming with a mouse, that you don't call the null address!

An application program that uses a mouse gets information about its state and location and performs a relevant action. One of the most common uses of the mouse in applications is for selecting an item in a menu. This process involves the following steps:

The mouse cursor is generated by the mouse driver that changes its location as you move the mouse. "When it is moved, the mouse generates short impulses called mickeys (christened by Bill Gates). The number of mickeys per inches is dependent on how the mouse was built and typically ranges from 200 to 400 mickeys per inch. Usually, the drivers moves the cursor by 1 pixel per mickey horizontally and 2 pixes per mickey vertically.

;  Program PMouse2 ( Chapter 10 )
;  The demo program for mouse (the menu selection, Text Mode)
;  Author:  A.I.Sopin, Voronezh University. 1993
;  The interrupt 33h (mouse service) is used
;  Mouse driver must be installed

        .MODEL  SMALL
        .STACK  100h


BELL    EQU     07      ;  sound signal
LF      EQU     10      ;  Line Feed
CR      EQU     13      ;  Carriage Return
TEXT0   DB      " The MOUSE demo program  (INT 33h). "
        DB      "  Press any key to continue...", BELL, CR, LF, "$"
TEXT1   DB      " The mouse driver is not installed !!!."
        DB      "  Press any key...", BELL, CR, LF, "$"
TEXT2   DB      " An active mouse driver found."
        DB      "  Press any key...", BELL, CR, LF, "$"
TEXT3   DB      'The menu command selection using the mouse (text mode).'
Ltxt3   EQU     $-TEXT3
TEXT8   DB      "Select Command and press Left Button:"
Ltxt8   EQU     $-TEXT8

TEXT10  DB      "1 - Command one  "
Ltxt10  EQU     $-TEXT10
TEXT11  DB      "2 - Command two  "
Ltxt11  EQU     $-TEXT11
TEXT12  DB      "3 - Command three"
Ltxt12  EQU     $-TEXT12
TEXT13  DB      "4 - Command four "
Ltxt13  EQU     $-TEXT13
TEXT14  DB      "5 - Command five "
Ltxt14  EQU     $-TEXT14
TEXT15  DB      "6 - Exit         "
Ltxt15  EQU     $-TEXT15

TXT3L   DB      "Left button pressed.  Command  "
NumSel  DB      20h
        DB       "   selected."
        DB      BELL, "$"

VMODE   DB      0                       ;  video mode saved
ATTR    DB      0                       ;
ROW0    DB      0
COL0    DB      0
CX0     DW      0
DX0     DW      0


OutMsg  MACRO   Txt                     ;=======   output text message
        lea     dx,Txt                                             ;  adders of message
        mov     ah,09h                  ;  function 09h - output text string
        int     21h                     ;  DOS  service call

WaitKey MACRO                           ;=======   Wait for a key pressed
        xor     ah,ah                   ;  function 0 - wait for key pressed
        int     16h                     ;  BIOS keyboard service

SetCurs MACRO   Row,Column              ;=======   Move the cursor
        mov     ah,2                    ;  function 02h - set cursor position
        xor     bh,bh                   ;  video page 0 is used
        mov     dh,&Row                 ;  cursor row
        mov     dl,&Column              ;  cursor column
        int     10h                     ;  BIOS vide service call

PutStr  MACRO   Row,Column,Text,Leng,Attrib
        Local   M0
        push    si
        mov     cx,Leng                 ;  string length
        lea     si,Text                 ;  DS:SI - address of text string
        mov     dl,Column               ;  initial position (column)
        cld                             ;  process strings from left to right
;  Outputting one character
M0:     SetCurs Row,dl                  ;
        lodsb                           ;  AL - character to be output
        mov     bl,Attrib               ;  BL - attribute
        mov     ah,9                    ;  function 09 - output char+attr
        xor     bh,bh                   ;  video page 0 is used
        push    cx                      ;  save cycle counter
        mov     cx,1                    ;  number of characters output
        int     10h                     ;  BIOS video service call
        pop     cx                      ;  restore cycle counter
        inc     dl                      ;  next position for output
        loop    M0                      ;  next cycle step
        pop     si                      ;


        mov     ah,0Fh                  ;  function 0Fh - get video mode
        int     10h                     ;  BIOS video service call
        mov     VMODE,al                ;  save current video mode
        mov     ah,0                    ;  function 0 - set video mode
        mov     al,3                    ;  80x25  Text
        int     10h                     ;  BIOS video service call
;  Output initial message
        OutMsg  TEXT0                   ;  output initial message
;  check for mouse driver present
        mov     ax, 03533h              ;  function 35h - get interrupt vector
        int     21h                     ;  DOS service call
        mov     ax,es                   ;  segment address of handler
        or      ax,bx                   ;  AX - segment .OR. offset of int 33
        jz      Nomouse                 ;  if full adders is 0 - no mouse
        mov     bl,es:[bx]              ;  get first instruction of handler
        cmp     bl,0CFh                 ;  is this IRET instruction?
        jne     Begin                   ;  if not - driver installed

        OutMsg  TEXT1                   ;  output message "driver not found"
        WaitKey                         ;  wait for key pressed
        jmp     Exit                    ;  Exit program


Begin:  OutMsg  TEXT2                   ;  output message "driver installed"
        WaitKey                         ;  wait for key pressed


;  Initialize mouse and report status (function 0 of INT 33h)
        xor     ax,ax                   ;  Initialize mouse
        int     33h                     ;  mouse service call
        cmp     ax,0                    ;  is mouse installed?
        jnz     Clear25                 ;  if so, pass to function 10
        jmp     Exit                    ;  if not, exit program

;  Fill the screen (yellow character on blue background)
Clear25:SetCurs 0,0                     ;  cursor to left upper corner
        mov     ah,9                    ;  function 09h - output char+attr
        xor     bh,bh                   ;  video page  0 is used
        mov     al,20h                  ;  character to be output
        mov     bl,1Eh                  ;  attribute - yellow on blue
        mov     cx,2000                 ;  number of characters to be output
        int     10h                     ;  BIOS video service call


;  Output the header and the menu text onto the screen
        PutStr   2,16,TEXT3, Ltxt3, 1Eh
        PutStr   8,20,TEXT8, Ltxt8, 1Eh
        PutStr  10,20,TEXT10,Ltxt10,1Fh
        PutStr  11,20,TEXT11,Ltxt11,1Fh
        PutStr  12,20,TEXT12,Ltxt12,1Fh
        PutStr  13,20,TEXT13,Ltxt13,1Fh
        PutStr  14,20,TEXT14,Ltxt14,1Fh
        PutStr  15,20,TEXT15,Ltxt15,1Fh
        SetCurs 25,80                   ;  move cursor out of screen


;  Function 10 - define text cursor
Func10: mov     ax,10                   ;  define text cursor
        xor     bx,bx                   ;  software cursor is used
        mov     cx,0FFFFh               ;  screen Mask
        mov     dx,4700h                ;  cursor Mask
        int     33h                     ;  mouse service call


;  Function 1 - show the mouse cursor
Func1:  mov     ax,1                    ;  function 01 - show mouse cursor
        int     33h                     ;  mouse service call


;  Determining mouse keys pressed
Func3:  mov     ah,1                    ;  function 01h - check keyboard buffer
        int     16h                     ;  BIOS keyboard service
        jz      ContF3                  ;  if no key pressed, continue
        jmp     Exit                    ;  exit if key pressed
ContF3: mov     ax,3                    ;  func. 03 - button status and location
        int     33h                     ;  mouse service call
        mov     CX0,cx                  ;  save  X coordinate (column)
        mov     DX0,dx                  ;  save  Y coordinate (row)
        test    bx,1                    ;  left button pressed?
        jnz     X_Range                 ;  OK !
        jmp     short Func3             ;  no button pressed - check again
;  Check horizontal cursor location

X_Range:mov     ax,CX0                  ;  X coordinate (Column)
        mov     cl,3                    ;  number bits to shift
        shr     ax,cl                   ;  shift by 3 - divide by 8
        cmp     ax,20                   ;  cursor on the left ?
        jb      Func3                   ;  not - continue check
        cmp     ax,36                   ;  cursor on the right?
        ja      Func3                   ;  not - continue check
;  Check vertical cursor location

Y_Range:mov     ax,DX0                  ;  X coordinate (Column)
        mov     cl,3                    ;  number bits to shift
        shr     ax,cl                   ;  shift by 3 - divide by 8
        cmp     ax,10                   ;  cursor on the top ?
        jb      Func3                   ;  not - continue check
        cmp     ax,15                   ;  cursor on the bottom?
        ja      Func3                   ;  not - continue check

;  report the number of the command selected
        mov     ax,DX0                  ;  Y coordinate (Row)
        mov     cl,3                    ;  number bits to shift
        shr     ax,cl                   ;  shift by 3 - divide by 8
        cmp     ax,15                   ;  line 15 (Exit) ?
        je      Exit                    ;  if so - finish
        sub     ax,9                    ;  number of command selected
        or      al,30h                  ;  convert to ASCII character
        mov     NumSel,al               ;  put number to output message
        SetCurs 17,20                   ;  move cursor
        OutMsg  TXT3L                   ;  output message "command selected"
        jmp     short Func3             ;  check again


;  Terminate program and exit to DOS
Exit:   mov     al,VMODE                ;  remember video mode on entry
        mov     ah,0                    ;  function 0 - set video mode
        int     10h                     ;  BIOS video service
        Call    CLRKEY                  ;  clear keyboard buffer
        mov     ax,4C00h                ;  function 4Ch - terminate process
        int     21h                     ;  DOS service call

;   This procedure clears the keyboard buffer

CLRKEY  PROC    NEAR uses ax es
        mov     ax,40h                  ;  address of BIOS data segment
        mov     ES,ax                   ;  ES points to BIOS data
        cli                             ;  no interrupts - system data modified
        mov     ax,ES:[1Ah]             ;  buffer head printer
        mov     ES:[1Ch],ax             ;  clear buffer (head ptr = tail ptr)
        sti                             ;  buffer cleared - allow interrupts

The Serial Ports - COM X

Parallel transfers are done with all bits being transmitted at the same time, with each bit being transferred down a separate wire in the cable. Serial transfers are done by sending one bit at a time down the same wire.

Sending or receiving one byte of data through the serial channel actuall involves transferring the following sequence of bits:

This transfer takes place at a speed (measured in bauds).

A special chip, the Intel UART8250 (Universal Asynchronous Receiver Transmitter) was designed to support serial data transfers. Access to this chip is thorough the I/O ports.

MS-DOS support two basic communications ports - COM1 and COM2. Their base addresses are stored in the BIOS data area at 0040:0000h (COM1) and 0040:0002h (COM2). The ports used by COM1 and COM2 are not fixed, but 3F8h and 2F8h are common, but so is the reverse. Alway get the port numbers from the BIOS data area. Many different devices can be connected via the serial ports.

The 8250 chip is programmed by 10 one-byte registers, available through the corresponding I/O ports. Some registers are write-only, some are read only and the remainder can be both.

The Asynchronous Adapter Registers
Port Mode value DLAB Meaning
3F8h OUT 0 Transmitter holding register
3F8h IN 0 Receiver holding register
3F8h OUT 1 Divisor latch (low byte)
3F9h OUT 1 Divisor latch (high byte)
3F9h OUT 0 Interrupt enable register
3FAh IN   Interrupt identification register
3FBh OUT   Line control register
3FCh OUT   Modem control register
3FDh IN   Line status register
3FEh IN   Modem status register

This range covers only 7 addresses, you can increase the number of registers actually available to 10 by setting the 7th bit of the line control register (3FBh). This bit is called DLAB - Divisor Latch Access Bit).

Levels of controlling the serial ports

The three ways of controlling ports are: The MS-DOS service provides function 40h (Write File with Handle) of interrupt 21h. This method treats the communications port as a standard file named AUX with a logical number (descriptor) equal to 3. (This is only for COM1.) it is set to 2400 baud with no parity control, one stop bit and 8 bits per symbol.

You can use the BIOS service through interrupt 14h. These functions allow you to initialize the port, set parameters for transferring data such as number of stop bits, the type of parity control and the speed of transfer. however, it will only allow you to set the speed to 9600 baud.

Low-level programming lets you use all the UART 8250 chip facilities, including working with the transfer speed to 115K and over, but requires that the hardware interrupt related to communications ports be processed by your program.

Peripheral Interface - PPI

The PPI was originally based on the 8255A chip, and is used for controlling the keyboard, the internal sound generator, and for getting information about the system configuration.

The 8255A chip is controlled by the ports that are attached to it.

The Programmable Peripheral Interface
Denotation Address Type Purpose
Port A 60h R/W Keyboard input
Port B 61h R/W Configuratin info, speaker and keyboard control
Port C 62h R Get system information
  63h R Mode control for ports A-C
  h4h R Keyboard status (AT or PS/2)

Port B of PPI - The Port 61h
Bit Meaning
0 Timer 2 gate (speaker)
1 Timer 2 data
2 Must be 0
3 1 = read high switches; 0 = read low swithces
4 0 = enable RAM parity checking; 1 = disable
5 0 = enable I/O channel check
6 0 = hold keyboard clock low
7 0 = enable keyboard; 1 = disable keyboard

Contents of PPI Port A (Bit 7 of Port B is set)
Bit Contents
0 0 - no floppy drives
1 Not used
2-3 The number of memory banks on the system board
4-5 Display mode
  11 = monochrome
  10 - color 80x25
  01 - color 40x25
6-7 PC: The number of floppy disk drives

The Contents of Port C
Bit Meaning
0 Values of DIP switches as in Equipment List
1 "
2 "
3 "
4 Must be 0
5 If set - Time channel 2 out
6 if set - I/O channel check
7 if set RAM parity check error occurred

The Interrupt Controller - Intel 8259

The 8259 is also known as the PIC (Programmable Interrupt Controller) and it ensures that hardware interrupts are processed according to their priorities. The interrupt singal is generated by the hardware and sent to the microprocessor to inform it that the hardware state has changed and certain operations need to be performed.

In order to handle multiple interrupts occurring at the same time, there are 8 or 16 interrupt levels (using one or two 8259's). We know them as IRQ0 - IRQ7 and IRQ8 - IRQ15. The smaller the number, the higher the priority is for that interrupt. The highest priority IRQ0 is for the system timer. IRQ1 is for the keyboard. There is an interrupt vector in the BIOS for each IRQ. You can disable some or all of the interrupts. You disable all of them with the CLI (Clear Interrupt) and enable all of them with STI (Set Interrupt). NOTE: IRQ2 (I/O channel) can not can not be disabled and is called a non-maskable interrupt.

There is an Interrupt Mask Register (IMR) that allows you to disable only certain interrupts. The least significant bit is IRQ0 and if it is set to 1, the interrupt is disabled. The first 8 interrupts are controlled through port 21h and the second 8 are controlled through port 0A1h.

The Hardware Interrupts
Level VectorEnable MaskDisable MaskMeaning
IRQ1 09h XXXX XX0X XXXX XX1X Keyboard
IRQ2 0Ah XXXX X0XX XXXX X1XX I/O channel
IRQ6 0Eh X0XX XXXX X1XX XXXX FDD controller
IRQ8 70h XXXX XXX0 XXXX XXX1 Real-time Clock
IRQ9 71h XXXX XX0X XXXX XX1X Translated into IRQ2
IRQ10 72h XXXX X0XX XXXX X1XX Reserved
IRQ11 73h XXXX 0XXX XXXX 1XXX Reserved
IRQ12 74h XXX0 XXXX XXX1 XXXX Reserved
IRQ13 75h XX0X XXXX XX1X XXXX Math co-processor
IRQ14 76h X0XX XXXX X1XX XXXX HDD controller
IRQ15 77h 0XXX XXXX 1XXX XXXX reserved

The Programmable Timer

The timer has three channels and operate at 1.193Mhz under control of the 8284A generator. The channels are available through ports 40h, 41h, and 42. The command register is available through port 43h.
The Programmable Timer Command Register
Bit Meaning
0 0 - binary data, 1 - BCD
1-3 Number of mode used (000-101)
4-5 Operation Type
  00 - send the value of counter
  01 - read/write high byte
  10 - read/write low/byte
  11 - read/write both high and low bytes
6-7 Number of channel to be programmed

Channel 0 is used by teh system clock to calculate the time of day. It is programmed for 18.2 pulses per second (called ticks) and stored in the BIOS data area at 0040h:006Ch. Every pulse initiates a timer interrupt 8h (IRQ0). Don't mess with this one!

Channel 1 is responsible for refreshing RAM and counts the pulses during disk operations, so that it can reset the timer counter upon completion of an operation. This is also not a good one to mess with.

Channel 2 (port 42h) is connected to the computer's speaker and issues square wave pulses used to make sounds. You can change the sound frequency with this channel.The 8255 chip, (PPI) is also involved in generating sound and that bits 0 and 1 of port 61h also control the speaker.

Example program

;  Program Sound ( Chapter 10 )
;  The program for outputting a sound of prescribed tone
;  Author: A.I.Sopin   Voronezh, Russia   1990 --- 1992
;  ------
;  Call from Assembler programs:
;       Call SOUND
;  Parameters passed through the registers:
;  Frequency    - DI register (from   21  to  65535  hertz)
;  Duration      -BX register (in hundredth of second)
;  Registers  AX, CX, DX, DS, ES, SI  are retained by the program 
         push   ax
         push   cx
         push   dx
         push   ds
         push   es
         push   si
         in     al,61h            ;  Read current port mode B (8255)
         mov    cl,al             ;  Save current mode
         or     al,3              ;  Switch on speaker and timer
         out    61h,al            ;
         mov    al,0B6h           ;  set for channel  2 (8253)
         out    43h,al            ;  command register  8253
         mov    dx,14h            ;
         mov    ax,4F38h          ;  divisor of frequency
         div    di                ;
         out    42h,al            ;  lower byte of frequency
         mov    al,ah             ;
         out    42h,al            ;  higher byte of frequency
;  Generation of sound delay 
         mov    ax,91             ;  multiplier  -  AX register !
         mul    bx                ;  AX =BX*91 (result in   DX:AX)
         mov    bx,500            ;  divisor, dividend in   DX:AX
         div    bx                ;  result in   AX, remainder in DX 
         mov    bx,ax             ;  save result
         mov    ah,0              ;  read time
         int    1Ah               ;
         add    dx,bx             ;
         mov    bx,dx             ;
Cycle:   int    1Ah               ;
         cmp    dx,bx             ;  Has time gone ?
         jne    Cycle             ;
         in     al,61h            ;  Read mode of port B (8255)
         mov    al,cl             ;  Previous mode 
         and    al,0FCh           ;
         out    61h,al            ;  Restore mode
;  Restoring registers and exit
Exit:    pop    si                ;
         pop    es                ;
         pop    ds                ;
         pop    dx                ;
         pop    cx                ;
         pop    ax                ;
         RETF                     ; exit from subroutine


CSEE | 211 | 211 F'99 | lectures | news | help