System Programming Course Code: CS609
Cs609@vu.edu.pk
Lecture # 16
Sample Program using BIOS routines
Example:
#include<BIOS.H>
#include<DOS.H>
char ch1, ch2;
void initialize (int pno)
{
_AH=0;
_AL=0x57;
_DX=pno;
geninterrupt(0x14);
}
char receivechar (int pno)
{
char ch;
_DX = pno;
_AH = 2;
geninterrupt (0x14);
ch = _AL;
return ch;
}
The initialize () function initializes the COM port whose number is passed as parameter
using BIOS services. The recievechar() function uses the COM port number to receive a
byte from the COM port using BIOS services.
Virtual University of Pakistan 129
System Programming Course Code: CS609
Cs609@vu.edu.pk
void sendchar (char ch, int pno)
{
_DX = pno;
_AH = 1;
_AL = ch;
geninterrupt (0x14);
}
unsigned int getcomstatus (int pno)
{
unsigned int temp;
_DX = pno;
_AH = 03;
geninterrupt (0x14);
*((char*)(&temp)) = _AL;
*(((char*)(&temp)) + 1) = _AH;
return temp;
}
the sendchar() function sends a character to the COM port using BIOS service whose
number is passed as parameter. And the getcomstatus() function retrieves the status of the
COM port whose number has been specified and returns the modem and line status in an
unsigned int.
void main()
{
while(1) {
i = getcomstatus (0);
if (((*(((char*)(&i)) + 1)&0x20) == 0x20) && (kbhit()))
{
ch1 = getche();
sendchar (ch1, 0);
}
if ((*(((char*)(&i)) +1) & 0x01) == 0x01) {
ch2 = receivechar (0);
putch (ch2);
}
if ((ch1 == 27) || (ch2 ==27))
break;
}
}
Let’s suppose two UARTs are interconnected using a NULL modem
In the main () function there is a while loop which retrieves the status of the COM port.
Once the status has been retrieved it checks if a byte can be transmitted, if a key has been
Virtual University of Pakistan 130
System Programming Course Code: CS609
Cs609@vu.edu.pk
pressed and its is clear to send a byte the code within the if statement sends the input byte
to the COM port using sendchar() function.
The second if statement checks if a byte can be read from the COM port. If the Data
ready bit is set then it receives a byte from the data port and displays it on the screen.
Moreover there is another check to end the program. The program looks for an escape
character ASCII = 27 either in input or in output. If this is the case then it simply breaks
the loop.
Sample Program
This program does more or less the same as the previous program but the only difference
is that in this case the I/O is done directly using the ports and also that the Self Test
facility is used to check the software.
#include <dos.h>
#include <bios.h>
void initialize (unsigned int far *com)
{
outportb ( (*com)+3, inport ((*com)+3) | 0x80);
outportb ( (*com),0x80);
outportb( (*com) +1, 0x01);
outportb ( (*com)+3, 0x1b);
}
void SelfTestOn(unsigned int far * com)
{
outportb((*com)+4,inport((*com)+4)|0x10);
}
The initialize() loads the divisor value of 0x0180 high byte in base +1 and low byte in
base +0. It also program the line control register for all the required line parameters.
The SelfTestOn() function simply enables the self test facility within the modem control
register.
Virtual University of Pakistan 131
System Programming Course Code: CS609
Cs609@vu.edu.pk
void SelfTestOff(unsigned int far * com)
{
outportb( (*com)+4, inport((*com)+4) & 0xEf);
}
void writechar( char ch, unsigned int far * com)
{
while ( !((inportb((*com)+5) & 0x20) == 0x20));
outport(*com,ch);
}
char readchar( unsigned int far *com)
{
while (!((inportb((*com)+5) & 0x01)==0x01));
return inportb(*com);
}
The SelfTestOff() function turns this facility off. The writechar() function writes the a
byte passed to this function on the data port. The readchar() function reads a byte from
the data port.
unsigned int far *com=(unsigned int far*) 0x00400000;
void main ()
{
char ch = 0; int i = 1;int j= 1;
char ch2='A';
initialize( com);
SelfTestOn(com);
clrscr();
while (ch!=27)
{
if (i==80)
{
j++;
i=0;
}
Virtual University of Pakistan 132
System Programming Course Code: CS609
Cs609@vu.edu.pk
The main function after initializing and turning the self test mode on enters a loop which
will terminate on input of the escape character. This loop also controls the position of the
cursor such the cursor goes to the next line right after a full line has been typed.
if (j==13)
j=0;
gotoxy(i,j);
ch=getche();
writechar(ch,com);
ch2=readchar(com);
gotoxy(i,j+14);
putch(ch2);
i++;
}
SelfTestOff (com);
}
All the input from the keyboard is directed to the output of the UART and all the input
from the UART is also directed to the lower part of the screen. As the UART is in self test
mode the output becomes the input. And hence the user can see output send to the UART
in the lower part of the screen as shown in the slide below
hello how r u ? whats new about systems programming?
hello how r u ? whats new about systems programming?
Virtual University of Pakistan 133
System Programming Course Code: CS609
Cs609@vu.edu.pk
Sample Program using interrupt driven I/O
#include <dos.h>
#include <bios.h>
void initialize (unsigned int far *com)
{
outportb ( (*com)+3, inport ((*com)+3) | 0x80);
outportb ( (*com),0x80);
outportb( (*com) +1, 0x01);
outportb ( (*com)+3, 0x1b);
}
void SelfTestOn(unsigned int far * com)
{
outportb((*com)+4,inport((*com)+4)|0x18);
}
void SelfTestOff(unsigned int far * com)
{
outportb( (*com)+4, inport((*com)+4) & 0xE7);
}
void writechar( char ch, unsigned int far * com)
{
//while ( !((inportb((*com)+5) & 0x20) == 0x20));
outport(*com,ch);
}
char readchar( unsigned int far *com)
{
//while (!((inportb((*com)+5) & 0x01)==0x01));
return inportb(*com);
}
Virtual University of Pakistan 134
System Programming Course Code: CS609
Cs609@vu.edu.pk
unsigned int far *com=(unsigned int far*) 0x00400000;
unsigned char far *scr=(unsigned char far*) 0xB8000000;
int i =0,j=0;char ch;int k;
void interrupt (*oldint)();
void interrupt newint();
void main ()
{
initialize(com);
SelfTestOn(com);
oldint = getvect(0x0c);
setvect(0x0c,newint);
outport((*com)+1,1);
outport(0x21,inport(0x21)&0xEF);
keep(0,1000);
}
This si program is also quite similar to the previous one. The only difference is that in
this the I/O is performed in an interrupt driven patter using the Int 0x0C as the COM1
uses IRQ4. Also to use it in this way IRQ4 must be unmasked from the IMR register in
PIC. Also before returning from the ISR the PIC must be signaled an EOI code.
void interrupt newint()
{
ch= readchar(com);
if (i==80)
{
j++;
i=0;
}
if (j==13)
j=0;
k = i*2+(j+14)*80*2;
*(scr+k)=ch;
i++;
outport(0x20,0x20);
}
Virtual University of Pakistan 135
System Programming Course Code: CS609
Cs609@vu.edu.pk
•C:\>DEBUG
-o 3f8 41
-o 3f8 42
-o 3f8 56
-o 3f8 55
-q
C:\>
#include <bios.h>
#include <dos.h>
void interrupt (*oldint)();
void interrupt newint();
unsigned char far *scr= (unsigned char far
*)0xB8000000;
void initialize (unsigned int far *com)
{
outportb ( (*com)+3, inport ((*com)+3) | 0x80);
outportb ( (*com),0x80);
outportb( (*com) +1, 0x01);
outportb ( (*com)+3, 0x1b);
}
Virtual University of Pakistan 136
System Programming Course Code: CS609
Cs609@vu.edu.pk
void main (void)
{
oldint = getvect(0x0C);
setvect (0x0C,newint);
initialize (*com);
outport ((*com)+4, inport ((*com)+4) | 0x08);
outport (0x21,inport (0x21)&0xEF);
outport ((*com) + 1, 1);
keep(0,1000);
}
void interrupt newint ()
{
*scr = inport(*com);
outport (0x20,0x20);
}
Virtual University of Pakistan 137