UMBC CMSC 211 |
The three parallel port registers are:
Bit | Meaning if set |
---|---|
0 | Timeout |
1-2 | Not used |
3 | I/O error |
4 | Printer is On-Line |
5 | Out of Paper |
6 | Acknowledge (if zero, normal setting) |
7 | Printer is not busy |
Bit | Meaning if set |
---|---|
0 | sending byte |
1 | CR treated as CR + LF |
2 | normal setting (reset printer when 0) |
3 | select printer |
4 | enable printe IRQ (IRQ 7 for LPT1) |
5 - 7 | not used |
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 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.
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.
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 ; ;*********************************************************************** NAME PMOUSE2 .DOSSEG .MODEL SMALL .STACK 100h ;---------------------------------------------------------- .DATA 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 ;---------------------------------------------------------- .CODE 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 ENDM WaitKey MACRO ;======= Wait for a key pressed xor ah,ah ; function 0 - wait for key pressed int 16h ; BIOS keyboard service ENDM 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 ENDM 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 ; ENDM ;------------------------------------------------------------------- .STARTUP 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 WaitKey ; 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 Nomouse: 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) Func0: 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 ret CLRKEY ENDP END
Sending or receiving one byte of data through the serial channel actuall involves transferring the following sequence of bits:
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.
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).
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.
The 8255A chip is controlled by the ports that are attached to it.
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) |
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 |
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 |
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 |
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.
Level | Vector | Enable Mask | Disable Mask | Meaning |
---|---|---|---|---|
IRQ0 | 08h | XXXX XXX0 | XXXX XXX1 | Timer |
IRQ1 | 09h | XXXX XX0X | XXXX XX1X | Keyboard |
IRQ2 | 0Ah | XXXX X0XX | XXXX X1XX | I/O channel |
IRQ3 | 0Bh | XXXX 0XXX | XXXX 1XXX | COM2 (AT), COM1 (XT) |
IRQ4 | 0Ch | XXX0 XXXX | XXX1 XXXX | COM1 (AT), COM2 (XT) |
IRQ5 | 0Dh | XX0X XXXX | XX1X XXXX | HDD (LPT2 for AT) |
IRQ6 | 0Eh | X0XX XXXX | X1XX XXXX | FDD controller |
IRQ7 | 0fh | 0XXX XXXX | 1XXX XXXX | LPT1 |
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 |
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.
;*************************************************************** ; 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 ; ; ; ;*************************************************************** PUBLIC SOUND CODE SEGMENT ASSUME CS:CODE SOUND PROC FAR 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 SOUND ENDP CODE ENDS END