CS609 Handouts 1 Merged
CS609 Handouts 1 Merged
CS609
Table of Contents
Input
Input Process Output
Output
While designing software the programmer may determine the required inputs for
that program, the wanted outputs and the processing the software would perform
in order to give those wanted outputs. The implementation of the processing part
is associated with application programming. Application programming facilitates
the implementation of the required processing that software is supposed to
perform; everything that is left now is facilitated by system programming.
DOS
BIOS
H/W
In this case the BIOS programs the hardware for required I/O operation which is
hidden to the user. In the third case the programmer may invoke operating
systems (DOS or whatever) routines in order to perform I/O operations. The
operating system in turn will use BIOS routines or may program the hardware
directly in order to perform the operation.
© Copyright Virtual University of Pakistan 3
01 - Introduction, Means of I/O
Methods of I/O
In the three layered approach if we are following the first approach we need to
program the hardware. The hardware can be programmed to perform I/O in three
ways i.e.
• Programmed I/O
• Interrupt driven I/O
• Direct Memory Access
In case of programmed I/O the CPU continuously checks the I/O device if the I/O
operation can be performed or not. If the I/O operations can be performed the
CPU performs the computations required to complete the I/O operation and then
again starts waiting for the I/O device to be able to perform next I/O operation. In
this way the CPU remains tied up and is not doing anything else besides waiting
for the I/O device to be idle and performing computations only for the slower I/O
device.
In case of interrupt driven the flaws of programmed driven I/O are rectified. The
processor does not check the I/O device for the capability of performing I/O
operation rather the I/O device informs the CPU that it’s idle and it can perform
I/O operation, as a result the execution of CPU is interrupted and an Interrupt
Service Routine (ISR) is invoked which performs the computations required for
I/O operation. After the execution of ISR the CPU continues with whatever it was
doing before the interruption for I/O operation. In this way the CPU does not
remain tied up and can perform computations for other processes while the I/O
devices are busy performing I/O and hence is more optimal.
Usually it takes two bus cycles to transfer data from some I/O port to memory or
vice versa if this is done via some processor register. This transfer time can be
reduced bypassing the CPU as ports and memory device are also interconnected
by system bus. This is done with the support of DMA controller. The DMA (direct
memory access) controller can controller the buses and hence the CPU can be
bypassed data item can be transferred from memory to ports or vice versa in a
single bus cycle.
I/O controllers
I/O device
I/O controller
CPU
No I/O device is directly connected to the CPU. To provide control signals to the
I/O device a I/O controller is required. I/O controller is located between the CPU
and the I/O device. For example the monitor is not directly collected to the CPU
rather the monitor is connected to a VGA card and this VGA card is in turn
connected to the CPU through busses. The keyboard is not directly connected to
CPU rather its connected to a keyboard controller and the keyboard controller is
connected to the CPU. The function of this I/O controller is to provide
• I/O control signals
• Buffering
• Error Correction and Detection
We shall discuss various such I/O controllers interfaced with CPU and also the
techniques and rules by which they can be programmed to perform the required
I/O operation.
We shall discuss all of them in detail and how they can be used to perform I/O
operations.
Operating systems
Systems programming is not just the study of programmable hardware devices.
To develop effective system software one needs to the internals of the operating
system as well. Operating systems make use of some data structures or tables
for management of computer resources. We will take up different functions of the
operating systems and discuss how they are performed and how can the data
structures used for these operations be accessed.
File Management
File management is an important function of the operating systems.
DOS/Windows uses various data structures for this purpose. We will see how it
performs I/O management and how the data structures used for this purpose can
be directly accessed. The various data structures are popularly known as FAT
which can be of 12, 16 and 32 bit wide, Other data structures include BPB(BIOS
parameter block), DPB( drive parameter block) and the FCBs(file control block)
which collectively forms the directory structure. To understand the file structure
the basic requirement is the understanding of the disk architecture, the disk
formatting process and how this process divides the disk into sectors and
clusters.
Memory management
Memory management is another important aspect of operating systems.
Standard PC operate in two mode in terms of memory which are
• Real Mode
• Protected Mode
In real mode the processor can access only first one MB of memory to control the
memory within this range the DOS operating system makes use of some data
structures called
• FCB (File control block )
• PSP (Program segment prefix)
We shall discuss how these data structures can be directly accessed, what is the
significance of data in these data structures. This information can be used to
traverse through the memory occupied by the processes and also calculate the
total amount of free memory available.
Certain operating systems operate in protected mode. In protected mode all of
the memory interfaced with the processor can be accessed. Operating systems in
this mode make use of various data structures for memory management which
are
• Local Descriptor Table
• Global Descriptor Table
• Interrupt Descriptor Table
We will discuss the significance these data structures and the information stored
in them. Also we will see how the logical addresses can be translated into
physical addresses using the information these tables
We will see where do they embed themselves and how can they be detected.
Moreover we will discuss techniques of how they can be removed and mostly
importantly prevented to perform any infections.
There are various types of viruses but we will discuss those which embed
themselves within the program or executable code which are
Executable file viruses
Partition Table or boot sector viruses
Device Drivers
Just connecting a device to the PC will not make it work unless its device drivers
are not installed. This is so important because a device driver contains the
routines which perform I/O operations on the device. Unless these routines are
provided no I/O operation on the I/O device can be performed by any application.
We will discuss the integrated environment for the development of device drivers
for DOS and Windows.
We shall begin our discussion from means of I/O. On a well designed device it is
possible to perform I/O operations from three different methods
• Programmed I/O
• Interrupt driven I/O
• DMA driven I/O
Output Input
D0
D0
D7
D7
Busy
DR
Strobe
CPU I/O
CPU
Controller
In case of programmed I/O the CPU is in a constant loop checking for an I/O
opportunity and when its available it performs the computations operations
required for the I/O operations. As the I/O devices are generally slower than the
CPU, CPU has to wait for I/O operation to complete so that next data item can be
sent to the device. The CPU sends data on the data lines. The device need to be
signaled that the data has been sent this is done with the help of STROBE signal.
An electrical pulse is sent to the device by turning this signal to 0 and then 1. The
device on getting the strobe signal receives the data and starts its output. While
the device is performing the output it’s busy and cannot accept any further data
on the other and CPU is a lot faster device and can process lot more bytes during
the output of previously sent data so it should be synchronized with the slower
I/O device. This is usually done by another feed back signal of BUSY which is
kept active as long as the device is busy. So the CPU is only waiting for the
device to get idle by checking the BUSY signal as long as the device is busy and
when the device gets idle the CPU will compute the next data item and send it to
the device for I/O operation.
Similar is the case of input, the CPU has to check the DR (data Ready) signal to
see if data is available for input and when its not CPU is busy waiting for it.
We shall start our discussion with the study of interrupt and the techniques used
to program them. We will discuss other methods of I/O as required.
1
2
Literally to interrupt means to break the continuity of some on going task. When
we talk of computer interrupt we mean exactly the same in terms of the
processor. When an interrupt occurs the continuity of the processor is broken and
the execution branches to an interrupt service routine. This interrupt service
routine is a set of instruction carried out by the CPU to perform or initiate an I/O
operation generally. When the routine is over the execution of the CPU returns to
the point of interruption and continues with the on going process.
Interrupt Mechanism
Interrupts are quite similar to procedures or function because it is also another
form temporary execution transfer, but there some differences as well. Note that
when procedures are invoked by there names which represents their addresses
is specified whereas in case of interrupts their number is specified. This number
can be any 8 bit value which certainly is not its address. So the first question is
what is the significance of this number? Another thing should also be noticed that
procedures are part of the program but the interrupts invoked in the program are
no where declared in the program. So the next question is where do these
interrupts reside in memory and if they reside in memory then what would be the
address of the interrupt?
Firstly lets see where do interrupts reside. Interrupts certainly reside somewhere
in memory, the interrupts supported by the operating system resides in kernel
which you already know is the core part of the operating system. In case of DOS
the kernel is io.sys which loads in memory at boot time and in case of windows
the kernel is kernel32.dll or kernel.dll. these files contain most of the I/O routines
and are loaded as required. The interrupts supported by the ROM BIOS are
loaded in ROM part of the main memory which usually starts at the address
F000:0000H. Moreover it is possible that some device drivers have been installed
these device drivers may provide some I/O routines so when the system boots
these I/O routines get memory resident at interrupt service routines. So these are
the three possibilities.
Secondly a program at compile time does not know the exact address where the
interrupt service routine will be residing in memory so the loader cannot assign
addresses for interrupt invocations. When a device driver loads in memory it
places the address of the services provided by itself in the interrupt vector table.
Interrupt Vector Table (IVT) in short is a 1024 bytes sized table which can hold
256 far addresses as each far address occupies 4 bytes. So its possible to store
the addresses of 256 interrupts hence there are a maximum of 256 interrupt in a
standard PC. The interrupt number is used as an index into the table to get the
address of the interrupt service routine.
02 - Interrupt Mechanism
Interrupt Mechanism
Interrupt follow a follow a certain mechanism for their invocation just like near or far
procedures. To understand this mechanism we need to understand its differences with
procedure calls.
The general concept for procedure call in most of the programming languages is that on
invocation of the procedure the parameter list and the return address (which is the value if
IP register in case of near or the value of CS and IP registers in case of far procedure) is
pushed Moreover in various programming languages whenever a procedure is called its
address need to be specified by some notation i.e. in C language the name of the
procedure is specified to call a procedure which effectively can be used as its address.
However in case of interrupts the a number is used to specify the interrupt number in the
call
• Int 21h
• Int 10h
• Int3
Fig 1 (Call to interrupt service routine and procedures/functions)
Main
Call proc1()
Call proc1()
Int 21h
Proc1()
Int 10h
Proc2()
Moreover when an interrupt is invoked three registers are pushed as the return address i.e.
the values of IP, CS and Flags in the described order which are restored on return. Also
no parameters are pushed onto the stack on invocation parameters can only be passed
through registers.
INTFF 0000:03FFH
Moreover it is important to understand the meaning of the four bytes within the interrupt
vector. Each entry within the IVT contains a far address the first two bytes (lower word)
of which is the offset and the next two bytes (higher word) is the segment address.
LO(1)
HI(0)
HI(1) 0000:0003
INT 1 0000:0004
0000:0007
IO.SYS
Device Driver
Command. COM
USER PROGRAM
This fact can be practically analyzed by the DOS command mem/d which gives the status
of the memory and also points out which memory area occupied by which process as
shown in the text below. The information given by this command indicates the address
© Copyright Virtual University of Pakistan 13
02 - Interrupt Mechanism
where IO.SYS and other device drivers have been loaded but the location of ROM BIOS
is not shown by this command.
C:\>mem /d
Address Name Size Type
------- -------- ------ ------
000000 000400 Interrupt Vector
000400 000100 ROM Communication Area
000500 000200 DOS Communication Area
Interrupt Invocation
Although hardware and software interrupts are invoked differently i.e hardware interrupts
are invoked by means of some hardware whereas software interrupts are invoked by
means of software instruction or statement but no matter how an interrupt has been
invoked processor follows a certain set steps after invocation of interrupts in exactly same
way in both the cases. These steps are listed as below
This can be analyzed practically by the use of debug program, used to debug assembly
language code, by assembling and debugging INT instructions
C:\>debug
-d 0:84
0000:0080 7C 10 A7 00-4F 03 55 05 8A 03 55 05 |...O.U...U.
0000:0090 17 03 55 05 86 10 A7 00-90 10 A7 00 9A 10 A7 00 ..U.............
0000:00A0 B8 10 A7 00 54 02 70 00-F2 04 74 CC B8 10 A7 00 ....T.p...t.....
0000:00B0 B8 10 A7 00 B8 10 A7 00-40 01 21 04 50 09 AB D4 ........@.!.P...
0000:00C0 EA AE 10 A7 00 E8 00 F0-B8 10 A7 00 C4 23 02 C9 .............#..
0000:00D0 B8 10 A7 00 B8 10 A7 00-B8 10 A7 00 B8 10 A7 00 ................7
0000:00E0 B8 10 A7 00 B8 10 A7 00-B8 10 A7 00 B8 10 A7 00 ................
0000:00F0 B8 10 A7 00 B8 10 A7 00-B8 10 A7 00 B8 10 A7 00 ................
0000:0100 8A 04 10 02 ....
-a
0AF1:0100 int 21
0AF1:0102
-r
AX=0000 BX=0000 CX=0000 DX=0000 SP=FFEE BP=0000 SI=0000 DI=0000
DS=0AF1 ES=0AF1 SS=0AF1 CS=0AF1 IP=0100 NV UP EI PL NZ NA PO NC
0AF1:0100 CD21 INT 21
-t
AX=0000 BX=0000 CX=0000 DX=0000 SP=FFE8 BP=0000 SI=0000 DI=0000
DS=0AF1 ES=0AF1 SS=0AF1 CS=00A7 IP=107C NV UP DI PL NZ NA PO NC
00A7:107C 90 NOP
-d ss:ffe8
0AF1:FFE0 02 01 F1 0A 02 F2 00 00
0AF1:FFF0 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00
The dump at the address 0000:0084 H shows the value of the vector of the interrupt #
21H i.e. 21H * 4 = 84H. This address holds the value 107CH in lower word and 00A7H
in the higher word which indicates that the segment address of interrupt # 21 is 00A7H
and the offset address of this ISR is 107CH.
Moreover the instruction INT 21H can be assembled and executed in the debug program,
on doing exactly so the instruction is traced through and the result is monitored. It can be
seen that on execution of this instruction the value of IP is changed to 107CH and the
value of CS is changed to 00A7H which cause the execution to branch to the Interrupt #
21H in memory and the previous values of flags, CS and IP registers are temporarily
saved onto the stack as the value of SP is reduced by 6 and the dump at the location
SS:SP will show these saved values as well.
interrupt; there are several methods for doing this. One of the methods is the use of
pseudo variables. A variable can be defined a space within the memory whose value can
be changed during the execution of a program but a pseudo variable acts very much like a
variable as its value can be changed anywhere in the program but is not a true variable as
it is not stored in memory. C programming language provides the use of pseudo variables
to access various registers within the processor.
The are various registers like AX, BX, CX and DX within the processor they can be
directly accessed in a program by using their respective pseudo variable by just attaching
a “_” (underscore) before the register’s name eg. _AX = 5; A = _BX .
After passing the appropriate parameters the interrupt can be directly invoked by calling
the geninterrupt () function. The interrupt number needs to be passed as parameter
into the geninterrupt() function.
Example:
#include<stdio.h>
#include<BIOS.H>
#include<DOS.H>
#include<conio.h>
void main()
{
clrscr(); //to clear the screen contents
_DX = (unsigned int) st;
_AH = 0x09;
geninterrupt(0x21);
getch(); //waits for the user to press any key
}
this is a simple example in which the parameters of int 21H/09H are loaded and then int
21H is invoked. DX and AH registers are accessed through pseudo variables and then
© Copyright Virtual University of Pakistan 16
02 - Interrupt Mechanism
geninterrupt()is called to invoke the ISR. Also note that _DS is not loaded. This is
the case as the string to be loaded is of global scope and the C language compiler
automatically loads the segment address of the global data into the DS register.
struct full
{
unsigned int ax;
unsigned int bx;
unsigned int cx;
unsigned int dx;
};
struct half
{
unsigned char al;
unsigned char ah;
unsigned char bl;
unsigned char bh;
unsigned char cl;
unsigned char ch;
unsigned char dl;
unsigned char dh;
};
typedef union tagREGS
{
struct full x;
struct half h;
}REGS;
This union can be used to signify any of the full or half general purpose register shows if
the field ax in x struct is to be accessed then accessing the fields al and ah in h will also
have the same effect as show in the example below.
Example:
#include<DOS.H>
union REGS regs;
void main (void )
{
regs.h.al = 0x55;
regs.h.ah = 0x99;
printf (“%x”,regs.x.ax);
}
© Copyright Virtual University of Pakistan 17
02 - Interrupt Mechanism
output:
9955
BOF
BOF cp
cp EOF
EOF
------------------- --------------------
This service is used to move the file pointer to a certain position relative to a certain
point. The value in AL specify the point relative to which the pointer is moved. If the
value of AL = 0 then file pointer is moved relative to the BOF (begin of File) if AL=1
then its moved relative to current position and if AL = 2 then its moved relative to the
EOF (end of file).
CX-DX specify the number of bytes to move a double word is needed to specify this
value as the size of file in DOS can be up to 2 GB.
On return of the service DX-AX will contain the number of bytes the file pointer is
actually moved eg. If the file pointer is moved relative to the EOF zero bytes the DX-AX
on return will contain the size of file if the file pointer was at BOF before calling the
service.
Example 21H/42H:
#include<stdio.h>
#include<fcntl.h>
#include<io.h>
#include<BIOS.H>
#include<DOS.H>
This program opens a file and saves its handle in the handle variable. This handle is
passed to the ISR 21H/42H along with the move technique whose value is 2 signifing
movement relative to the EOF and the number of bytes to move are specified to be zero
indicating that the pointer should move to the EOF. As the file was just opened the
previous location of the file pointer will be BOF. On return of this service DX-AX will
contain the size of the file. The low word of this size in ax is placed in the low word of
size variable and the high word in dx is placed in the high word of size variable.
Another Example:
Lets now illustrate how ISR can be invoked by means of another example of BIOS
service. Here we are choosing the ISR 10h/01h. This interrupt is used to perform I/O on
the monitor. Moreover this service is used to change the size of cursor in text mode. The
description of this service is given as under.
Entry
AH = 01
CH = Beginning Scan Line
CL = Ending Scan Line
On Exit
Unchanged
The size of the cursor depends upon the number of net scan lines used to display the
cursor if the beginning scan line is greater than the ending scan line the cursor will
disappear. The following tries to accomplish just that
void main()
{
char st[80];
union REGS regs;
regs.h.ah = 0x01;
regs.h.ch = 0x01;
regs.h.cl = 0x00;
int86(0x10,®s,®s); //corrected
gets(st);
}
The program is quite self explanatory as it puts the starting scan line to be 1 and the
ending scan line to be 0. Henceforth when the service execute the cursor will disappear.
same is getvect(int#) which requires the interrupt number a parameter and returns
the value of its vector.
Intproc
Function pointers
Another thing required to be understood are the function pointers. C language is a very
flexible language just like there are pointers for integers, characters and other data types
there are pointers for functions as well as illustrated by the following example
void myfunc()
{
void (*funcptr) ( )
funcptr = myfunc;
(*funcptr) ( );
myfunc();
There are three fragments of code in this example. The first fragment shows the
declaration of a function myfunc()
The second fragment show declaration of a pointer to function named funcptr which is
a pointer to a function that returns void.
In the third fragment funcptr is assigned the address of myfunc as the name of the
function can be used as its address just like in the cases of arrays in C. Then the function
pointed by funcptr by the statement (*funcptr)(); is called and then the original
myfunc() is called. The user will observe in both the cases same function myproc()
will be invoked.
Similarly a pointer to such interrupt type function can also be declared as following
void interrupt (*intptr) ( );
where intptr is the interrupt pointer and it can be assigned an address using the
getvect() function
intptr = getvect(0x08);
Now interrupt number 8 can be invoked using the interrupt vector as following
(*intptr) ( );
In the following example a certain interrupt type function has been declared. The address
of this function can be placed on to the vector of any interrupt using setvect()
function as following. The following code places the address of newint function at the
vector of int 8
setvect(0x08, newint);
Here is a listing of a program that makes use of int 65H to exhibit how software interrupts
needs to be programmed.
the keep() function requires the return code which is usually zero for normal termination
and the number of paragraphs required to be allocated. Each paragraph is 16 bytes in size.
TSR Programs
Following is a listing of a TSR (Terminate and Stay Resident) program which programs
the interrupt number 65H but in this case the new interrupt 65H function remains in
memory even after the termination of the program and hence the vector of int 65h does
not become a dangling pointer.
#include<BIOS.H>
#include<DOS.H>
The main()function gets and sets the vector of int 65H such that the address of
newint65 is placed at its vector. In this case the program is made memory resident
using the keep function and 1000 paragraphs of memory is reserved for the program (the
amount of paragraphs is just a calculated guess work based upon the size of application).
Now if any application as in the following case invokes int 65H the string st which is also
now memory resident will be displayed.
#include<BIOS.H>
#include<DOS.H>
void main()
{
geninterrupt (0x65);
geninterrupt (0x65);
}
This program invokes the interrupt 65H twice which has been made resident.
#include<BIOS.H>
#include<DOS.H>
char st[80] ={"Hello World$"};
char st1[80] ={"Hello Students!$"};
void interrupt (*oldint65)( );
void interrupt newint65( );
void main()
{
oldint65 = getvect(0x65);
setvect(0x65, newint65);
keep(0, 1000);
}
void interrupt newint65( )
{
if (( _AH ) == 0) //corrected
{
_AH = 0x09;
_DX = (unsigned int) st;
geninterrupt (0x21);
}
else
{
if (( _AH ) == 1) //corrected
{
_AH = 0x09;
_DX = (unsigned int) st1;
geninterrupt (0x21);
}
}
}
Various interrupts provide a number of services. The service number is usually placed in
the AH register before invoking the interrupt. The ISR should in turn check the value in
AH register and then perform the function accordingly. The above example exemplifies
just that. In this example int 65 is assigned two services 0 and 1. Service 0 prints the
string st and service 1 prints the string st1. These services can be invoked in the
following manner.
#include<BIOS.H>
#include<DOS.H>
void main()
{
_AH = 1;
geninterrupt (0x65);
_AH = 0;
geninterrupt (0x65);
}
This technique makes use of the fact that the vector is stored in the IVT and it can be read
and written. The interrupt which is to be hooked its (original routine ) vector is first read
from the IVT and then stored in a interrupt pointer type variable, after this the vector is
changed to point to one of the interrupt function (new routine) within the program. If the
interrupt is invoked now it will force the new routine to be executed provided that its
memory resident. Now two things can be done, the original routine might be performing
an important task so it also needs to invoked, it can either be invoked in the start of the
new routine or at the end of the new routine using its pointer as shown in the following
execution charts below
Original Routine
Interrupt Interception
Original Routine
New Routine
Care must be taken while invoking the original interrupt. Generally in case hardware
interrupts are intercepted invoking the original interrupt at the start of new routine might
cause some problems whereas in case of software interrupts the original interrupt can be
invoked anywhere.
The above program gets the address stored at the vector of interrupt 8 and stores it in the
pointer oldint. The address of the interrupt function newint is then placed at the vector of
int 8 and the program is made memory resident. From this point onwards whenever
interrupt 8 occurs the interrupt function newint is invoked. This function after performing
its operation calls the original interrupt 8 whose address has been stored in oldint pointer.
Timer Interrupt
In the coming few examples we will intercept interrupt 8. This is the timer interrupt. The
timer interrupt has following properties.
¾ Its an Hardware Interrupts
¾ It is Invoked by Means of Hardware
¾ It approximately occurs 18.2 times every second by means of hardware.
Insert key
Right Shift key
Caps Lock Key Left Shift Key
Num Lock key Ctrl Key
Another Example
#include <dos.h>
void interrupt (*old)();
void interrupt new();
char far *scr=(char far* ) 0x00400017;
void main()
{
old=getvect(0x08);
setvect(0x08,new);
keep(0,1000);
}
void interrupt new (){
*scr=64;
(*old)();
}
This fairly simple example intercepts the timer interrupt such that whenever the timer
interrupt occurs the function new() is invoked. Remember this is .C program and not a
.CPP program. Save the code file with .C extension after writing this code. On occurrence
of interrupt 8 the function new sets the caps lock bit in key board status by placing 64 at
this position through its far pointer. So even if the user turns of the caps lock on the next
occurrence of int 8 ( almost immediately) the caps lock will be turned on again (turing on
the caps lock on like this will not effect its LED in the keyboard only letters will be typed
in caps).
M I/O
P
OUT
M I/O
P
MOV
The memory area starting from the address b800:0000H. Two bytes (a word) are reserved
for a single character to be displayed in this area. The low byte contains the ASCII code
of the character to be displayed and the high byte contains the attribute of the character to
be displayed. The address b800:0000h corresponds to the character displayed at the top
left corner of the screen, the next word b800:0002 corresponds to the next character on
the same row of the text screen and so on as described in the diagram below.
void main()
{
(*scr)=0x0756;
(*(scr+1))=0x7055;
}
The next example fills whole of the screen with spaces. This will clear the contents of the
screen.
Another Example
In the following example memory mapped I/O is used in combination with interrupt
interception to perform an interesting task.
#include <dos.h>
void interrupt (*old)();
void interrupt newfunc();
char far *scr=(char far* ) 0xb8000000;
void main()
{
old=getvect(0x08);
setvect(0x08,newfunc);
keep(0,1000);
}
In the above example the timer interrupt is intercepted such that whenever the timer
interrupt is invoked (by means of hardware) the memory resident newfunc() is invoked.
This function simply displays the ASCII character 0x41 or ‘A’ in the top left corner of the
text screen.
This program scans through all the bytes of text display memory when int 8 occurs. It
once resident will replace all the ‘1’ on the screen by ‘9’. If even somehow a ‘1’ is
displayed on the screen it will be converted to ‘9’ on occurrence of interrupt 8 which
occurs 18.2 times every second.
Kbd .
Example
#include <dos.h>
void interrupt (*old)( );
void interrupt newfunc( );
void main( )
{
old = getvect(0x09);
setvect(0x09,newfunc);
keep(0,1000);
}
void interrupt newfunc ( )
{
(*old)( );
(*old)( );
(*old)( );
}
This program simply intercepts the keyboard interrupt and places the address of newint
in the IVT. The newint simply invokes the original interrupt 9 thrice. Therefore the
same character input will be placed in the keyboard buffer thrice i.e three characters will
be received for each character input.
Example
#include <dos.h>
void interrupt (*old)( );
void interrupt newfunc( );
char far *scr = (char far* ) 0x00400017;
void main( )
{
old = getvect(0x09);
setvect(0x09,newfunc);
keep(0,1000);
}
void interrupt newfunc ( )
{
*scr = 64;
(*old)( );
}
The above program is quite familiar it will just set the caps lock status whenever a key is
pressed. In this case the keyboard interrupt is intercepted.
Example
This too is a familiar example. Whenever a key is pressed from the keyboard the newfunc
functions runs through whole of the test display memory and replaces the ASCII ‘1’
displayed by ASCII ‘9’.
#include <dos.h>
void interrupt (*oldTimer)( ); //corrected
void interrupt (*oldKey)( ); //corrected
void interrupt newTimer ( );
void interrupt newKey ( );
char far *scr = (char far* ) 0xB8000000;
int i, t = 0, m = 0;
char charscr [4000];
void main( )
{
oldTimer = getvect(8);
oldKey = getvect (9);
setvect (8,newTimer);
setvect (9,newKey);
getch();
getch();
getch();
getch();
}
This program works like a screen saver. The newTimer function increments t whenever
it is invoked so the value of t reaches 182 after ten second. At this moment the function
saves the value in display text memory in a character array and fills the screen with
spaces and sets a flag m. The newKey function is invoked when a key press occurs.
© Copyright Virtual University of Pakistan 37
05 - TSR programs and Interrupts (Keyboard interrupt)
The flag is checked if the it’s set then the screen is restored from the values saved in that
character array.
AX =1234H
Proc1 ( ) AX =FF55H
AX = ?
In the above example the function Proc1() is invoked. On invocation the register AX
contained the value 1234H, the code within the function Proc1() changes the value in AX
to FF55H. On return AX will contain the value 1234H if the function have been
implemented as a reentrant procedure i.e a reentrant procedure would restore the values in
registers their previous value (saved in the stacked) before returning.
C language reentrant procedures save the registers in stack following the order AX, BX,
CX, DX, ES, DS, SI, DI, BP on invocation and restores in reverse order before return.
This fact about reentrant procedures can be analysed through following example.
#include <stdio.h>
void interrupt *old();
void interrupt newint()
void main ()
{
int a;
old = getvect(0x65);
setvect(0x65,newint);
_AX=0xf00f;
geninterrupt(0x65);
a = _AX
printf(“%x”,a);
}
Firstly its important to compile this above and all the rest of the examples as .C files
and not as .CPP file. It these codes are compiled using .CPP extension then there is no
surety that this program could be compiled.
Again int 65H is used for this experiment. The int 65H vector is made to point at the
function newint(). Before calling the interrupt 65H value 0xF00F is placed in the AX
register. After invocation of int 65H the value of AX register is changed to 0x1234. But
after return if the value of AX is checked it will not be 0x1234 rather it will be 0xF00F
indicating that the values in registers are saved on invocation and restore before return
and also that the interrupt type procedures are reentrant.
Push
AX,BX,CX,DX,ES,DS,SI,DI,BP
POP
BP,DI,SI,DS,ES,DX,CX,BX,AX
Pop IP,CS,flags
The registers Flags, CS and IP are pushed on execution of INT instruction and executions
branches to the interrupt procedure. The interrupt procedure pushes register AX, BX, CX,
DX, ES, DS, SI, DI, BP in this order. The interrupt procedure then executes, before
returning it pops all the registers in the reverse order as BP, DI, SI, DS, ES, DX, CX, BX
and AX. IP, CS and flags are poped on execution of the IRET instruction.
Next diagram shows the status of the stack after invocation of the interrupt procedure.
BP
DI
SI
DS
ES
DX
CX
BX
AX
IP
CS
Flags
The arguments in simple procedure or functions are saved in the stack for the scope of the
function/procedure. When an argument is accessed in fact stack memory is accessed.
Now we will take a look how stack memory can be accessed for instance in case of
interrupt procedures to modify the value of register in stack.
Although interrupt do not take parameters through stack but an interrupt procedure can
still have parameters. This parameter list can be used to access the stack. The leftmost
parameter accesses the item on top of the stack and the rest of the parameters accesses
deeper into the stack according to its order toward left. In the above example value of AX
in stack is moved in a, the value of BX is moved into b and the value of ES is moved into
d.
Example:
In this example the value on invocation in AX is 0x1234, the interrupt procedure does not
change the current value of the register through pseudo variables rather it changes the
corresponding of AX in stack which will be restored in AX before return.
Disk Interrupt
The following example makes use of disk interrupt 13H and its service 3H. The details of
this service are as under.
On Entry
AH = Service # = 03
AL = No of Blocks to write
BX = Offset Address of Data
CH = Track # , CL = Sector #
DH = Head #
DL = Drive #(Starts from 0x80 for fixed disk & 0 for removable disks)
ES = Segment Address of data buffer.
On Exit
AH = return Code
Carry flag = 0 ( No Error AH = 0)
Carry flag = 1 ( Error AH = Error Code)
Boot block is a special block on disk which contains information about the operating
system to be loaded. If the data on boot block is somehow destroyed the disk would be
rendered inaccessible. The address of partition block on hard disk is head # =1, track# = 0
and sector # = 1. Now let’s write an application that will protect the boot block to be
written by any other application.
#pragma inline
#include <dos.h>
#include <bios.h>
void interrupt (*oldtsr) ( );
void interrupt newtsr (unsigned int BP, …, flags);
//must provide all the arguments
void main ( )
{
oldtsr = getvect (0x13);
setvect(0x13, newtsr); //corrected
keep (0, 1000);
}
void interrupt newtsr(unsigned int BP, unsigned int DI,
unsigned int SI, unsigned int DS, unsigned int ES, unsigned
int DX, unsigned int CX, unsigned int BX, unsigned int AX,
unsigned int IP, unsigned int CS,
unsigned int flags) //corrected
{
if ( _AH == 0x03)
if(( _DH == 1 && _CH == 0 && _CL == 1)&& _DL >= 0x80)
{
asm clc;
asm pushf;
asm pop flags;
return;
}
_ ES = ES; _DX = DX;
_CX = CX; _BX = BX;
_AX = AX;
*oldtsr;
asm pushf;
asm pop flags;
AX = _AX; BX = _BX;
CX = _CX; DX = _DX;
ES = _ES;
}
The above program intercepts interrupt 13H. The new interrupt procedure first check AH
for service number and other parameters for the address of boot block. If the boot block is
to be written it simply returns and clears the carry flag before returning to fool the calling
program that the operation was successful. And if the boot block is not to be written then
it places the original parameters back into the registers and calls the original interrupt.
The values returned by the original routine are then restored to the corresponding register
values in the stack so that they maybe updated into the registers on return.
Convert to ASCII
& place it in keyboard buffer
The following application show how this can be done.
#include <dos.h>
#include <bios.h>
#include <stdio.h>
void interrupt (*oldint15) ( );
void interrupt newint15(unsigned int BP, …, flags);
void main ( )
{
oldint15 = getvect (0x15);
setvect (0x15, newint15);
keep (0, 1000);
}
void interrupt newint15(unsigned int BP, unsigned int DI,
unsigned int SI, unsigned int DS, unsigned int ES, unsigned
int DX, unsigned int CX, unsigned int BX, unsigned int AX,
unsigned int IP, unsigned int CS,
unsigned int flags)
{
if (*(((char*)&AX) + 1) == 0x4F )
{
if (*((char*)&AX) == 0x2C)
*(((char*)&AX)) = 0x1E;
else if (*((char*)&AX) == 0x1E)
*((char*)&AX) = 0x2C; //corrected
}
else
(*oldint15)();
}
© Copyright Virtual University of Pakistan 44
06 - TSR programs and Interrupts (Disk interrupt, Keyboard hook)
The application intercepts interrupt 15H. The newint15 function checks for the service #
4F in the high byte of AX, if this value is 4F the definitely the value in AL with be the
scan code. Here a simple substitution have been performed 0x1E is the scan code of ‘A’
and 0x2C is the scan code of ‘Z’. If the scan code is AL is that of ‘A’ it is substituted with
the scan code of ‘Z’ and vice versa. If some other service of 15H is invoked the original
interrupt function is invoked.
07 - Hardware Interrupts
The microprocessor package has many signals for data, control and addresses. Some of
these signals may be input signals and some might be output. Hardware interrupts make
use of two of such input signals namely NMI (Non maskable Interrupt) & INTR(Interrupt
Request).
Reset
Hold
NMI Microprocessor
INTR
NMI is a higher priority signal than INTR, HOLD has even higher priority and RESET
has the highest priority. If any of the NMI or INTR pins are activated the microprocessor
is interrupted on the basis of priority, if no higher priority signals are present. This is how
microprocessor can be interrupted without the use of any software instruction hence the
name hardware interrupts.
Interrupt Controller
A single interrupt controller can arbitrate among 8 different devices.
D0 IRQ0
PIC
D7
INT IRQ7
As it can be seen from the diagram above the PIC device has 8 inputs IRQ0-IRQ7. IRQ0
has the highest priority and IRQ7 has the lowest. Each IRQ input is attached to an I/O
device whenever the device requires an I/O operation it sends a signal to the PIC. The
PIC on the basis of its priority and presence of other requests decides which request to
serve. Whenever a request is to be served by PIC it interrupt the processor with the INT
output connected to the INTR input of the processor and send the interrupt # to be
generated the data lines connected to the lower 8 datelines of the data bus to inform the
processor about the interrupt number. In case no higher priority signal is available to the
processor and the processor is successfully interrupted the microprocessor sends back an
INTA (interrupt Acknowledge) signal to inform the PIC that the processor has been
interrupted.
The following diagram also shows the typical connectivity of the IRQ lines with various
devices
Interval Timer
0 IRQ1
KBD Controller
1
DO
2
MICRO
COM2 3 D7 PROCESSOR
PIC
COM1 4
INT INTR
5
Other
6 INTA
Controllers
Printer Controller 7 IRQ7
In standard PCs there maybe more than 8 devices so generally two PIC are used for INTR
line arbitration. These 2 PICs are cascaded such that they collectively are able to arbitrate
among 16 devices in all as shown in the following diagram.
MASTER IRQO
DO
PIC IRQ7
D7 cas1
cas2
INTA cas3
DO IRQ8
D7 PIC IRQ15
cas1
INTA cas2
cas3
SLAVE
The PICs are cascaded such that a total of 16 IRQ levels can be provided number IRQ0-
IRQ15. The IRQ level 2 is used to cascade both of the PIC devices. The Data lines are
multiplexed such that the interrupt number is issued by the concerned PIC. The IRQ 2
input of the Master PIC is connected to the INT output of the Slave PIC. If the slave PIC
is interrupted by a device its request ins propagated to the master PIC and the master PIC
ultimately interrupts the processor on INTR line according to the priorities.
In a standard PC the PICs are programmed such that the master PIC generated the
interrupt number 8-15 for IRQ0 –IRQ7 respectively and the slave PIC generates interrupt
number 70-77H for IRQ8-IRQ15
processed and then ‘A’. So the sequence of input will change to CBA while the correct
sequence would be ABC.
C PRESSED
A PRESSED
B PRESSED
The input will be received in correct sequence only if the H/W interrupts are non-
preemptive as illustrated in the diagram below.
A PRESSED
B PRESSED
C PRESSED
To understand the ISR, IMR and IRR lets take a look at the following diagram illustrating
an example.
7 6 5 4 3 2 1 0
ISR 0 0 0 1 0 0 0 0
7 6 5 4 3 2 1 0
IMR 0 0 0 0 0 0 1 0
7 6 5 4 3 2 1 0
IRR 1 1 0 0 0 1 0 1
The values shown in the various registers illustrate that the currently in-service interrupt
is that generated through IRQ4 of the PIC (int 0CH in case of mater PIC), also the
interrupt through IRQ1 has been masked (int 9h (keyboard interrupt) in case of master
PIC) which means that even though a request for this interrupt is received by the PIC but
this request is ignored by the PIC until this bit is cleared. And the requests through IRQ7,
IRQ6, IRQ2 and IRQ0 are pending and waiting for the previously issued interrupt to
return.
Port Addresses
Few of the operation control words can be altered after boot time. The addresses for these
OCW are listed as below
Let’s now discuss an example that accesses these ports to control the PIC
#include <stdio.h>
#include <bios.h>
void main()
{
outport(0x21,0x02);
This example simply accesses the bit # 1 of IMR in the master PIC. It sets the bit #1 in
IMR which masks the keyboard interrupt. As a result no input could be received from the
keyboard after running this program.
#include <dos.h>
#include <stdio.h>
#include <bios.h>
void interrupt(*oldints)();
void interrupt newint8();
int t=0; //corrected
void main()
{
oldints=getvect(0x08);
setvect(0x08,newint8);
keep(0,1000);
}
void interrupt newint8()
{
t++:
if (t==182)
{
outport(0x21,2);
}
else{
if (t==364)
{
outport(0x21,0);
t=0;
}
}
(*oldints)();
}
The example above is also an interesting example. This program intercepts the timer
interrupt. The timer interrupt makes use of a variable to keep track of how much time has
passed; t is incremented each time int 8 occurs. It the reaches the 182 after 10 second, at
this point the keyboard interrupt is masked and remains masked for subsequent 10 second
at which point the value of t will be 364, also t is cleared to 0 for another such round.
#include <dos.h>
void interrupt(*old)();
void interrupt newint9();
char far *scr=(char far *) 0x00400017;
void main()
{
old=getvect(0x09);
setvect(0x09,newint9);
keep(0,1000);
}
void interrupt newint9()
{
if (inportb(0x60)==83
&&(((*scr)&12)==12)) //corrected
{
outportb(0X20,0x20);
return;
}
(*old)();
}
The above program disables the CTRL+ALT+DEL combination in the DOS environment
(if windows OS is also running this combination will not be disabled for its environment).
The keyboard interrupt has been intercepted, whenever the keyboard interrupt occurs the
newint9 function receives the scan key code from the keyboard port 0x60, 83 is the scan
key code of DEL key. Also the program checks if the ALT and CTRL button has been
pressed as well from the status of the 40:17H keyboard status byte. If it confirms that the
combination pressed is CTRL+ALT+DEL then it does not invoke the real int 9 ( *oldint()
which will make the computer reboot in DOS environment had the computer been booted
through DOS) and simply returns. But notice that before returning it notifies the PIC that
the interrupt has ended. The EOI code sent to the OCW at the address 0x20 is also 0x20.
This is being done because int 9 is a hardware interrupt, had this been a software interrupt
this would have not been required.
#include <dos.h>
void interrupt(*old)();
void main()
{
old=getvect(0x09);
setvect(0x09,newint9);
keep(0,1000);
}
void interrupt newint9()
{
if (inportb(0x60)==0x1F) //corrected
outportb(0X20,0x20);
return;
}
(*old)();
The above C language program suppresses the ‘s’ input from the keyboard. The keyboard
interrupt has been intercepted. When a key is pressed newint9 is invoked. This service
checks the value through the import statement of the keyboard port numbered 0x60. If he
scan code ( and not the ASCII code) is 0x1F then it indicates that the ‘s’ key was pressed.
This program in this case simply returns the newint9 hence suppressing this input by not
calling the real int 9. Before return it also notifies the PIC about the end of interrupt.
Keyboard Buffer
• Keyboard Buffer is located in BIOS Data Area.
• Starts at 40: IEH
• Ends at 40 : 3DH
• Has 32 byes of memory 2 bytes for each
character.
• Head pointer is located at address 40 : 1A to
40:IBH
• Tail pointer located at address 40 : IC to 40:IDH
The keyboard buffer is a memory area reserved in the BIOS data area. This area stores the
ASCII or special key codes pressed from the keyboard. It works as a circular buffer and
two bytes are reserved for each character, moreover 2 bytes are used to store a single
character. The first character stores the ASCII code and the second byte stores 0 in case
an ASCII key is pressed. In case a extended key like F1- F12 or arrow key is pressed the
first byte stores a 0 indicating a extended key and the second byte stores its extended key
code.
Circular buffer
40:1AH
40:1CH
Head Tail
40:1EH
40:3DH
The circular keyboard buffer starts at the address 40:1EH and contains 32 bytes. The
address 40:1AH stores the head of this circular buffer while the address 40:1CH stores the
tail of this buffer. If the buffer is empty the head and tail points at the same location as
shown in the diagram above.
Tail
0x1E
‘A’
0’
‘B’ 0x20
0 0x21
0 0x22
83 0x23
Head = 0x24
The above slide shows how characters are stored in the buffer. If ‘A; is to be stored then
the first byte in the buffer will store its ASCII code and the second will store 0, and if
© Copyright Virtual University of Pakistan 55
08 - Hardware Interrupts and TSR programs
extended key like DEL is to be stored the first byte will store 0 and the second byte will
store its scan code i.e. 83. The diagram also shows that head points to the next byte where
the next input character can be stored. Also notice that head contain the offset from the
address 40:00H and not from address 40:1EH. i.e. it contain 0x24 which is the address of
the next byte to be stored relative to the start of BIOS data area and not the keyboard
buffer.
Position of tail
0xIE
Tail=0x20
‘B’
0
0
83 Head = 24
As discussed earlier the keyboard buffer is a circular buffer therefore the tail need to be
placed appropriately. In the given example the input ‘A’ stored in the buffer is consumed.
On consumption of this character the tail index is updated so that it points to the next
character in the buffer. In brief the tail would point to the next byte to be consumed in the
buffer while head points to the place where next character can be stored.
Example
#include <dos.h>
void interrupt (*old)();
void interrupt new1()!
unsigned char far *scr = (unsigned char far
*) 0x0040001C
void main()
{
old=getvect(0x09);
setvect(0x09,new1);
keep(0,100);
}
The program listed in the slides above intercepts interrupt 9. Whenever the interrupt 9
occurs it reads the keyboard port 0x60. If the port contains 83 then it means DEL was
pressed, if so it places the code 25 in the buffer and then updates the head in circular
manner. The code 25 placed instead of 83 represents the combinations CTRL+Y. The
program when resident will cause the program to receive CTRL+Y combination
whenever DEL is pressed by the user. i.e in Borland C environment CTRL+Y
combination is used to delete a line, if this program is resident then in Borland C
environment a line will be deleted whenever DEL is pressed by the user. But the thing
worth noticing is that the interrupt function returns and does not call the real interrupt 9
after placing 25 in the buffer, rather it returns directly. But before returning as it has
intercepted a hardware interrupt it needs to notify the PIC, this is done by
outport(0x20,0x20); statement. 0x20 is the address of the OCW that receives the EOI
code which incidentally is also 0x20.
For Master
outportb(0x20,0x20);
For Slave
outportb(0x20,0x20);
outportb(0xA0,0x20);
As discussed earlier the slave PIC is cascaded with the master PIC. If the hardware
interrupt to be processed is issued by the master PIC then the ISR needs to send the EOI
code to the master PIC but if the interrupt request is issued by the slave PIC then the ISR
needs to inform both master and slave PICs as both of them are cascaded as shown in the
slide.
Reading OCW
OCW2& OCW3
7 6 5 4 3 2 1 0
X X X
00 If EOI is to be sent
The same port i.e 0x20 is used to access the OCWs. 00 is placed in bits number 4 and 3 to
indicate an EOI is being received and 01 is placed to indicate that a internal register is to
be accessed.
7 6 5 4 3 2 1 0
0
The value in bits number 1 and 0 indicate which Register is to accessed. 10 is for IRR and
11 is for ISR.
7 6 5 4 3 2 1 0
0 0 0 0 1 0 0 0
No EOI relevant
Don’t Care
A value is placed in the port 0x20 as shown in the above slide to indicate that a register is
to be accessed.
7 6 5 4 3 2 1 0
0 0 0 0 1 0 1 0
IRR Accessed
Then again a value in that same port is placed to indicate which register is to be accessed,
as in the above slide IRR is to be accessed.
7 6 5 4 3 2 1 0
0 0 0 0 1 0 1 1
ISR Accessed
And in this slide a value is formed which can be programmed in the port 0x20 to access
the ISR.
A sample program
#include <stdio.h>
#include <dos.h>
#include <bios.h>
void main (void)
{ char a;
outport(0x20,8);
outport(0x20,0x0A);
a=inport(0x20);
printf (“value of IRR is %x”; ,a);
outport(0x20,0x08);
outport(0x20,0x0B);
a=inport(0x20);
printf (“value of ISR is %x”; ,a);
}
The above program makes use of the technique described to access the ISR and IRR.
Firstly 0x08 is placed to specify that a register is to be accessed then 0x0A is placed to
indicate that IRR is to accessed. Now this port 0x20 can be read which will contain the
value in IRR. Similarly it is done again by placing the 0x0B in port 0x20 to access the
ISR.
int flag;
flag =1;
keep(0,1000);
if (flag==1)
Make TSR
else
exit Program
This will not work as this global variable is only global for this instance of the program.
Other instances in memory will have their own memory space. So the
Example:
#include<stdio.h> setvect(0x08, newint);
#include<BIOS.H> (*int65vec) = 0xF00F;
#include<DOS.H> keep (0,1000);
unsigned int far * int65vec = }else
(unsigned far *) {
MK_FP(0,0x65*4) puts (“Program Already
void interrupt (*oldint) ( ); Resident”);
void interrupt newfunc ( ); }}
void main() void interrupt newfunc ()
{ { :::::::
if((*int65vec) != 0xF00F) :::::::
//corrected (*oldint) ( );
{ }
oldint =getvect (0x08);
The above template shows how the vector of int 0x65 can be used as a flag. This template
shows that a far pointer is maintained which is assigned the address of the int 0x65
vector. Before calling the keep() function i.e making the program resident a value of
0xf00f is placed at this vector( this vector can be tempered as it is not being used by the
OS or device drivers). Now if another instance of the program attempts to run the if
statement at the start of the program will check the presence of 0x0f00f at the int vector
of 0x65, if found the program will simply exit otherwise it will make itself resident. Or in
other word we can say that 0xf00f at the int 0x65 vector in this case indicate that the
program is already resident.
Another Method
¾Service # 0xFF usually does not
exist for ISR’s.
¾Key is to create another service #
0xFF for the ISR interrupt besides
other processing.
Example:
#include<stdio.h>
#include<BIOS.H>
#include<DOS.H>
void interrupt (*oldint) ( );
void interrupt newfunc ( unsigned int BP,..…,flags);
void main()
{
_DI = 0;
_AH = 0xFF;
geninterrupt (0x13);
if (_DI = = 0xF00F) {
puts (“Program Already Resident”);
exit (0);
}
The implements the service 0xff of interrupt 0x13 such that whenever this service is
called it returns 0xf00f in DI and if this value does not return then it means that this
program is not resident.
Example:
Else
{
oldint = getvect (0x13);
setvect (0x13, newint);
keep (0, 1000);
}} else
void interrupt newint ( ) { :::::::
{ :::::::
if (_AH == 0xFF) :::::::
{ }
DI = 0xF00F; (*oldint) ( );
return; }
}
Interval Timer
- Synchronous Devices require a
timing signal.
Clock Clk
Clk Microprocessor
generated
The interval timer is used to divide an input frequency. The input frequency used by the
interval timer is the PCLK signal generated by the clock generator. The interval timer has
three different each with an individual output and memory for storing the divisor value.
Counter Registers:
• Counter registers can be used to divide frequency.
7 6 5 4 3 2 1 0
count
/16 /8 /4 /2
A counter register can be used to divide the clock signal. As shown in the slide above, 0
of the clock register is used to divide the clock frequency by 2 subsequently bit 1 is used
to divide it by 4 and so on.
The above slide shows a sequence of output that a 8bit clock register will generate in
sequence whenever it receives the clock signal. Observe bit #1, its value changes between
0 and 1 between two clock cycles so it can be used to divide the basic frequency by 2.
© Copyright Virtual University of Pakistan 69
09 - The interval Timer
Similarly observe bit #2 its value transits between 0 and 1 within 4 clock cycles hence it
divides the frequency by 4 and so on.
Timing diagram
Timing Diagram
Bit 0 (/2)
Bit 1 (/4)
Bit 2 (/8)
Bit 3 (/16)
:::: :
:::: :
:::: :
Here is the timing diagram for above example. Bit #1 performs one cycle in between 2
clock cycles. Similarly bit #2 performs one cycle in between 4 clock cycles and so on.
Command register and the channels need to be programmed for the interval timer to
generate a wanted frequency.
Command Register
7 6 5 4 3 2 1 0
1 0 1 1 0 1 0 0
Binary = 0
Ch: 00=0
BCD = 1
01=1
10=2 Mode 0 ~ 5
=000 ~ 101
01=Low Byte
10=High Byte
11=Low Byte followed
by High Byte
Mode Description
Divisor = 4
Mode = 0 -----4----- -----4-----
Divisor = 4
Mode = 1 -----3----- -----3-----
Divisor = 4
Mode = 2 ---2--- ---2---
Divisor = 4
Mode = 3
-----4----- -----4-----
The interval timer can operate in six modes. Each mode has a different square wave
pattern according to need of the application. Some modes might be suitable to control a
motor and some might be suitable to control the speaker.
Binary counter
BCD COUNT=89 1 0 0 0 1 0 0 1
1 0 0 1 0 0 0 0
1 0 0 1 0 0 0 1
99= 1 0 0 1 1 0 0 1
0 0 0 0 0 0 0 0
The interval timer channels can be used as a binary as well as a BCD counter. In case its
used in binary mode its counter registers will count in binary sequence and if its used as a
BCD counter its registers will count in BCD sequence as described above.
The interval timer has 3 channels each channel is 16 bit wide. The port 43H is an 8 bit
port used as the command register. Ports 40h, 41H and 42H are associated with the
channels o, 1 and 2 respectively. Channels are 16 bit wide whereas the ports are 8 bit
wide. A 16 bit value can be loaded serially through the ports into the register.
61H Port
Connect
to interval
timer = 1
Rest of the bits are used by othe r
devices and should not be changed.
Turn ON Speaker = 1
Turn OFF Speaker=0
the port 61h is used to control the speaker only the least significant 2 bits are important.
Bit 0 is used to connect the interval timer to the speaker and the bit #1 is used to turn the
speaker on off. Rest of the bits are used by other devices.
Example
Example:
//Program loads divisor value of 0x21FF
//Turns ON the speaker and connects it to Interval
Timer
#include<BIOS.H>
#include<DOS.H>
void main()
{
outportb (0x43,0xB4);
outportb (0x42,0xFF);
outportb (0x42,0x21);
outportb (0x61,inportb(0x61) | 3);
getch();
outportb (0x61,inportb(0x61) & 0xFC);
}
The above programs the interval timer and then turns it on. A value of 0xb4 is loaded into
the command register 0x43. This value signifies that the channel 2 is to programmed,
both the bytes of divisor value are to loaded, the interval timer is to be programmed in
mode 2 and is to be used as a binary counter.
Then the divisor value say 0x21ffH, is loaded serially. First 0xFF low byte and then the
high byte 0x21 is loaded. Both the least significant bits of 0x61 port are set to turn on the
speaker and connect it to the interval timer.
On a key press the speaker is again disconnected and turned off.
Timer Count:
40:6CH
Incremented every 1/18.2 seconds. Whenever INT8
unsigned long int far *time = (unsigned long int far*) 0x0040006C
void main()
{
unsigned long int tx;
tx = (*time);
tx = tx +18;
puts(“Before”);
while((*time) <= tx);
puts(“After”);
}
Delay can be produced using double word variable in the BIOS Data area placed at the
location 0040:006C. This value contains a timer count and is incremented every 1/18th of
a second. In this program the this double word is read, placed in a program variable and
incremented by 18. The value of 40:6cH is compared with this variable in a loop. This
loop iterates until the value of 40:6cH is not greater. In this way this loop will keep on
iterating for a second approximately.
The inner while loop in the program is used to induce delay. The outer loop simply
reloads the divisor value each time it iterates after reducing this value by 30. In this way
the output frequency of the interval timer changes after every quarter of a second
approximately. The speaker will turn on with a low frequency pitch and this frequency
will increase gradually producing a spectrum of various sound pitches.
Sample Program
#include <dos.h>
#include <bios.h>
void interrupt (*oldint15) ( );
void interrupt newint15 (unsigned int BP, unsigned int DI,
unsigned int SI, unsigned int DS, unsigned int ES,
unsigned int DX, unsigned int CX, unsigned int BX,
unsigned int AX, unsigned int IP, unsigned int CS,
unsigned int flags);
void main ( )
{
oldint15 = getvect (0x15);
setvect (0x15, newint15);
keep (0, 1000);
}
The above program is a TSR program that can be used to turn the speaker on/off. The
above program intercepts the int 15h. Whenever this interrupt occurs it looks for service #
0x4f (keyboard hook). If ‘S’(0x1f scan code) has been pressed it toggles the speaker.
Sample Program
#include <dos.h>
#include <bios.h>
unsigned int divisors[4]={0x21ff,0x1d45,0x1b 8a,,0x1e4c};
unsigned long int far *time =(unsigned long int far *)0x0040006C;
void main ()
{ unsigned long int tx;
int i=0;
while (!kbhit ())
{
while (i<4)
{ outport(0x43,0xB4);
outport(0x42,*((char *)(&d ivisor[i])));
outport(0x42,*(((char *)(&div isor[i]))+1));
outport(0x61, inport(0x61)|3);
tx=*time;
tx=t x+4;
while (t x >= (*time));
i++;
}
i=0;
}
outport(0x61,inport(0x61)&0xFC);
}
This program generates a tune with 4 different pitches. This program is quite similar to
the one discussed earlier. The only major difference is that in that program the pitch was
gradually altered from low to high in this the pitches change periodically until a key is
pressed to terminate the outer loop. Four various pitches are maintained and their divisor
values are placed in the divisors[] array. All these divisor values are loaded one by one
after a delay of approximately quarter of a second and this continues until a key is
pressed.
Sample Program
#include <stdio.h>
#include <dos.h>
#include <bios.h>
struct tagTones
{ unsigned int divisor;
unsigned int delay;
};
struct tagTones Tones[4]={
{0x21ff,3},{0x1d45,2},{0x1b8a,3},{0x1e4c,4}};
int i,ticks,flag=0 ;
void interrupt (*oldint15)();
void interrupt (*oldint8)();
void interrupt newint15();
void interrupt newint8();
void main ()
{
oldint15=getvect(0x15);
setvect(0x15,newint15);
oldint8=getvect(0x08);
setvect(0x08,newint8);
keep(0,1000);
}
This is an interrupt driven version of the previous program. This program makes use of
the timer interrupt rather than a loop to vary the divisor value. Moreover interrupt 15 is
used to turn the speaker on /off.
The speaker turns on whenever ‘S’ (scan code 0x1f) is pressed and turns off whenever
‘A’ (scan code 0x1E) is pressed.
The timer interrupt shift the divisor value stored in the tones structure whenever the
required numbered of ticks( timer counts) have passed as required by the value stored in
the delay field of the tone structure.
More such divisor values and their delays can be initialized in the tones structure to
generate an alluring tune.
Parallel Communication
Output
D0
D1
D2
CPU Parallel Out Put Device
D7
Busy
Strobe
PPI is used to perform parallel communication. Devices like printer are generally based
on parallel communication. The principle of parallel communication is explained in the
slide above. It’s called parallel because a number of bits are transferred from one point ot
another parallel on various lines simultaneously.
Parallel Communication
Input
D0
D1
D2
CPU Parallel Input Device
D7
DR
CPU I/O
Controller
Parallel Communication
¾Faster
¾Only Economically Feasible For
Small Distances
Parallel
CPU PPI I/O Device
Printer
The PPI acts as an interface between the CPU and a parallel I/O device. A I/O device
cannot be directly connected to the buses so they generally require a controller to be
placed between the CPU and I/O device. One such controller is the PPI. Here we will see
how we can program the PPI to control the device connected to the PPI which generally is
the printer.
Int 17H
Int 17H is used to control the printer via the BIOS. The BIOS functions that perform the
printer I/O are listed in the slide above with its other parameter i.e DX which contains the
LPT number. A standard PC can have 4 PPI named LPT1, LPT2, LPT3 and LPT4.
Status Byte
7 6 5 4 3 2 1 0
Time out
Printer Busy
Receive Mode Selected
Out of Paper
The above listed function returns a status byte in the AH register whose meaning is
described in the slide above. Various bits of the byte describe the status of the printer.
The BIOS service once invoked will try to perform the requested operation on the printer
repeated for a certain time period. In case if the operation is rendered unsuccessful due to
any reason BIOS will not quit trying and will try again and again until the number of tries
specified in the timeout bytes shown above runs out.
If((pstate&0x29)!=0)or
((pstate&0x80)==0) or
((pstate&0x10)==0)
{printerok=FALSE;}
else
{printerok=TRUE;}
The status of the printer can be used in the above described manner to check if the printer
can perform printing or not. In case there is a transfer error, the printer is out of paper or
there is a timeout the printer could not be accessed. Or if the printer is busy or if the
printer is offline the printer cannot be accessed. The pseudo is just performing these
checks.
Printing Programs
Sample Program
Printing Program
union REGS regs; FILE *fptr;
void main(void)
{
fptr=fopen(“c:\\temp\\abc.txt”,”rb”);
regs.h.ah=1;
regs.x.dx=0;
int86(0x17,®s,®s);
while(!feof(fptr))
{regs.h.ah=2;
regs.x.dx=0;
int86(0x17,®s,®s);
if ((regs.h.ah & 0x80)==0x80)
{ regs.h.ah=0;
regs.h.al=getc(fptr);
int86(0x17,®s,®s);
}}}
The above program performs programmed I/O on the printer using BIOS services. The
program firstly initializes the printer int 17H/01. The while loop will end when the end of
file is reached, in the loop it checks the printer status (int 17h/02) and write the next byte
in the file if the printer is found idle by checking the most significant bit of the status
byte.
Sample Program
The above program intercepts int 17H. Whenever a certain program issues int 17H to
print a character the above TSR program will intercept the service and do nothing if A or
Z is to be printed rest of the characters will be printed normally. Only the As and the Zs in
the printing document will be omitted.
Sample Program
In this sample program again int 17H is intercepted. The new interrupt function will
ignore all the spaces in the print document.
Sample Program
In this program interrupt 17h is again intercepted. Whenever a character is to printed the
new function call the old function thrice. As a result a single character in the print
document will be repeated 4 times.
Now we will see how the register within the PPI can be accessed directly to control the
printer.
Above slide list the addresses within the BIOS data area where the base address (starting
port number) of LPT devices is stored.
The dump of BIOS data area address specified in the previous slide for a certain computer
shows that the base port address of LPT1 is 0x03bc, for lpt2 it is 0x0378, for Lpt3 it is
0x0278. These values need not be the same for all the computer and can vary from
computer to computer.
Swapping LPTs
The LPTs can be swapped i.e LPT1 can be made LPT2 and vice versa for LPT2. This can
be accomplished simply by swapping their addresses in the BIOS data area as shown in
the slide above.
LPT Ports
7 6 5 4 3 2 1 0
Base +1=Printer Status
Printer is Busy
The first port (Base +0) is the data port. Data to be sent/received is placed in this port. In
case of printer the (Base + 1) is the printer status port as described in the slide. Each bit
represents the various status of the printer quite similar to the status byte in case of BIOS
service.
7 6 5 4 3 2 1 0
0 0 0 IRQ SI IN ALF ST
(Base +2) is the printer control register it is used to pass on some control information to
the printer as described in the slide.
The above program directly accesses the registers of the PPI to print a file. The while
loop terminates when the file ends. The if statement only schecks if the printer is busy of
not. If the printer is idle the program writes the next byte in file on to the data port and
then turns the strobe bit to 1 and then 0 to indicate that a byte has been sent to the printer.
The loop then again starts checking the busy status of the printer and the process
continue.
Printer
Interface
Printer ACK
Interface
INT
PIC IRQ7
Printer
The printer interface uses the IRQ 7 as shown in the slide above. Therefore if interrupt
driven I/O is to be performed int 0x0f need to be programmed as an hardware interrupt.
Above is a listing of a program that uses int 0x0f to perform interrupt driven I/O. To
enable the interrupt 0x0f three things are required to be done. The interrupt should be
enabled in the printer control register; secondly it should also be unmasked in the IMR in
PIC. The program can then intercept or set the vector of interrupt 0x0f by placing the
address of its function newint();
The newint() will now be called whenever the printer can perform output. This newint()
function writes the next byte in buffer to the data registers and then send a pulse on the
strobe signal to tell the printer that data has been sent to it. When whole of the buffer has
been sent the int 0x0f vector is restored, interrupt is masked and the memory for the
program is de-allocated.
The above listing might not work. Not all of the printer interfaces are designed as
described above. Some modifications in the printer interface will not allow the interrupt
driven I/O to work in this manner. If this does not work the following strategy can be
adopted to send printing to the printer in background.
#include <stdio.h>
#include <dos.h>
#include <bios.h>
#include <conio.h>
#include <stdlib.h>
void interrupt (*oldint)();
void interrupt newint();
unsigned int far * lpt = (unsigned int far *)0x00400008;
char st[80]= "this is a test print string !!!!!!!!!!!";
int i ;
void main ()
{
oldint = getvect(0x08);
setvect(0x08,newint);
keep(0,1000);
}
This program uses the timer interrupt to send printing to the printer in the back ground.
Whenever the timer interrupt occurs the interrupt function checks if the printer is idle or
not. If it’s the printer is idle it takes a byte from the buffer and sends it to the data port of
the printer interface and then sends a pulse through the strobe signal. When the buffer is
full the program restores the int 8 vector and the relinquishes the memory occupied by the
program.
Not all the bits of the internal registers of the PPI are available in standard PCs. In
standard PCs the PPI is connected to a DB25 connector. And some of the bits of its
internal registers are available as pin outs as describes in the slide above.
Computer to Computer
Connectivity
It might be desirable to connect one computer to another via PPIs to transfer data. One
might desire to connect them such that one port of PPI at one end is connected to another
port of the other PPI at the other end. But interconnecting the whole 8 bits of PPI cannot
be made possible as all the bits of the internal ports are not available as pinouts. So the
answer is to connect a nibble (4-bits) at one end to the nibble at the other. In this way two
way communication can be performed. The nibbles are connected as shown in the slide
above.
PPI Interconnection
P0 2 15 Q3
P1 3 13 Q4
P2 4 12 Q5
P3 5 10 Q6
P4 6 11 Q7
Q3 15 2 P0
Q4 13 3 P1
Q5 12 4 P2
Q6 10 5 P3
Q7 11 6 P4
The pins that are interconnected are shown in the slide above. Another thing worth
noticing is that the 4th bit of the data port is connected to the BUSY and vice versa. The
BUSY is inverted before it can be read from the status port. So the 4th bit in data port at
PC1 will be inverted before it can be read at the 7th bit of status register at PC2.
Flow Control
An algorithm should be devised to control the flow of data so the receiver and sender may
know when the data is to be received and when it is to be sent. The following slides
illustrate one such algorithm.
D4 D3 D2 D1 D0
Sender
0 B3 B2 B1 B0
Sender sends
LOW Nibble
and D4 = 0
received as
BUSY = 1
Receiver
1 B3 B2 B1 B0
BUSY ACK PE SLC ER
E7 E6 E5 E4 E3
First the low nibble of the byte is sent from the sender in bit D0 to D3 of the data port. D4
bit is cleared to indicate the low nibble is being sent. The receiver will know the arrival of
the low nibble when its checks BUSY bit which should be set (by the interface) on
arrival.
The receiver then sends back the nibble turning its D4 bit to 0 as an acknowledgement of
the receipt of the low nibble. This will turn the BUSY bit to 1 at the sender side.
D4 D3 D2 D1 D0
Sender
1 B7 B6 B5 B4
Sender sends Hi
Nibble and turns
D4 = 1 received
as BUSY = 0 by
Receiver
Receiver
0 B7 B6 B5 B4
BUSY ACK PE SLC ER
The sender then send the high nibble and turns its D4 bit to 1 indicating the transmission
of high nibble. On the receiver side the BUSY bit will turn to 0 indicating the receipt of
high nibble.
The receiver then sends back the high nibble to the sender as an acknowledgment.
D4 D3 D2 D1 D0
13 - Serial Communication
This is the sender program. This program if find the BUSY bit clear sends the low nibble
but turns the D4 bit to 0 before sending. Similarly it right shifts the byte 4 times sets the
D4 bit and then sends the high nibble and waits for acknowledgment until the BUSY is
cleared.
int i;
while (1)
{ if ((inport(*lpt + 1)& 0x80) == 0x80)
{ x = inport ((*lpt) + 1);
x = x >> 3;
x = x & 0x0F;
outport((*lpt), x);
while((inport(*lpt + 1) &0x80) == 0x80);
}
else
{ y = inport ((*lpt) + 1);
y = y << 1;
temp = y;
y = y & 0xF0; //instruction added
y = y | x;
This is receiver program. If the BUSY bit is clear it receives the low nibble and stores it
in x. Similarly if the BUSY bit is 0 it receives the high nibble and concatenates the both
nibble to form a byte.
Serial Communication
Serial Communication
• Advantages
• Disadvantages
Types Of Serial Communication
• Synchronous
• Asynchronous
In case of serial communication the bits travel one after the other in serial pattern. The
advantage of this technique is that in this case the cost is reduced as only 1 or 2 lines
maybe required to transfer data.
The major disadvantage of Serial communication is that the speed of data transfer maybe
reduced as data is transferred in serial pattern.
There are two kinds of serial communications.
Synchronous Communication
Synchronous Communication
• Timing signal is used to identify start and end
of a bit.
LSB MSB
1 1 0 1 0 1 1 0
0110 1011
Synchronous Communication
• Sampling may be edge triggered.
• Special line may be required for
timing signal (requires another line).
• Or the timing signal may be encoded
within the original signal (requires
double the bandwidth).
Asynchronous Communication
Asynchronous Communication
• Does not use make use of timing
signal.
• Each byte (word) needs to
encapsulated in start and end bit.
In case of asynchronous communication no timing signal is required but each byte needs
to be encapsulated to know the end and start of a byte.
Sampling Rate
Bit rate = 9600
A bit is sampled after = 1/9600
-- But start and end bits of a particular
Byte cannot be recognized.
-- So 1.5 stop bit (high) is used to
encapsulate a byte. A low start bit at
the start of Byte is used to identify the
start of a Byte.
Sampling Rate
-- Bit rate and other settings should be
the same at both ends i.e.
- Data bits per Byte. (5 – 8 )
- Parity check
- Parity Even/Odd
- No. of stop bits.
Sampling Rate
1/1300 sec
RS – 232C Standard
• Standard for physical dimensions of the
connectors.
RS – 232C Cable
PC (DCE)
Modem
(DTE) Connected via
serial port
13
25
12
24
11
23
10
22 RI
9
21
CD 8
20 DTR
GND 7 19
DSR 6 18
CTS 5
17
RTS 4
16
RD 3
15
TX D 2
14
1
25 pin connector on PC
The pin outs of the DB25 connector used with RS232C is shown in the slide above.
RS – 232C Standard
• Standard for physical dimensions of the
connectors.
RS – 232C Cable
PC (DCE)
Modem
(DTE) Connected via
serial port
13
25
12
24
11
23
10
22 RI
9
21
CD 8
20 DTR
GND 7 19
DSR 6 18
CTS 5
17
RTS 4
16
RD 3
15
TX D 2
14
1
25 pin connector on PC
RI
CD
DSR
PC RTS MODEM
CTS
RxD TxD
Data is received through the RxD line. Data is send through the TxD line. DTR (data
terminal ready) indicates that the data terminal is live and kicking. DSR(data set ready)
indicates that the data set is live. Whenever the sender can send data it sends the signal
RTS( Request to send) if as a result the receiver is free and can receive data it send the
sender an acknowledge through CTS( clear to send) indicating that its clear to send now.
DB9 Connector
1
CD
6
2 DSR
Rx D 7
3 RTS
TxD 8
4 CTS
DT R 9
5 RI
GND
UART internals
UART Internals R xD
Receiver Buffer Register Receiver Shift Register
Transmit Shift T xD
Transmitter Holding Register
Register
This slide shows the various internal registers within a UART device. The programmer
only needs to program these registers efficiently in order to perform asynchronous
communication.
Register summary
Base +
Transmitter Holding Register THR 0
Receiver Dat a RBR 0
Band Rate Divisor (Low Byte) DLL 0
Band Rate Divisor (High Byte) DLM 1
Interrupt Enable IER 1
FIFO Control Register FCR 2
Interrupt ID IIR 2
Line Cont rol LCR 3
Mode Control MCR 4
Line Status LSR 5
Modem Status MSR 6
Scratch Pad SP 7
The above table lists the registers within the UART ans also shows their abbreviation.
Also it shows there offsets with respect to the base register.
Text Dump
-d 40:0
The above dump of the BIOS data area for a certain computer shows that the address of
COM1 is 03F8 , the address of COM2 is 02F8 and the address of COM3 is 03E8. These
addresses may not be same for all the computers and may vary computer to computer.
The baud rate is set in accordance with the divisor value loaded within the UART internal
registers base +0 and base +1.
Line Control Register
The line control register contains important information about the behaviour of the line
through which the data will be transferred. In it various bits signify the word size, length
of stop bits, parity check, parity type and also the a control bit to load the divisor value.
The bit 7 if set indicates that the base +0 and base + 1 will act as the divisor register
otherwise if cleared will indicate that base + 0 is the data register.
Data Ready =1
Line status register illustrates the status of the line. It indicates if the data can be sent or
received. If bit 5 and 6 both are set then 2 consecutive bytes can be sent for output. Also
this register indicates any error that might occur during communication.
Trigger Interrupt
On Data Ready =1
Trigger Interrupt
As soon as THR is empty =1
Trigger Interrupt
On change in Modem Status =1 Trigger Interrupt
On line status change =1
If interrupt driven output is to be performed then this register is used to enable interrupt
for the UART. It can also used to select the events for which to generate interrupt as
described in the slide.
Interrupt ID Register
Interrupt ID Register
2 1 0
Trigger Triggered
Modem/Line
00 =Change in Modem Status
01 = THR is Empty
10 = Data is Ready
11 =Error in Data
Once an interrupt occurs it may be required to identify the case of the interrupt. This
register is used to identify the cause of the interrupt.
15 - COM Ports
1 =Self Test
0 =Normal RTS
In case software oriented flow control technique is used the bits 0 and 1 need to be set in
that case. Bit #3 need to be set to enable interrupts. Moreover if a single computer is
available to a developer the UART contains a self test mode which can be used by the
programmer to self test the software. In self test mode the output of the UART is routed
to its input. So you receive what you send.
Change
CD in CTS
RI Change in DSR
DSR Change in RI
CTS Change in CD
This register indicates the status of the modem status line or any change in the status of
these lines.
FIFO Queue
This feature is available in the newer version of the UART numbered 16500. A queue or
a buffer of the input or output bytes is maintained within the UART in order to facilitate
more efficient I/O. The size of the queue can be controlled through this register as shown
by the slide.
Interrupt ID Register
7 6 3 2 1 0
Interrupt
1= Interrupt Triggered
Because Buffer is not full Triggered =1
But other side has
stop sending data. Reasons of Interrupt
(Time OUT) 00=Change in Modem Line Status
01=THR is Empty
10=Data is ready
11=Error in Data Transmit
Any one of these BEING
Set Indicates FIFO is ON.
INT # 14H
The following slide shows how int 14H service 0 can be used to set the line parameter of
the UART or COM port. This illustrates the various bits of AL that should be set
according before calling this service.
Service # 0
AL =
The Service on return places the line status in AH register as shown in the slide below.
AH = Line Status
And places the modem status in the AL register as shown in slide below.
AL = Modem Status
CD Change in CTS
RI Change in DSR
Ready (DSR) Change in RI
Ready to Receive Change in CD
Other service of 14h include service #1 which is used to send a byte and service #2 which
is used to receive a byte as shown in the slide below.
Service # 01
ON ENTRY
AL = ASCII character to send
ON RETURN
AH = Error Code
If 7th bit in AH = 1 = Unsuccessful
0 = Successful
Service # 02
ON RETURN
AL = ASCII character received
AH = Error Code
Modem
PC Tel Line
Modem
PC
Modem
Modem is generally used to send/receive data to/from an analog telephone. Had the
telephone line been purely digital there would have been no need of a modem in this
form. If data is to be transferred from one computer to another through some media which
can carry digital data then the modem can be eliminated and the UART on both
computers can be interconnected. Such arrangement is called a NULL modem.
NULL
Modem
PC PC
CD 1 CD 1
RxD 2 RxD 2
TxD 3 TxD 3
DTR 4 DTR 4
GND 5 GND 5
DSR 6 DSR 6
RTS 7 RTS 7
CTS 8 CTS 8
RI 9 RI 9
The above slide shows the configuration used to interconnect two UARTs In this way a
full duplex communication can be performed and moreover flow control can also be
performed using DSR, DTS, RTS and CTS signals.
Sample Program
Example:
#include<BIOS.H>
#include<DOS.H>
char ch1, ch2;
16 - COM Ports II
Sample Program using BIOS routines
Example:
#include<BIOS.H>
#include<DOS.H>
char ch1, ch2;
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.
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;
}
}
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 programs the line control register for all the required line parameters.
The SelfTestOn() function simply enables the self test facility within the modem control
register.
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.
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
#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);
}
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.
•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);
}
#include <dos.h>
#include <bios.h>
char ch1,ch2;
void main ( )
{
initialize(0x3f8);
while (1)
{
if ( ((inport(0x3fd)&0x20)==0x20) && (kbhit()))
{ ch1=getche();
outport(0x3f8,ch1);
}
if (( (inport(0x3fd)&0x01)==1))
{ ch2= inport(0x3f8);
putch(ch2);
}
if (( ch1==27) || (ch2==27))
break;
}
}
This program is same functionally as one of the previous programs which used BIOS
services to get the input data and send the output data. The only difference is that in this
case it does the same directly accessing the ports.
Only two or three of the lines are being used to send receive data rest of the lines are
being used for flow control. The cost of these lines can be reduced by reducing the lines
used to flow control and incorporating software oriented flow control rather than
hardware oriented flow control as show in the slide below.
The DTR, DSR, RTS and CTS lines have been eliminated to reduce cost but in this flow
control will be performed in a software oriented manner.
XON whenever received indicates the start of communication and XOFF whenever
received indicates a temporary pause in the communication.
Following is a pseudo code which can be used to implement the software oriented flow
control.
while (1)
{
receivedchar = readchar (com);
if (receivedchar == XON)
{ ReadStatus = TRUE;
continue;
}
if (receivedchar == XOFF)
{ ReadStatus = FALSE;
continue;
}
if (ReadStatus == TRUE)
Buf [i++] = receivedchar;
}
the received character is firstly analysed for XON or XOFF character. If XON is received
the status is set to TRUE and if XOFF is received the status is set to FALSE. The
characters will only be received if the status is TRUE otherwise they will be discarded.
Real time clock is a device incorporated into the PC to update time even if the computer
is off. It has the characteristics shown in the slide above which enables it to update time
even if the computer is off.
The BIOS interrupt 0x1Ah can be used to configure this clock as shown in the slide
below it has various service for getting/setting time/date and alarm.
AL = 1 if Midnight passed
AL = 0 if Midnight not passed
Set Clock Counter 1AH/01
ON ENTRY
AH = 01
CX = Clock count (Hi word)
DX = Clock count (Low word)
RTC internals
7FH
The RTC internally has an array of registers which can be used to access the 64 byte
battery powered CMOS RAM.
Internal Ports
70 – 7FH (16 ports)
Only 70 & 71H are important from
programming point of view
The following slide shows the function of some of the bytes in the battery powered RAM
used to store the units of time and date.
Week Day
01H = Sunday
02H = Monday
03H = Tuesday
04H = Wednesday
05H = Thursday
06H = Friday
07H = Saturday
The value in the days of the week byte indicates the day according to slide shown above.
Generally BCD values are used to represent the units of time and date.
Year
No of Century and Year are in BCD.
Following slide shown a fragment of code that can be used to read or write onto any byte
within the 64 byte battery powered RAM.
Status Register A
7 6 5 4 3 2 1 0
Interrupt
frequency
Time
frequency
The lower 4 bits of this register stores a code indicating the frequency with which the
RTC hardware interrupt can interrupt the processor. The next field is used to specify the
time frequency i.e. the frequency with the time is sampled and hence updated. The most
significant bit indicates that after time sampling if the time has been updated in to the 64
byte RAM or not.
Status Register B
7 6 5 4 3 2 1 0
0 = Daylight
Update time saving time
The status register B is the main control register. It is used to specify the date time
formats and is also used to enable interrupt on various events like alarm time and time up-
dation. Another feature of RTC is periodic interrupt which occur with a frequency
specified in the A register.
Status Register C
7 6 5 4 3 2 1 0
Status register is used to identify the reason of interrupt generation as described in the
slide above.
Status Register D
7 6 5 4 3 2 1 0
0 = Battery Dead
Only the most significant byte in status register D is important which on being 0 indicates
that the battery is dead.
Sample Program.
void main ()
{
unsigned int hours, months, seconds;
_AH =2;
geninterrupt(0x1a);
hours = _CH;
minutes = _CL;
seconds = _DH;
hours = hours <<4;
*((unsigned char *)(& hours)) =
(*((unsigned char *) (& hours))) >>4;
hours = hours + 0x3030;
The above program uses the service int 1Ah/02H to read the time from the real time
clock. It reads the time and converts the packed BCD values into unpacked BCD values.
These values are then converted into ASCII and displayed using the printf() statement.
#include <bios.h>
#include <dos.h>
void main ()
{
int hrs,mins,secs;
char temp;
do {
outportb(0x70,0x0a);
temp=inportb(0x71);
}while ((temp & 0x80) == 0);
outportb(0x70,0);
secs=inport(0x71);
outportb(0x70,2);
mins=inport(0x71);
outportb(0x70,4);
hrs=inport(0x71);
printf("%c%c:%c%c:%c%c",
*(((unsigned char*)(&hrs))+1),
*((unsigned char*)(&hrs)),
*(((unsigned char*)(&mins))+1),
*((unsigned char*)(&mins)),
*(((unsigned char*)(&secs))+1),
*((unsigned char*)(&secs)));
getch();
}
The time units are similarly read and converted to ASCII and displayed.
#include <bios.h>
#include <dos.h>
unsigned char ASCIItoBCD(char hi, char lo)
{
hi = hi - 0x30;
lo = lo - 0x30;
hi = hi << 4;
hi = hi | lo;
return hi;
}
void main ()
{
unsigned char hrs,mins,secs;
char ch1, ch2;
puts("\nEnter the hours to update: ");
ch1=getche();
ch2=getch();
hrs = ASCIItoBCD(ch1, ch2);
*tm = 0;
_CH = hrs;
_CL=mins;
_DH= secs;
_DL=0;
_AH =3;
geninterrupt(0x1a);
puts("Time Updated");
}
The above listing of the program inputs the time from the user which is in ASCII format.
It converts the ASCII in packed BCD and uses BIOS services to update the time. In DOS
or windows this time change may not remain effective after the completion of the
program as the DOS or windows device drivers will revert the time to original even if it
has been changed using this method.
Sample Program
#include <bios.h>
#include <dos.h>
unsigned char ASCIItoBCD (unsigned
char hi, unsigned char lo)
{
hi = hi - 0x30;
lo = lo - 0x30;
hi = hi << 4;
hi = hi | lo;
return hi;
}
void main ()
{
unsigned int hrs,mins,secs;
char ch1, ch2;
int temp;
outportb(0x70,0x0b);
temp = inport(0x71);
outport (0x70,0);
outport (0x71,secs);
outport (0x70,2);
outport (0x71,mins);
outport (0x70,4);
outport (0x71,hrs);
outportb(0x70,0x0b);
temp = inport(0x71);
temp = temp & 0x7f;
outportb(0x70,0x0b);
outportb(0x71,temp);
delay (30000);
do {
outportb(0x70,0x0a);
temp=inportb(0x71);
}while ((temp & 0x80) == 0);
outportb(0x70,0);
secs=inport(0x71);
outportb(0x70,2);
mins=inport(0x71);
outportb(0x70,4);
hrs=inport(0x71);
hrs = hrs <<4;
*((unsigned char *)(&hrs)) =
(*((unsigned char *)(&hrs))) >>4;
hrs = hrs + 0x3030;
To elaborate more on the problem posed by the OS device drivers here is another
program. This program first updates the time accessing the 64 byte RAM directly and
taking the new time as input from the user. After updating the program produces a delay
of 30 seconds and then reads time to display it. A difference of 30 seconds will be noticed
in the time entered and the time displayed. This shows that during the execution of the
program the time was successfully changed and was being updated accordingly.
#include <bios.h>
#include <dos.h>
void main ()
{
unsigned int cen,yrs,mons,days;
_AH =4;
geninterrupt(0x1a);
cen=_CH;
yrs=_CL;
mons=_DH;
days=_DL;
cen = cen <<4;
*((unsigned char *)(&cen)) =
(*((unsigned char *)(&cen))) >>4;
cen = cen + 0x3030;
clrscr();
printf("%c%c-%c%c-%c%c%c%c",
*(((unsigned char*)(&days))+1),
*((unsigned char*)(&days)),
*(((unsigned char*)(&mons))+1),
*((unsigned char*)(&mons)),
*(((unsigned char*)(&cen))+1),
*((unsigned char*)(&cen)),
*(((unsigned char*)(&yrs))+1),
*((unsigned char*)(&yrs)));
getch();
}
The above sample program takes ASCII input from the user for the new date. After taking
all the date units as input the program sets the new date using the BIOS service 1Ah/05H.
The alarm can be set using BIOS function 1Ah/06h. Once the alarm is set BIOS will
generate the interrupt 4Ah when the alarm time is reached. The above program intercepts
the interrupt 4Ah such that newint() function is invoked at the time of alarm. The newint()
function will just display a character ‘A’ on the upper left corner of the screen. But this
program may not work in the presence of DOS or Windows drivers.
#include <bios.h>
#include <dos.h>
void interrupt newint70();
void interrupt (*oldint70)();
unsigned int far *scr =
(unsigned int far *)0xb8000000;
unsigned char ASCIItoBCD(char hi, char lo)
{
hi = hi - 0x30;
lo = lo - 0x30;
hi = hi << 4;
hi = hi | lo;
return hi;
}
outportb(0x70,1);
outportb(0x71,secs);
outportb(0x70,3);
outportb(0x71,mins);
outportb(0x70,5);
outportb(0x71,hrs);
outportb(0x70,0x0b);
temp = inport(0x71);
temp = temp | 0x70;
outportb(0x70,0x0b);
outportb(0x71,temp);
oldint70 = getvect(0x70);
setvect(0x70, newint70);
keep(0,1000);
}
void interrupt newint70()
{
outportb(0x70,0x0c);
if (( inport(0x71) & 0x20) == 0x20)
sound(0x21ff);
*scr=0x7041;
(*oldint70)();
}
This program takes the time of alarm as ASCII input which is firstly converted into BCD.
This BCD time is placed in the 64 byte RAM at the bytes which hold the alarm time.
Once the alarm time is loaded the register is accessed to enable the interrupts such that
other bits are not disturbed. Whenever the RTC generates an interrupt, the reason of the
interrupt needs to be established. This can be done by checking the value of status register
C, if the 5th bit of register C is set it indicates that the interrupt was generated because the
alarm time has been reached. The reason of interrupt generation is established in the
function newint70(). If the interrupt was generated because of alarm then speaker is
turned on by the sound() function and a character ‘A’ is displayed on the upper left corner
of the screen.
INT 11H
INT 12H
INT 11H
used to get hardware environment info.
On Entry
call 11H
On Exit
AX = System Info.
Interrupt 11H is used to determine the systems information. On return this service returns
the systems info in AX register. The detail of the information in AX register is shown in
the slide above.
Int 12H is used to determine the amount of conventional memory interfaced with the
processor in kilobytes. The amount of memory above conventional memory (extended
memory) can be determined using the service 15H/88H.
Types of Processor
15 12
Unused in 8086
The above slides show the test that can be used to determine if the underlying processor is
8086 or not. If its not 8086 some test for it to be 80286 should be performed.
If the bits 14-12 are cleared on pushing the flags register then the processor is 80286. This
can be checked as shown in the slide above.
Eflags
Alignment Check
Alignment Check:
mov dword ptr [12], EDX
In 32-bit processors it is more optimal in terms of speed if double word are placed at
addresses which ate multiples of 4. If data items are placed at odd addresses the access to
such data items is slower by the virtue of the memory interface of such PCs. So it more
optimal to assign such variables addresses which are multiple of 4. The 386 and 486 are
both 32 bit processors but 486 has alignment check which 386 does not have. This
© Copyright Virtual University of Pakistan 164
20 - Determining system information
property can be used to distinguish between 386 and 486. If the previous tests have failed
then there is a possibility that the processor is not 8086 or 286. To eliminate the
possibility of it being a 386 we perform the alignment test. As shown in the slide above
the 18th bit of the EFLAGS register is the alignment bit, it sets if a double word is moved
onto a odd address or an address which does not lie on a 4 byte boundary.
Alignment Test
pushfd
pop eax
mov ecx, eax
mov dword ptr [13], EDX
pushfd
pop eax
In the above slide a double word is moved into a odd address. If the processor is 386 then
the 18th bit of the EFLAGS register will not be set, it will be set if the processor is higher
than 386.
CPUID Test
• 486 will pass the alignment test.
• To distinguish 486 with Pentium
CPUID Test is used.
A Pentium and 486 both will pass the alignment test. But a 486 does not support the
CPUID instruction. We will next incorporate the CPUID instruction support test to find if
the processor is 486 or a Pentium as Pentium does support CPUID instruction.
CPUID Test
21
Eflags
If the CPUID instruction is available the processor is a Pentium processor otherwise it’s a
486.
CPUID Instruction
Before After the execution of Instruction
EAX = 0 EAX = 1
EBX – EDX – ECX
EBX = “Genu”
EDX = “ineI”
ECX = “ntel”
The CPUID instruction, if available, returns the vendor name and information about the
model as shown in the slide above. Beside rest of the test the CPUID instruction can also
be used by the software to identify the vendor name.
1 1
11 after initialization
signifies extended
precision operation
The coprocessor control word contains some control information about the coprocessor.
The bit number 7 of coprocessor control word is the Interrupt Enable Flag and bit number
8 & 9 should contain 11 on initialization.
C3 C3 C1 C0
C3 C2 C0
0 0 0 st > operand
0 0 1 st < operand
1 0 0 st = operand
The coprocessor status register stores the status of the coprocessor. Very much like the
flags register in the microprocessor the Coprocessor status word can be used to determine
the result of a comparison as shown in the slide.
© Copyright Virtual University of Pakistan 168
20 - Determining system information
To Check Coprocessor is
• Initialize Present
• Read Hi – Byte of Control register.
• If value in Hi – Byte is 3, then
coprocessor is available, otherwise
its absent.
Once its established that the coprocessor is present then the model of the coprocessor
should be determined. In case an invalid numerical operation is requested the 8087
coprocessor generates an interrupt while the higher coprocessors does not use interrupts
in fact they make use of exceptions. This feature can be used to distinguish between 8087
and higher processor as shown in the slide above. The higher processor will not respond
to an attempt made to set the IEM flag while 8087 will respond.
If the sign of infinity can be reversed than the coprocessor is 80387 otherwise its 80387
void main()
{
PrintConfig();
}
In this program the general configurations of the computer are read using interrupt 11H,
12H and 15H. First its determined if the Processor is and AT (advanced technology all
processors above 8086) type computer or not. This can be done easily by checking its
signature byte placed at the location F000:FFFEH which will contain neither 0xFF nor
0xFE if its an AT computer. The program shows the size of conventional RAM using the
interrupt 12H, then if the computer is an AT computer then the program checks the
extended memory size using int 15H/88H and reports its size. And ultimately the program
calls int 11H to show the number and kind of I/O interfaces available.
21 - Keyboard Interface
Processor Identification
In the above slide the test for 8086 or not is performed by clearing all the bits of flags
register then reading its value by pushing flags and then poping it in AX, the bits 15-12 of
ax are checked if they have been set then it’s a 8086.
The above slide further performs the test for 80286 if the previous test fails. It sets the bit
14-12 of flags and then again reads back the value of flags through stack. If the bits 14-12
have been cleared then it’s a 80486.
mov [ebx+1],eax
pushfd
pop eax
shr first,18
shr eax,18
and first,1
and eax,1
cmp first,eax
inc dl
sti
jne pende
The above code performs the alignment test as discussed before by test the 18th bit after
addressing a double word at an odd address.
pushfd
pop eax
mov temp, eax
mov eax,1
shl eax,21
push eax
popfd
pushfd
pop eax
shr eax,21
shr temp,21
cmp temp, eax
inc dl
je pende
the above code performs a test to see if CPUID instruction is available or not for which
the bit number 21 of flags is set and then read back.
© Copyright Virtual University of Pakistan 173
21 - Keyboard Interface
A CPUID Program
#include "stdafx.h"
#include <stdio.h>
#include <dos.h>
unsigned long int id[3];
unsigned char ch='\0';
unsigned int steppingid ;
unsigned int model,family,type1 ;
unsigned int cpcw;
int main(int argc, char* argv[])
{
_asm xor eax,eax
_asm cpuid
_asm mov id[0], ebx ;
_asm mov id[4], edx ;
_asm mov id[8], ecx;
printf(" %s\n ", (char *) (id));
_asm mov eax,1
_asm cpuid
_asm mov ecx,eax
_asm AND eax,0xf;
_asm mov steppingid,eax;
_asm mov eax, ecx
The above program places 0 in eax register before issuing the CPUID instruction. The
string returned by the instruction is then stored and printed moreover other information
about family, model etc is also printed.
Detecting a Co Processor
_asm finit
_asm mov byte ptr cpcw+1, 0;
_asm fstcw cpcw
if ( *(((char *) (&cpcw))+1)==3)
puts("Coprocessor found");
else
puts ("Coprocessor not found");
After initialization the control word is read if the higher byte contains the value 3.
In the code above the IEM bit is set and then the value of control word is read to analyse
change in the control word. If the most significant bit is set then it’s a 8087 co processor
otherwise other tests must be performed.
An operation (like division by zero is performed) which results in infinity. Then the sign
of the result is reversed, if it can be reversed then its 80387 co processor otherwise its
certainly 80287.
KeyBoard Interface
60H
Proce ssor
64H
INTR
IRQ1 PIC
Synchronous Data
Keyboard
The keyboard interface as discussed earlier uses the IRQ1 and the port 60H as data port, it
also uses another port number 64H as a status port. The keyboard can perform
synchronous serial I/O.
1 = Output
1 = Parity Buffer full
Error
1 = Time Out Error 1 = Input Buffer
during input full
1 = Time Out Error
during output 1 = Keyboard Active
The above slide shows the detailed meaning of bits in port 64H.
Typematic Rate
7 6 5 4 3 2 1 0
Typematic Rate
Delay 11111 = 2 char/s
00 ¼ Second 11110 = 2.1 char/s
01 ½ Second 11101 = 2.3 char/s
11010 = 3 char/s
10 ¼ Second ::::::::::::::::
11 1 Second ::::::::::::::::
00100 = 20 char/s
00011 = 21.8 char/s
00010 = 24 char/s
00001 = 26.7 char/s
00000 = 30 char/s
The typematic rate of the keyboard can be controlled by a control word as depicted in the
slide above. The delay and typematic rates need to be specified in this control word. The
delay indicates the delay between first and second character input whenever a key is
pressed. The timing of rest of the successive character inputs for the same key is
determined by the typematic rate.
64H
The input character scan code is received at port 60H. A certain bit in the port 64H or
keyboard controller is used as the IBF (input buffer full) bit. A device driver can check
this bit to see if a character has been received from the keyboard on which this bit will
turn to 1.
Later on
Receives 0xFA to indicate
succe ssful transmi ssion
64H
Similarly some data (as control information) can be send to the keyboard. The processor
will write on the port 60H. The device driver will check the OBF( output buffer full bit of
port 64H which remains set as long as the byte is not received by the keyboard. On
receipt of the byte from the port 60H the keyboard device write a code 0xFA on the port
60H to indicate that the byte has been received properly.
Using the described information we can design a protocol for correctly writing on the
keyboard device as described below.
Keyboard is a typically an input device but some data can also be send to the keyboard
device. This data is used as some control information by the keyboard. One such
information is the typematic rate. This type matic rate can be conveyed to the keyboard as
described by the slide below.
Other such control information is the LED status. Every keyboard has three LEDs for
representing the status of Num Lock, Caps Lock and the Scroll Lock. If the device driver
© Copyright Virtual University of Pakistan 180
22 - Keyboard Interface, DMA Controller
needs to change the status then the LED status byte should be written on the keyboard as
described below. But before writing this byte the keyboard should be told that the control
byte is to be written. This is done by sending the code 0XED before sending the status
byte using the above described protocol.
Keyboard LEDs
LED Status byte
2 1 0
Scroll Lock
Num Lock
Caps Lock
#include <dos.h>
#include <conio.h>
char st [80];
int SendKbdRate(unsigned char data , int maxtry)
{
unsigned char ch;
do{
do{
ch=inport(0x64);
}while (ch&0x02);
outport(0x60,data);
do{
ch = inport(0x64);
}while (ch&0x01);
if (ch==0xfa)
{ puts("success\n");
break;
}
maxtry = maxtry - 1;
} while (maxtry != 0);
if (maxtry==0)
return 1;
else
return 0;
}
The above program has function SendKbdRate(). This function takes 2 parameters, first
one is value to be sent and the second one is the maximum number of retries it performs if
the byte cannot be sent. This function implements the described protocol. It first waits for
the IBF to be cleared and then starts trying to send the byte. The functions stops trying
either if 0xFA is received (success) or if the number of retries end (failure).
void main ()
{
//clrscr();
SendKbdRate(0xf3,3);
SendKbdRate(0x7f,3);
gets(st);
SendKbdRate(0xf3,3);
SendKbdRate(0,3);
gets(st);
}
Now this function is used to change the typematic rate. Firstly 0XF3 is written to indicate
that the typematic rate is to be changed then the typematic rate is set to 0x7F and a strng
can be type to experience the new typematic rate. Again this rate is set to 0. This program
will not work if you have booted the system in windows. First boot the system in DOS
and then run this program.
© Copyright Virtual University of Pakistan 182
22 - Keyboard Interface, DMA Controller
#include <bios.h>
#include <dos.h>
char st [80];
unsigned char far *kbd =
(unsigned char far *) 0x00400017;
int SendKbdRate(unsigned char data , int maxtry)
{
unsigned char ch;
do{
do{
ch=inport(0x64);
}while (ch&0x02);
outport(0x60,data);
do{
ch = inport(0x64);
}while (ch&0x01);
ch=inport(0x60);
if (ch==0xfa)
{ puts("success\n");
break;
}
maxtry = maxtry - 1;
} while (maxtry != 0);
if (maxtry==0)
return 1;
else
return 0;
}
void main ()
{
//clrscr();
SendKbdRate(0xed,3);
SendKbdRate(0x7,3);
puts("Enter a string ");
gets(st);
*kbd=(*kbd )|0x70;
puts("Enter a string ");
gets(st);
}
Again the same function is being used in this program to turn on the keyboard LEDs.
Firstly 0xED is sent to indicate the operation and then 7 is written to turn on all the LEDs.
But tuning on the LEDs like this will not change the keyboard status indicated by the byte
at 40:17H. If the status for the device driver usage is to changes as well then the
corresponding at 40:17H can be set by ORing it with 0x70. This program will not work if
you have booted the system in windows. First boot the system in DOS and then run this
program.
DMA Controller
DMA
DMA is a device which can acquire complete control of the buses and hence can be used
to transfer data directly from port to memory or vice versa. Transferring data like this can
prove faster because a transfer will consume 2 bus cycles if it is performed using the
processor. So in this approach the processor is bypasses and its cycles are stolen and are
used by the DMA controller.
The latch B of the DMA interface is used to hold the higher 4 or 8 bits of the 20 or 24 bit
absolute address respectively. The lower 16bits are loaded in the base address register and
the number of bytes to be loaded are placed in the count register. The DMA requests to
acquire buses through the HOLD signal, it receives a HLDA (Hold Acknowledge ) signal
if no higher priority signal is available. On acknowledgment the DMA acquires control of
the buses and can issue signals for read and write operations to memory and I/O ports
simultaneously. The DREQ signals are used by various devices to request a DMA
operation. And if the DMA controller is successful in acquiring the bus it sends back the
DACK signal to signify that the request is being serviced. For the request to be serviced
properly the DMA channel must the programmed accurately before the request.
DMA Cascading
A single DMA can transfer 8bit operands to and from memory in a single a bus cycle. If
16bit values are to be transmitted then two DMA controllers are required and should be
cascaded as shown above.
Internal Registers
• No of 16 & 8 bit Internal registers
• Total of 27 internal registers in DMA
Register Number Width
Starting Addre ss 4 16
Counter 4 16
Current Addre ss 4 16
Current Counter 4 16
Temporary Addre ss 1 16
Temporary Counter 1 16
Status 1 8
Command 1 8
Intermediate Memory 1 8
Mode 4 8
Mask 1 8
Request 1 8
The above slides shows the characteristics of each register when a DMA channel is to be
programmed and also shows the total number of registers in the DMA controller. Some of
the registers are common for all channels and some are individual for each channel.
DMA Modes
• Block Transfer
• Single Transfer
• Demand Transfer
The DMA can work in above listed modes. In block transfer mode the DMA is
programmed to transfer a block and does not pause or halt until the whole block is
transferred irrespective of the requests received meanwhile.
In Single transfer mode the DMA transfers a single byte on each request and updates the
counter registers on each transfer and the registers need not be programmed again. On the
next request the DMA will again transfer a single byte beginning from the location it last
ended.
Demand transfer is same as block transfer, only difference is that the DREQ signal
remains active throughout the transfer and as soon as the signal deactivates the transfer
stops and on reactivation of the DREQ signal the transfer may start from the point it left.
The above table shows the addresses of all the registers that should be programmed to
perform a transfer. These registers act as status and control registers and are common for
all the channels.
Terminal count if reached signifies that the whole of the block as requested through some
DMA channel has been transferred. The above status register maintains the status of
Terminal count (TC) and DREQ for each channel within the DMA.
This register can be used to simulate a DMA request through software (in case of memory
to memory transfer). The lower 2 bits contains the channel number to be requested and
the bit # 2 is set to indicate a request.
This register can be used to mask/unmask requests from a device for a certain DMA
channel. The lower 2 bits contains the channel number and the bit #2 is set if the channel
is to be masked.
This register can also be used to mask the DMA channels. It contains a single bit for each
channel. The corresponding bit is set to mask the requests for that channel.
This register can be used to set the mode on each. The slide shows the detail of the values
and bits which should be placed in the register in order to program a required mode.
A channel is programmed for a start address and the count of bytes to be transferred
before the transfer can take place. Both these values are placed in various registers
according to the channel number as shown by the slide above. Once the transfer starts
these values start changing. The start address is updated in to the current address and the
count is also updates as bytes are transferred. During the transfer the status of the transfer
can be analyzed by getting the values of these registers listed In the slide above for the
channel(s) involved in the transfer.
The above slide shows the port number for each channel in which the higher 4 or 8 bits of
the absolute address is stored in case of 20 or 24 bit address bus.
#include <dos.h>
#include <bios.h>
char st[80];
unsigned long int temp;
unsigned int i;
unsigned int count=48;
This program, programs the DMA channel 3 for read cycle by placing 0x0B in mode
register (0x0B). Before the channel is unmasked and the channel mode is programmed the
base address the count and the higher 4 or 8 bits of the address should be placed in base
register, count register and Latch B respectively. The 20 (or 24) bit address is calculated.
The higher 4 ( or 8) bits are placed in the Latch B for channel 3, then the rest of the 16
bits of the base address are placed in base register for channe3 and ultimately the count is
25 - File Systems
This program attempts to perform memory to memory transfer operation. This program
will only work for a 8086 processor, higher processors’ DMA may not support memor to
memory transfer.
#include <dos.h>
#include <bios.h>
This program, programs the channel 0 and channel 1 of the DMA. It loads the address of
Source string st in base register and the Latch B and loads the count register for channel 0
and does the same for st1. It then programs the mode, mask and command register for
memory to memory transfer and to unmask channel 0 and channel 1.
outportb(3,0xff);
outportb(3,0x07);
outportb(0x0b,0x85);
outportb(0x08,1);
outportb(0x0f,0x0c);
outportb(0x09,0x04);
while (!kbhit())
{
printf("Channel 0 =
%x,% x\n",inportb(0x01),inportb(0x01));
printf("Channel 1 =
%x,% x\n",inportb(0x03),inportb(0x03));
printf("Status = % x\n",inportb(0x08));
}
puts(st1);
}
File Systems
File System
•Disk Architecture
•Disk Partitioning
•File systems
Reading Contents
Windows History
Keeping the demand of graphical user interface, Microsoft developed its first version Windows
3.1. In this version, DOS Kernel and FAT based file systems were used.
After that in the 1990s, certain new versions of Windows named Windows 95, 97 and 98 were
introduced supporting the 32-bit architecture of Intel’s processors.
Later on Windows NT versions were introduced supporting a file system based on new
technology called NTFS. Its security and file system was better than the previous versions.
Windows Server 2008 OS was developed for professional use to manage enterprise and server
applications. Support for multi-core technology and 64-bit applications was provided in this OS.
Other Windows versions supporting 32-bit, 64-bit architecture, multi-core and multiprocessing
were also introduced including Windows XP, Windows Vista, Windows 7, 8 and Windows 10.
Due to its dominance role, certain applications and software development tools are available in
the market that can easily integrate with Windows OS and can develop windows applications
ranging from small scale to enterprise level.
One of the key features of Windows OS is its rich GUI that makes its use very convenient. This
interface can be easily customized according to the local setup. The size, color and visibility of
graphical interface objects can also be changed by the user.
Compared to other operating systems, certain modern features exist in Windows due to which
most of the developers develop their applications for Windows targeting the huge market of
Windows.
Open Source Software is a software that is publically available with its source code to use,
modify and distribute with original rights. It is developed by the community rather than a single
company or vendor. In contrast, proprietary software is copyrighted and only available to use
under a license.
· As Windows components are provided and updated only by a single vendor, its
implementation remains uniform throughout the world. Further, extensions in Window
components or APIs are only vendor-specific and so no non-standard extension is possible
except for platform differences.
Windows also support various types of hardware platforms like open systems.
● In Windows OS, all the system resources including processes, threads, memory, pipes,
DLL etc. are represented by objects which are identified and referenced by a handle.
These objects cannot be directly accessed. In case, if any application approaches to
access these objects directly, Windows throws an appropriate exception. The only way
to access and operate on these objects is a set of APIs provided by Windows. Several
APIs can be related to a single object to manipulate it differently.
● A long list of parameters is associated with each API where each parameter has its own
significance but only few parameters are specified for a specific operation.
● To perform the task of multitasking and multi-threading efficiently, Windows provides a
number of synchronization constructs to arbitrate among the resources.
● The names of Windows APIs are long and descriptive for its proper and convenient use.
● Some pre-defined data types required for Windows APIs are:
■ BOOL (for storing a single logical value)
■ HANDLE (a handle for object)
■ LPTSTR (a string pointer)
■ DWORD (32-bit unsigned integer)
● Windows Data types avoid the pointer operator (*).
● Some lowercase prefix letters with variable names are used to identify the type of
variable. This notation is called Hungarian notation. For example, in the variable name
lpszFilename, ‘lpsz’ is Hungarian notation representing a long pointer to zero
terminated string.
● windows.h is a header file including all the APIs prototypes and data types
Topic 6: 32-Bit and 64-Bit Source Code Portability
Windows keeps two versions of each API, one for 32-bit and other for 64-bit. A 32-bit code can
be run on 64-bit hardware but will be unable to exploit some features of 64-bit like accessing
large disk space or using large pointer or 64-bit operation.
Latest versions of Windows support both 32 and 64-bit architectures by keeping two versions of
each API, one for 32-bit and other for 64-bit.
Interoperability of 32 and 64-bit: A single source code can be built for 32-bit as well as 64-bit
versions. To decide whether executable code of 32 or 64-bit is generated by the compiler at
runtime, it depends on its settings or configuration. Further, to decide which version of API is
used, it is also based on the compiler’s configuration.
A 32-bit code can run on 64-bit hardware successfully but will be unable to use some features
of 64-bit like large disk space, large pointer etc.
A source code developed for 64-bit architecture cannot easily run on a 32-bit machine. For this
purpose, re-compilation of the program is required and suitable configuration is made in the
compiler to generate a 32-bit executable code.
Windows provides a set of built-in APIs to perform I/O operations. A related API with specific
parameters is invoked for the concerned resource and I/O operation is performed.
Similarly, certain C/C++ standard functions are available to perform I/O operations. For example,
fopen(), fclose(), fread(), fwrite() etc. are C functions that can be used to perform I/O
operations related to files.
Standard C functions can be used inside the source code to run on Windows platform because
Windows has system calls at low level to support C/C++ functions for I/O operations.
In case, if portability is not focused and required to avail the advanced Windows features, then
it is preferred to use the Windows APIs.
if(argc!=3) {
printf(“Usage: cp file1 file2\n”);
return 1; }
inFile=fopen(argv[1], “rb”);
if(inFile==NULL) {
perror(argv[1]);
return 2;
}
outFile=fopen(argv[2], “wb”);
if(outFile==NULL) {
perror(argv[2]);
return 3; }
This program is used to copy one file to another using C standard functions. In this program, a
buffer of size 256 bytes is used in which the chunks of file are copied one by one.
The source file is opened in read binary mode and the destination file in write binary mode
using the C fopen() function.
If both are successfully opened, then a file is read inside a loop chunk by chunk using fread()
function and written onto the destination file using fwrite() function. After a few iterations, the
file will be written to the destination file and both files are closed.
if(argc !=3) {
fprintf(stderr, “Usage: cp file1 file2\n”);
return 1; }
lpwszFile1 = (LPTSTR)malloc(510);
lpwszFile2 = (LPTSTR)malloc(510);
iLen1 = MultiByteToWideChar(CP_ACP, 0, argv[1], -1, lpwszFile1, 510);
iLen2 = MultiByteToWideChar(CP_ACP, 0, argv[2], -1, lpwszFile2, 510);
hIn=CreateFile(lpwszFile1, GENERIC_READ, FILE_SHARE_READ, NULL,
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (hIn==INVALID_HANDLE_VALUE) {
fprintf(stderr, “Cannot open input file. Error: %x\n”, GetLastError());
return 2; }
Numerous Windows functions are used to perform various tasks at low level. However,
Windows has a set of Convenience functions that combine several functions to perform a
common task. In most cases, these functions improve the performance because several tasks
are performed by a single function.
For example, CopyFile() is a convenience function that replaces the algorithms used for creating,
opening, reading and writing one file to another.
Program 1 - 3
#include<stdio.h>
#include<windows.h>
#define BUF_SIZE 256
LPWSTR lpwszFile1, lpwszFile2;
INT iLen1, iLen2;
CreateFile() API with a list of parameters is used to open or create a new file. Its return type is
HANDLE to an open file object in case of successful opening or creation. The parameters are:
dwDesiredAccess: It is a 32-bit double word which specifies the GENERIC_READ and WRITE
access.
Syntax:
● If the file is not opened in concurrent mode, then ReadFile() starts reading from the
current position.
● If the current location is End of File, then no Errors occur and *lpNumberOfBytesRead is
set to zero
● The function returns FALSE if it fails in case any of the parameter is invalid
Parameters
Syntax:
To write through the current size of file, the file must be opened with
FILE_FLAG_WRITE_THROUGH option
Lecture 15: Closing a File
After opening & using a file, it is required to close and invalidate the file handles in order to
release the system resources.
The CloseFile() API is used to close a file. A file handle is passed as parameter to this API as a
result of which the API will return True or False value. If the operation is successful, then it
returns True value. In case if the handle is already invalid, then it will return False value.
While writing a new code or enhancing an existing one, a programmer can adapt any of the
following strategies based on requirements.
● Enviornment.h
● Everything.h
#if(WIN32_WINNT>=0x600)
#else
#endif
#endif
#ifdef UNICODE
#define_UNICODE
#endif
#ifndef UNICODE
#undef_UNICODE
#endif
Everything.h includes all the header file that will be typically required for all the
subsequent window programs.
#include “ENVIORNMENT.h
#include<stdlib.h>
#include “support.h”
#include _MT
#endif
#include “Everything.h”
_ftprint(stderr,_t(“%s\n”},userMessage};
If (printErrorMessage)
eMsgLen= FormatMessage{FORMAT_MESSAGE_ALLOCATE_BUFFER|
FORMATE_MESSAGE_FROM_SYSTEM,
NULL,errNUM,MAKELANGID{LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPSTR)&lpsSysMSg,0,NULL);
If(eMsgLen>0)
_ftprint(stder,T(“%s\n”|,lpvSysMsg));
Else
_ftprint{stderr,_T{“LastErrorNumber,%d\n”},errNum};
If (lpvSysMsg!=NULL) LOCALFree(lpvSysMsg);
If(exitCode>0)
ExitProcess(exitCode);
return;
}
Topic 21:- Standard IO devices:
Reading Material:
● Input
● Output
● Error
1. STD_INPUT_HANDLE
2. STD_OUPUT_HANDLE
3. STD_ERROR_HANDLE
Operating system have also the concept of redirection using the given API
It also return true if calls succeed and return false in case of fail.
Topic 22: Copying multiple files using windows API
Reading Content:
We will see in this module how to display files using cosonle APIs of windows,
in other words display file on screen is actually copying file on console. For this
we made utility function “options()”. We will also use this function further. This
function take a variable list of parameters and use to parse these variable list.
Basically we specify the list of parameters of a program on command prompt,
there are number of options in it. Option () is use to parse these options. It
identify the “-“ prefix and check all the possible options, and set the flag
against the set options.
#include “Everything.h”
#include <stdarg.h>
DWORD Options (int argc, LPCTSTR argv [], LPCTSTR OptStr, …) /*… show the
parameters list are variables */
Va_list pFlagList;
LPBOOL pFlag;
*pFlag= False;
For (iArg= 1; !(*(pFlag) && iArg <argc &&argv[iARG] [0]== _T(‘-‘); iArg++)
*pFlag = _memtchr (argv [iArg], OptStr [iFlag], _tcslen (argv [iArg]))!=
NULL
iFlag++;
Va_end (pFlagList);
For (iArg= 1; !(*(pFlag) && iArg <argc &&argv[iARG] [0]== _T(‘-‘); iArg++);
Retrun iArg;
CatFile Function:
Return;
}
Topic 23 : Encrypting files
Reading Content:
Encryption is a very old technique, and roman empire use to encrypt secret
conversation in war days and they use Ceasar Cipher algorithm to encrypt. In
this method an alphabet is substituted by another alphabet placed n positions
forward in circular manner. The text that is changed using encryption method is
called Cipher text.
The text that we are going to encrypt is called plain text so it is denoted by P
and after encrypt we present it with C.
● C = (P + n) mod 256
This technique is not exactly cipher but little bit similar to cipher. Following is
the code of encrypting file
#include "Everything.h"
#include <io.h>
BOOL cci_f (LPCTSTR, LPCTSTR, DWORD);
if (argc != 4)
return 0;
if (hOut == INVALID_HANDLE_VALUE) {
CloseHandle(hIn);
return FALSE;
}
while (writeOK && ReadFile (hIn, buffer, BUF_SIZE, &nIn, NULL) && nIn > 0) {
CloseHandle (hIn);
CloseHandle (hOut);
return writeOK;
Reading Content:
We will see in this module the types of API for file management. Windows
provides lots of function for file and directory management. These functions
are pretty straightforward and easy to use.
• Delete
• Copy
• Rename
Delete
Delete function will help to delete the file on a given path. For deleting file
the following API is used.
Returns TRUE if the file at the given valid file path is deleted
Copy
Hard Copy
Move
DWORD dwFlags );
We will discuss the functions which we can use for directory management. We
will do different directory operation like create directory , remove directory and
move directory.
LPSECURITY_ATTRIBUTES lpSecurityAttributes
);
BOOL RemoveDirectory(
LPCSTR lpPathName
);
BOOL SetCurrentDirectory(
LPCTSTR lpPathName
);
DWORD GetCurrentDirectory(
DWORD nBufferLength,
LPTSTR lpBuffer
);
In the previous module we see the certain APIs , which perform input/output
operations on console, now we use these APIs. We create two types of utility
functions, one is help us to display string on console and other is pass some
message to user and also take input from users. Following are names and
description of these functions.
#include "Everything.h"
#include <stdarg.h>
LPCTSTR pMsg;
va_end (pMsgList);
return FALSE;
va_end (pMsgList);
return TRUE;
BOOL success;
if (success)
else
CloseHandle (hIn);
CloseHandle (hOut);
return success;
Topic 28:
In this module we will see a small code which will use get current directory.
#include "Everything.h"
DWORD lenCurDir;
return 0;
Topic 29:
If we see historically, there were some file system which was of 12-bit after that
we have 32-bit system and still somewhere 32-bit file system are used. FAT
based system allowed a maximum file size of 232 bytes which is 4GB. NTFS
theoretically provides the file size limit of 264 which is very huge.
Files of such proportion are called huge files. Although for most of the
application 32 bit file space is sufficient. However due to rapid technological
changes leading to increased disk spaces its useful to know how to deal with 64
bit huge file spaces and windows facilitate with some API’s that support 64-bit
file system.
Topic 30:
Whenever a file is opened using CreateFile() the file pointer is placed at the start
of file. The file pointer changes as ReadFile() or WriteFile() operations are
performed. Every subsequent read/write operation is performed at the current
file pointer position.
SetFilePointer()
DWORD SetFilePointer(
HANDLE hFile,
DWORD dwMoveMethod
);
hFile
lDistanceToMove
The low order 32-bits of a signed value that specifies the number of bytes to
move the file pointer.
lpDistanceToMoveHigh
A pointer to the high order 32-bits of the signed 64-bit distance to move.
dwMoveMethod
FILE_BEGIN // file pointer move number of bytes w.r.t the start of file
Topic 31:
For large files that may have size 264 , we need to understand the 64 bit
arithmetic. To facilitate 64-bit integer arithmetic windows provide a union
LARGE_INTEGER. This union has structure for dealing with lower and higher
double words Moreover it also has a field to deal with whole quadword of type
LONGLONG.
struct {
DWORD LowPart;
LONG HighPart;
};
struct {
DWORD LowPart;
LONG HighPart;
} u;
LONGLONG QuadPart;
} LARGE_INTEGER;
Extension of SetFilePointerEx
BOOL SetFilePointerEx(
HANDLE hFile,
LARGE_INTEGER liDistanceToMove,
PLARGE_INTEGER lpNewFilePointer,
DWORD dwMoveMethod
);
hFile
A handle to the file. The file handle must have been created with the
GENERIC_READ or GENERIC_WRITE access right
liDistanceToMove
lpNewFilePointer
A pointer to a variable to receive the new file pointer.
dwMoveMethod
FILE_BEGIN
FILE_CURRENT
FILE_END
Topic 32:
union {
struct {
DWORD Offset;
DWORD OffsetHigh;
} DUMMYSTRUCTNAME;
PVOID Pointer;
} DUMMYUNIONNAME;
HANDLE hEvent;
} OVERLAPPED, *LPOVERLAPPED;
Implementation:
…..
Topic 33:
One method of getting file size is already exist and that is to open a file first
using create file, once file is open the file pointer is pointing to the first byte
then we move file pointer to the end of file (eof). So file pointer is move from
starting to end of file is give use the size of the file. Windows also provides an
API to get file size GetFileSizeEx()
GetFileSizeEx()
BOOL GetFileSizeEx(
HANDLE hFile,
PLARGE_INTEGER lpFileSize
);
hFile
A handle to the file. The handle must have been created with the
FILE_READ_ATTRIBUTES access right
lpFileSize
Windows also give option to set the size. The file size can also be changed,
reducing the file size truncate data. Increasing the file size can be useful where
the size of file is expected to grow. We use SetEndOfFileEx() to change the file
size.
Topic 34:
In this topic we discuss the example of creates a file with a capacity of specified
records. The file has a header followed by equal size records. The feature of
this example is, user can modify any record randomly and get the total count of
records in the file.
#include "Everything.h"
SYSTEMTIME recordCreationTime;
SYSTEMTIME recordLastRefernceTime;
SYSTEMTIME recordUpdateTime;
TCHAR dataString[STRING_SIZE];
} RECORD;
DWORD numRecords;
DWORD numNonEmptyRecords;
} HEADER;
HANDLE hFile;
LARGE_INTEGER currentPtr;
RECORD record;
TCHAR string[STRING_SIZE], command, extra;
SYSTEMTIME currentTime;
if (argc < 2)
if (hFile == INVALID_HANDLE_VALUE)
header.numRecords = _ttoi(argv[2]);
currentPtr.QuadPart = (LONGLONG)sizeof(RECORD) *
_ttoi(argv[2]) + sizeof(HEADER);
if (!SetEndOfFile(hFile))
return 0;
while (TRUE) {
continue;
currentPtr.QuadPart = (LONGLONG)recNo *
sizeof(RECORD) + sizeof(HEADER);
ov.Offset = currentPtr.LowPart;
ov.OffsetHigh = currentPtr.HighPart;
record.recordLastRefernceTime = currentTime;
if (record.referenceCount == 0) {
if (prompt) _tprintf (_T("record
Number %d is empty.\n"), recNo);
continue;
} else {
recNo, record.referenceCount);
record.referenceCount = 0;
header.numNonEmptyRecords--;
headerChange = TRUE;
recordChange = TRUE;
} else if (command == _T('w')) { /* Write the record, even if for the first time */
if (record.referenceCount == 0) {
record.recordCreationTime =
currentTime;
header.numNonEmptyRecords++;
headerChange = TRUE;
record.recordUpdateTime = currentTime;
record.referenceCount++;
recordChange = TRUE;
} else {
if (headerChange) {
argv[1], header.numNonEmptyRecords,
header.numRecords);
CloseHandle (hFile);
return 0;
}
Topic 35:
Windows provide a certain set of APIs for search files/folders within the hierarchical
structure of Directories/folders. These APIs include:
FindFirstFile() API
Where lpFileName represents the directory or path, and the filename. The name can
include wildcard characters, for example, an asteristk (*) or a question mark (?).
DWORD dwFileAttributes;
FILETIME ftCreationTime;
FILETIME ftLastAccessTime;
FILETIME ftLastWriteTime;
DWORD nFileSizeHigh;
DWORD nFileSizeLow;
DWORD dwReserved0;
DWORD dwReserved1;
CHAR cFileName[Max_Path];
CHAR cAlternateFileName[14];
DWORD dwFileType;
DWORD dwCreatorType;
DWORD WFinderFlags;
};
FindNextFile() API:
Where hFindFile represents the search handle returned by a previous call to the
FindFirstFile or FindFirstFileEx function &
FindClose() API
Topic 36:
Certain other APIs are also used for getting the file attributes but these API need to
have an open file handle rather than scan a directory or use a filename.
GetFileTime() API
lpCreationTime is a pointer to a FILETIME structure to receive the data and time the file
or directory was created.
lpLastAccessTime is a pointer to a FILETIME structure to receive the data and time the
file or directory was last accessed.
lpLastWriteTime is a pointer to a FILETIME structure to receive the data and time the
file or directory was last written to truncated or overwritten.
FileTimeToSystemTime() API
SystemTimeToFileTime() API
CompareFileTime() API
It compares file times of two files. It returns -1 if less, 0 if equal and +1 if greater.
SetFileTime() API
It sets the three time of file. NULL used if the file time is not to be changed.
GetFileType API
GetFileAttributes() API
DWORD GetFileAttributes(LPCTSTR lpFileName);
Where lpFileName is the name of a file or directory. Its return value is:
Topic 37:
Windows provide the facility of creating temporary files for storing the intermediate
results. These files are assigned unique names in a directory with extension .tmp.
Certain APIs are used for creating temporary files. These include:
GetTempFileName API
Where lpPathName represents the directory path for the filename. The string cannot be
longer than 14 characters.
Topic 38:
We can get the attributes of a file, listing of files and can traverse the directory
structure using certain windows APIs.
An application called lsW is used for showing files and listing their attributes. It uses
two option switched that is –l and –R where –l option is used to list the attributes of
files in a folder and –R is used for recursive traversal through subfolders.
This application or program will work with a relative pathname; it will not work with
absolute pathname.
#include<everything.h>
DWORD FileType(LPWIN32_FIND_DATA);
int i, fileIndex;
DWORD pathLength;
/* parse the search pattern into two parts: the parent and the filename or wild card
expression. The filename is the longest suffix not containing a slash. The parent is the
remaining prefix with a slash. This is performed for all command line search pattern. If
no file is specified, use * as the search pattern */
UNIX Touch command changes file access and changes the time to
current system time.
SetFileTime() Sets the date and time that the specified file or directory
was created, last accessed, or last modified.
BOOL LockFileEx(
HANDLE hFile,
DWORD dwFlags,
DWORD dwReserved,
DWORD nNumberOfBytesToLockLow,
DWORD nNumberOfBytesToLockHigh,
LPPVERLAPPED lpOverlapped
)
If a program does not release a lock or holds the lock longer, other
programs will not be able to proceed and their performance will be
negatively impacted.
The registry contains two basic elements: keys and values. Registry
keys are container objects similar to folders. Registry values are non-
container objects similar to files. Keys may contain values and sub-
keys. Keys are referenced with a syntax similar to Windows' path
names, using backslashes to indicate levels of hierarchy. Keys must
have a case insensitive name without backslashes.
The hierarchy of registry keys can only be accessed from a known root
key handle (which is anonymous but whose effective value is a
constant numeric handle) that is mapped to the content of a registry
key pre-loaded by the kernel from a stored "hive", or to the content of
a sub-key within another root key, or mapped to a registered service
or DLL that provides access to its contained sub-keys and values.
HKEY_LOCAL_MACHINE or HKLM
HKEY_CURRENT_CONFIG or HKCC
HKEY_CLASSES_ROOT or HKCR
HKEY_CURRENT_USER or HKCU
HKEY_USERS or HKU
HKEY_PERFORMANCE_DATA (only in Windows NT, but invisible in
the Windows Registry Editor)[5]
HKEY_DYN_DATA (only in Windows 9x, and visible in the Windows
Registry Editor)
Service Manager stores many settings in the registry. You seldom have
to edit the registry yourself, because most of those settings are
derived from entries that you make in day-to-day use. However, some
changes to settings might occasionally be required. Service Manager
stores most registry values in the following locations:
HKEY_CURRENT_USER\Software\Microsoft\System
Center<version>\Service Manager\Console
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\System
Center<version>
Topic 47: Listing Registry Keys
You can show all items directly within a registry key by using Get-
ChildItem. Add the optional Force parameter to display hidden or
system items. For example, this command displays the items directly
within PowerShell drive HKCU:, which corresponds to the
HKEY_CURRENT_USER registry hive:
PowerShell
Get-ChildItem -Path HKCU:\ | Select-Object Name
You can also specify this registry path by specifying the registry
provider's name, followed by ::. The registry provider's full name is
Microsoft.PowerShell.Core\Registry, but this can be shortened to just
Registry. Any of the following commands will list the contents directly
under HKCU:.
PowerShell
Get-ChildItem -Path Registry::HKEY_CURRENT_USERGet-ChildItem -
Path Microsoft.PowerShell.Core\Registry::HKEY_CURRENT_USERGet-
ChildItem -Path Registry::HKCUGet-ChildItem -Path
Microsoft.PowerShell.Core\Registry::HKCUGet-ChildItem HKCU:
It's a good idea to use a function call in the filter expression whenever
filter needs to do anything complex. Evaluating the expression causes
execution of the function, in this case, Eval_Exception.
DWORD GetExceptionCode(VOID);
__except(GetExceptionCode())
{ --- }
EXCEPTION_ARRAY_BOUNDS_EXCEEDED:
The thread attempts to access an array element that is out of bounds
EXCEPTION_DATATYPE_MISALIGNMENT:
The thread attempts to read or write data that is misaligned on hardware that does
not provide alignment. For example, 16-bit values must be aligned on 2-byte
boundaries, 32-bit values on 4-byte boundaries, and so on.
EXCEPTION_FLT_DIVIDE_BY_ZERO:
The thread attempts to divide a floating point value by a floating point divisor of 0
(zero).
EXCEPTION_FLT_INEXACT_RESULT:
The result of a floating point operation cannot be represented exactly as a decimal
fraction.
Topic 52: Exceptions Handling Sequence
try:
You do your operations here;
......................
except ExceptionI:
If there is ExceptionI, then execute this block.
except ExceptionII:
If there is ExceptionII, then execute this block.
......................
else:
If there is no exception then execute this block.
IEEE defines a standard for floating-point exceptions it is called IEEE Standard for Binary
Floating-Point Arithmetic (IEEE 754). This standard have defined five types of floating-point
exception:
Invalid operation
Division by zero
Overflow
Underflow
Inexact calculation
Errors Exception
Errors are usually raised by the environment in Exceptions are caused by the code of the
which the application is running. app the code belongs to.
The use of try-catch blocks can handle
It is not possible to recover from an error. exceptions and recover the system from
exception.
Errors occur at run-time and are unknown by the Exceptions may or may not be caught by
compiler. the compiler.
Programmers include an explicit test to check for An exception could occur nearly
error,for example whether a file read/write operation anywhere, and it is practical to test for
has failed. an exception.
Topic 55: Treating Errors as Exceptions
Programmer can use ReportError function to report the error and let windows treat it and
terminate the process.But it have its own limitations.
• A fatal error terminates the entire process when only a single thread should terminate.
• The programmer may require to continue program execution rather than terminate the process.
• Synchronization resources, such as events or semaphores, will not be released in most of the
circumstances.
Termination handlers are declared in language-specific syntax. Using the Microsoft C/C++
Optimizing Compiler, they are implemented using __try and __finally.
The guarded body of code can be a block of code, a set of nested blocks, or an entire procedure
or function.
The termination block is executed when the flow of control leaves the guarded body, regardless
of whether the guarded body terminated normally or abnormally.
Termination and exception handlers allow you to make your program more robust by both
simplifying recovery from errors and exceptions and helping to ensure that resources and file
locks are freed at critical junctures.
Consider the below given code where we are checking for invalid handle and
ReportingException.
If (hin == INVALID_HANDLE_VALUE)
ReportException(argv[iFile],1);
If(!GetFileSizeEx(hIn, &fsize) || fsize.HighPart > 0)
ReportException(_T(“FIle is Too Large”,1));
The filter function identifies the exception type and based on the type of the exception, the
handler can treat each exception differently. In the following program, the exception handling
and termination of a program are illustrated using a filter function.
The program generates an exception based on the type of the exception entered by the user. The
floating point exceptions are enabled with the help of controlfp function and old status is saved
in the fpOld. The try block mentions the different cases of exception generation with the help of
a switch statement.
Now we will see how the values in the ecategory reference variable are placed.
User generated exceptions are identified based on the masking operation generating zero as a
result.
Console control handlers are quite similar to the mechanism of exception handlers. Normal
exceptions respond to several asynchronous events like division by zero, invalid page fault etc.,
but they do not respond to console related events like Ctrl+C. Console control handlers can
detect and handle the events that are console related. The API SetConsoleCtrlHandler() is used to
add console handlers.
The API takes the address of the HandlerRoutine and Add Boolean as parameters. There can be a
number of handler routines if the Add parameter is set as TRUE. If the HandlerRoutine
parameter is set as NULL and Add is TRUE, then the Ctrl-C signal will be ignored.
The handler routine will be invoked if a console exception is detected. Handler routine runs in an
independent thread within the process. Raising an exception within the handler routine will not
interfere with the working of the original routine that created the handler routine. Signals apply
to the whole process, while exception applies to a single thread.
Usually signal handlers are used to perform cleanup tasks whenever a shutdown, close or logoff
events are detected. Signal Handler would return a TRUE value in case it takes care of the task
or it may return FALSE. In case of FALSE, the next handler in the chain is invoked. Signal
handler chain is invoked in the reverse order of which they are set up in and the system signal
handler is the last one in this chain.
We have a simple program that set up a console control handler and starts beeping in a
loop. The control handler is invoked whenever a console event occurs. The handler
handles the event likewise and clears an exitFlag to end the loop of the main function.
/* Chapter 4. CNTRLC.C */
/* Catch Cntrl-C signals. */
#include "Everything.h"
static BOOL WINAPI Handler(DWORD cntrlEvent);
static BOOL exitFlag = FALSE;
int _tmain(int argc, LPTSTR argv[])
while (!exitFlag) { /* This flag is detected right after a beep, before a handler exits */
Sleep(4750); /* Beep every 5 seconds; allowing 250 ms of beep time. */
Beep(1000 /* Frequency */, 250 /* Duration */);
}
}
_tprintf(_T("Stopping the main program as requested.\n"));
return 0;
}
BOOL WINAPI Handler(DWORD cntrlEvent)
{
switch (cntrlEvent) {
/* The signal timing will determine if you see the second handler message */
case CTRL_C_EVENT:
_tprintf(_T("Ctrl-C received by handler. Leaving in 5 seconds or
less.\n"));
exitFlag = TRUE;
Sleep(4000); /* Decrease this time to get a different effect */
_tprintf(_T("Leaving handler in 1 second or less.\n"));
return TRUE; /* TRUE indicates that the signal was handled. */
case CTRL_CLOSE_EVENT:
_tprintf(_T("Close event received by handler. Leaving the handler in 5
seconds or less.\n"));
exitFlag = TRUE;
Sleep(4000); /* Decrease this time to get a different effect */
_tprintf(_T("Leaving handler in 1 second or less.\n"));
return TRUE; /* Try returning FALSE. Any difference? */
default:
_tprintf(_T("Event: %d received by handler. Leaving in 5 seconds or
less.\n"), cntrlEvent);
exitFlag = TRUE;
Sleep(4000); /* Decrease this time to get a different effect */
_tprintf(_T("Leaving handler in 1 seconds or less.\n"));
return TRUE; /* TRUE indicates that the signal was handled. */
}
}
The program can be terminated by the user either by closing the console or with a Ctrl-C. The
handler will register with windows using the SetConsoleCtrlHandler(Handler, TRUE) function.
The handler will be activated upon the occurrence of any console event. If the registration of any
handler fails due to any reason, then an error message will be printed.
No __try and __catch keywords are required with VEH and they are like console control
handlers. Windows provides a set of APIs for VEH management as follows.
The given API has two parameters; FirstHandler is the parameter used to specify the order in
which the handler executes. Non-zero value indicates that it will be the first one to execute and
zero specifies it to be the last. If there are more than one handlers setup with zero value, then
they will be invoked in the order they are added using AddVectoredExceptionHandler(). Return
value is NULL in case of failure, otherwise it returns the Handle to the Vectored Exception
Handler.
The exception handler function should be fast and must return as quickly as possible, therefore it
should not have a lot of code. The VEH should neither perform any blocking operation like the
Sleep() function nor use any synchronization objects. Typically a VEH would access exception
information structure, do some minimal processing, and set a few flags.
Dynamic Memory
Need of dynamic memory arises whenever dynamic data structures like search tables, trees,
linked lists etc. are used. Windows provides a set of APIs for handling dynamic memory
allocation.
Windows also provides memory mapped files which allows direct movement of data to and from
user space and files without the use of file APIs. Memory Mapped files can help conveniently
handle dynamic data structure and make file handling faster because they are treated just like
memory. It also provides a mechanism for memory sharing among processes.
Windows essentially uses two API platforms i.e. Win32 and Win64.
The Win32 API uses pointers of size 32 bits, hence the virtual space is 2^32. All data types have
been optimized for 32 bit boundaries. Win64 uses a virtual space of 2^64 (16 Exabytes).
A good strategy is to design an application in such a way that it could run in both modes without
any change in code.
Win32 makes at least half of the virtual space (8GB) accessible to a process and the rest of the
space is reserved by the system for shared data, code, and drivers etc. Overall Windows provides
a large memory space available to user programs and hence requires optimal management.
Dynamic Memory
Need of dynamic memory arises whenever dynamic data structures like search tables, trees,
linked lists etc. are used. Windows provides a set of APIs for handling dynamic memory
allocation.
Windows also provides memory mapped files which allows direct movement of data to and from
user space and files without the use of file APIs. Memory Mapped files can help conveniently
handle dynamic data structure and make file handling faster because they are treated just like
memory. It also provides a mechanism for memory sharing among processes.
Windows essentially uses two API platforms i.e. Win32 and Win64.
The Win32 API uses pointers of size 32 bits, hence the virtual space is 2^32. All data types have
been optimized for 32 bit boundaries. Win64 uses a virtual space of 2^64 (16 Exabytes).
A good strategy is to design an application in such a way that it could run in both modes without
any change in code.
Win32 makes at least half of the virtual space (2 GB) accessible to a process and the rest of the
space is reserved by the system for shared data, code, and drivers etc. Overall Windows provides
a large memory space available to user programs and hence requires optimal management.
Further information about the parameters of Windows Memory Management can be probed
using the following API.
The API returns a pointer to SYSTEM_INFO structure. The structure contains various
information regarding the system like page size, granularity, and application’s physical memory
address space.
A programmer allocates memory dynamically from a heap. Windows maintains a pool of heaps
and a process can have many heaps. Traditionally, one heap is considered enough. But several
heaps may be required to make a program more efficient.
In case a single heap is sufficient, then a runtime library function for heap allocation like
malloc(), free(), calloc(), realloc() might be enough.
Heap is a windows object and hence is accessed by a handle. Whenever you require allocating
memory from heap, you need a heap handle. Every process in windows has a default heap which
can be accessed through the following API.
HANDLE GetProcessHeap(VOID)
The API returns a handle to the process heap. NULL is returned in case of failure and not
INVALID_HANDLE_VALUE.
However, due to a number of reasons it would be desirable to have more than one heap.
Sometimes it is convenient to have distinct heaps for different data structures.
Separate Heaps
1. If a distinct heap is assigned to each thread, then each thread will only be able to use the
memory allocated to each thread.
3. Fragmentation is reduced when one fixed size data structure is allocated from a single heap.
4. Allocating a single heap among each thread simplifies synchronization.
5. If a single heap contains complex data structures, then they can be easily de-allocated with
a single API call by de-allocating the entire heap. We will not need complex de-allocation
algorithms in such cases.
6. Small heaps for a single data structure reduces the chances of page faults as per the
principle of locality.
We can create a new heap using HeapCreate() API and its size can be set to zero. The API
adjusts the heap size to the nearest multiple of page size. Memory is committed to the heap
initially, rather than on demand. In case the memory requirements increase than the initial, more
pages will automatically be allocated to the heap up to maximum size allowed.
If the required memory is not known, then deferring memory commitment is a good practice as
heap is a limited resource. Following is the syntax of the API used to create new heaps.
dwMaximumSize if non-zero, determines the maximum limit of the heap memory set by the
user. Heap is not grow-able beyond this point. In case it’s zero, then the heap is grow-able to the
extent of the virtual memory space available for the heap.
dwInitialSize is the initial size of the heap set by the programmer. SIZE_T is used to enable
portability. Based on the win32 or win64 platforms, SIZE_T will be 32 or 64 bit wide.
BOOL HeapDestroy(
HANDLE hHeap
);
hHeap is the handle to a previously created heap. Do not use the handle obtained from
GetProcessHeap() because it may raise an exception. This is an easy way to get rid of all the
contents of the heap including complex data structures.
Once a heap is created, it does not allocate memory that is directly available to the program.
Rather, it only creates a logical structure of heap that will be used to allocate new memory
blocks. Memory blocks are allocated using heap memory allocation APIs like HeapAlloc() and
HeapReAlloc().
hHeap is the handle of the heap from which memory is to be allocated. dwFlags are quite similar
to the flags used in HeapCreate().
HEAP_GENERATE_EXCEPTIONS: This flag will raise exceptions in case there is any failure
while allocating memory to heap. Exceptions are not generated by CreateHeap(), rather they may
occur at the time of allocation.
dwBytes is the size of the memory block to be allocated. For non-grow-able heap, its 0x7FFF8
approximately equivalent to 0.5 MB.
The return value of the function is LPVOID. This is the address of the allocated memory block.
Use this pointer in a formal way and there is no need to make any reference to the Heap handle.
If the exception flag is not set, then NULL is returned by HeapAlloc() and the GetLastError()
does not work on HeapAlloc().
BOOL HeapFree(HANDLE hHeap, DWORD dwFlags,
hHeap is the heap handle from which memory is to be allocated. dwFlags should be 0 or set to
HEAP_NO_SERIALIZE. lpMem should be the pointer previously returned by HeapAlloc() or
HeapReAlloc().
Return value of FALSE will indicate a failure. GetLastError() can be used to get the error.
HEAP_ZERO_MEMORY: only the newly allocated memory is set to zero (in case dwBytes is
greater than the previous allocation).
lpMem: specifies the pointer to the block previously allocated to the same heap hHeap.
dwBytes: It refers to the block size to be allocated that can be lesser or greater than the previous
allocation. But the same restriction as HeapAlloc applies i.e. the block size cannot be greater
than 0x7FFF8.
Some programs may require to determine the size of allocated blocks in the Heap. The size of the
allocated block is determined using the API HeapSize() as follows.
SIZE_T HeapSize(
HANDLE hHeap,
DWORD dwFlags,
LPCVOID lpMem
);
The function returns the size of the block or zero in case of failure. The only valid dwFlag is
HEAP_NO_SERIALIZE.
Serialization
Serialization is required when dealing with concurrent threads using some common resource.
Serialization is not required if threads are autonomous and there is no possibility of concurrent
threads disrupting each other.
b. Each thread has its own heap that is insulated from other threads.
Heap Exceptions
Heap exceptions are enabled using the flag HEAP_GENERATE_EXCEPTION. This allows the
program to close open “handles” before a program terminates. There can be two scenarios with
this option:
There are some other functions that can be used while working with heaps. For example,
HeapSetInformation() can be used to enable low fragmentation mode. It can also be used to
allow termination of a thread upon heap’s corruption.
Till now we have used the Memory Management APIs for allocating, reallocating and
deallocating heaps. We can also get the size of a heap through an API.
A typical methodology of dealing with heaps should be to get a heap handle either using
HeapCreate() or GetProcessHeap(). Use the handle obtained from the above to allocate memory
blocks from the heap using HeapAlloc(). If some block needs to be deallocated, use HeapFree().
Before the program is terminated or when the heap is not required, use HeapDestroy() to dispose
of the heap.
It is convenient not to mix up windows heap API and Run Time Library functions. Anything
allocated with C library functions should also be deallocated with C library functions.
The example is formulated using two heaps. The first one will be a node heap, while the other is
a record heap. Node heap will be used to build a tree, while the data heap will be used to store
keys.
AL-JUNAID TECH INSTITUTE
1. Which of the following tasks is not performed by the operating system.
Multitasking
Memory Management
File Management
Hardware repairing
2. Windows operating system allows us to run a huge process in a small
memory space due to
Efficient primary memory management
Flexibility naming scheme for resources
High processing speed of processor
Virtual memory management
3. To provide an interface between the user and computer, a system is required
which is called_______
Application software
Operating system
Customized software
Both application and customized software
4. A process-1 in windows operating system can access the momery space of
process-2 if _______
Process-1 has no privilege to access memory space of other processes
Both processes have same ID
Process-1 loaded in the same space as process-2
Process-1 has privilege to access memory space of other processes.
JUNAID MALIK 1
AL-JUNAID TECH INSTITUTE
Real time
Multitasking
7. API stands for ______.
Application programming interface
Advance programming interface
Application programming integrity
Application programs interoperability.
8. Which operating system was offered by Microsoft that was used prior to
windows
LINUX
UNIX
Solaris
Dos
9. Which of the following theme is not consider while introducing the new
version of windows?
Enhanced API
Scalability
Performance
Increasing cost
10.Which version of windows is used for mobile devices
Windows ME
Windows CE
Windows vista
Windows server
11.In 2021, which of the following desktop operating systems was widely used
in the world market?
Windows
Fedora
Salaris
Linux
12.Using _____ commands can be issued to the system through icons, buttons,
shortcuts, sound etc.
Result- driven interface
JUNAID MALIK 2
AL-JUNAID TECH INSTITUTE
Graphical user interface
Menu-driven interface only
Command only
13.One of the major causes of windows dominance in PC’s market is its
User-friendly GUI
Best security features
Feature of multitasking
Best marketing strategy
14.Which statement is not correct about the windows operating system
It can only be used in desktop system
It supports both 32&64-bit architecture
It supports voice commands
It supports diverse hardware platforms
15.Which statement is incorrect about open source software?
Paid license is required for it use
Changes can be made by the general public
Source code is freely available
It is publicly available
16.Choose the major drawback of a closed source software
Not affordable by the user
Not customizable
Not freely available to download
Neither affordable, customizable, nor freely available for download
17.Example of a closed source software is _______
Linux
Windows OS
Chrome browser
Fedora
18.A uniform extension is software components is possible in ___ software.
Vender specific
Open source
Community source
Both open and closed
JUNAID MALIK 3
AL-JUNAID TECH INSTITUTE
19.A socket on end-point is required only if
Processor tries to write on internal hard disk
Two processes communication over network
A process needs a resource
Process needs to access main memory
20.DWORD data type represents ______
32 bit unsigned integer
32 bit signed integer
16 bit unsigned integer
16 bit signed integer
21.A software or application can access any windows object ______
Directly
Directly and through API as well
Through API only
Not directly nor through API
22.Windows datatype LPTSTR
Long pointer to TSTR
Last pointer to TSTR
Last pointer to string
Long pointer to STR
23.Each windows API has a _____ number of parameters.
Fixed
Two
Variable
Four
24.Which statement is true about a multi- threading process?
A process has one or more threads
A process has only one thread
A thread has only one process
A thread can be created without process
25.Windows supports both the 32 and 64-bit source code by _____
Keeping separate API’s for 32 and 64-bit code
Converting 32-bit into 64-bit code
JUNAID MALIK 4
AL-JUNAID TECH INSTITUTE
Converting 64-bit into 32-bit code
Keeping separate compilers for each hardware
26.Windows operating system keeps _____ version of each API
Two
One
Complied
Interpreted
27.Which statement is incorrect about the 32-bit source code?
It runs on 64-bit hardware and can use its all features
It has its own windows API
It does not support large disk space
It runs on 64-bit hardware
28.Choose the appropriate advantage of C source code that uses C standard
function
Can access advance windows features
Portable source code
Runs on windows platform only
Runs without making system calls to windows API’s.
29.Choose the correct option for a source code that uses only windows API
instead of C library functions.
Source code can only access some features of windows
Source code will not remain portable
Source code cannot be complied
Source code is portable
30.Which statement is true about open () function in C?
It opens the existing file and not exists it creats a new file
It opens the file only writing
It opens the file only reading
It opens the file only existing
31.fopen() function in C returns ____ if the file is not successfully opened
Zero value
Point to a file
NULL value
JUNAID MALIK 5
AL-JUNAID TECH INSTITUTE
Neither NULL nor Zero
32.Open file objects using C library functions are identified by _____
Pointer to a file structure
Buffer
Handle
Both buffer and handle
33. A successfully read using fread() function in C is indicated by a ____ return
value.
Non-negative
Zero
Negative
Boolean
34.What the following C statement represents; FILE *ptr;
Pointer to a file structure
Pointer to a character
Pointer to a integer
Pointer to a binary number
35.Which statement is true about createfile() function
DWORD
BOOL
HANDLE
INT
36.The return type of readfile() and writefile() is
It open the existing file or creating a new file
It is not used for opening a file
It opens or create a file only for generic read
It open or create a file only for generic write
37.LPWSTR stand for
Last pointer to wide string
Long pointer to wind string
Long pointer with string
Last pointer to string
38. The return type of malloc() function in C can be
JUNAID MALIK 6
AL-JUNAID TECH INSTITUTE
Pointer to allocate space or NULL
Linked list
NULL only
A array
39.Which statement is correct about the convenience function?
It does not improve overall performance
It takes considerable time in execution
It performs a small task
A big task is performed a single API
40.UDF stands for
Universal driven format
Universal disk file
Universal driven file
Universal disk format
41.Which option is not related to the NT file system
Compression
Encryption
File size limitation
Fault tolerance
42.Which feature of NTFS related to data security?
Large file name mechanism
Encryption AL-JUNAID TECH INSTITUET
File allocation table
Compression
43.Keeping in view the support for huge file size, which file system is more
favorable?
NTFS
FAT16
FAT32
FAT8
44.NTFS stand for ______
New trend file system
New technology file system
JUNAID MALIK 7
AL-JUNAID TECH INSTITUTE
New trend for system
New technology for system
45.Which special symbol can be used in windows filename?
Pipe
Forward slash
Backward slash
Underscore
46.The path name of a remote resource of server starts with ____ symbol.
Forward slash
Pipe
Double back slash
Black slash
47.In the windows file system, which symbol can be used as a path separator?
Pipe symbol
Back slash only
Both forward and backward
Forward slash only
48.The file extension usually contains _____ characters.
5 to 8
2 to 4
1 to 2
1 to 3
49.In windows file system, the extension and file name is separated by
_________.
|
Dot(.)
\
/ AL-JUNAID TECH INSTITUTE
50.The name of windows API used for opening and creating a new file is
CreateFile()
OpenFile()
CreateopenFile()
ReopenFile()
JUNAID MALIK 8
AL-JUNAID TECH INSTITUTE
51.The return type of create file() function is.
NULL
A handle to an open file or INVALID_HANDLE_VALUE
INVALID_HANDLE_VALUE
Always handle to run open file object
52.In FILE_SHARE_READ mode, the file is shared for ______
Concurrent read and write by multiple process
Concurrent read and write by a single process
Concurrent read by single process
Concurrent read by multiple process
53.In the createfile() function, if the same name file already exists when the
attributes, create, Always is used to
Delete the existing file and create a new file
Delete the existing file
Over write an existing file
Create an existing file
54.In the createFile() function, which statement is true about open-existing
attribute if the file does not exist.
It will create an existing file
It will open some other file insteated of specified file
It will fail to open the new file
It will create a new file
55.The windows API ______ used to read data from a file and store it in a buffer.
Create File()
Copy file()
Read file()
Write file()
56.If the file is not opened in concurrent mode, then ReadFile() API.
ReadFile()API starts reading from the ______
Backup file
Start file
End of file
Current file
JUNAID MALIK 9
AL-JUNAID TECH INSTITUTE
57.If we want to read 1000 bytes from a file with ReadFile() function but there
are actually only 400 bytes in a file then _______
Read operation will fail
400 bytes will be read
1000 bytes will be read
Exception will be thrown
58.The windows API _______ is used to write data from a better and store it in a
file
Create file
Copy file
Read file
Write file
59.The return type of writeFile() function is
BOOL
DWORD
LPDWORD
LPOVERLAPPED
60.It an invalid file handle is passed as a parameter to the closeFile() function,
then it will return _____
1
Empty string
File handle
False value
61.A Unicode word consists of ______ bits
24
32
16
8 AL-JUNAID TECH INSTITUTE
JUNAID MALIK 10
AL-JUNAID TECH INSTITUTE
2
63.The latest version of windows supports _______ standard.
ASCII
Unicode
Scan codes
Both ASCII and Unicode
64.TCHAR is a/ an _______ type variable.
ASCII
Generic
Unicode
Both ASCII and Unicode
65._stprintf() is a/ an ______ c library function.
Both ASCII and Unicode
Generic
Unicode
ASCII
66._tcscmp() is _____ function to compare the string
An ASCII
A Unicode
Not a generic
A generic
67.Which one is the correct definition of generic main() function?
Int-main
Int main
Int main
Int_main
68.All generic data types are include ____ header file.
<tchar.h>
<string.h>
<windows.h>
<char.h>
69.All generic functions are include in _____ header file
<string.h>
JUNAID MALIK 11
AL-JUNAID TECH INSTITUTE
<windows.h>
<char.h>
<tchar.h>
70.TextOutW() is _____ bit API and it supports ____ standard.
32,Generic
32,ASCII
32,Unicode
16,Unicode
71.The standard C library function atio() supports _____
Generic code
Unicode AL-JUNAID TECH INSTITUTE
128-bit character code
8-bit character code
72.To switch between 8-bit character code and standard Unicode ____ functions
and data type are required.
Generic
Non-generic
Unicode
8-bit
73.Developing generic code needs extra effort but provides maximum ____
Productivity
User-friendly look
Chance of errors
Flexibility
74.What is the return value of GetlastError() function?
It returns error code for last error
It return a formatted message for last error
It takes input message from user and returns
It return error message for the last error
75.Which windows API is used to return a system error code?
Geterror()
Format message ()
Get last error()
JUNAID MALIK 12
AL-JUNAID TECH INSTITUTE
Both geterror() and format Message()
76.Which header file includes all the Unicode macros for setting environment of
a program?
<everything.h>
<environment.h>
<tchar.h>
<windows.h>
77.There are _____number of standard I/O devices in a windows system.
Five
Three
Two
Four
78.In a windows system, input ____ and _____ are three standard I/O devices.
Error, correction
Output, display
Display, error
Output, error
79.On execution, HANDLE_GetstHandle(DWORDnst Handle) will return a valid
handle in case of
Passing invalid parameters
Success
Exception AL-JUNAID TECH INSTITUTE
Failure
80.STD_INPUT_HANDLE macro contains a variable, CONIN$,which is a/an
______.
Input variable
Default variable
Environment variable
Console variable
81.STD_OUTPUT_HANDLE contains _____ as an environment variable.
CONIN$
CONOUT$
CONPRNT$
JUNAID MALIK 13
AL-JUNAID TECH INSTITUTE
CONDIS$
82.Option () function takes ______ parameters.
3
4
5
Variable
83.Catfile() function takes ______ parameters.
3
5
4
2
84.______ empire is considered to be pioneers of encryption as they used basic
encryption algorithms to encrypt secret conversation in a war.
Persian
Chines
Roman
Mughal
85.Roman empire use _____ algorithm to encrypt secret conversation.
CTR
Ceaser cipher
Brute force
Cryto graph
86.The text that we are going to encrypt is called ____ test so it is denoted by
Personal, p
Secret, w
Proposed, p
Plain, p AL-JUNAID TECH INSTITUTE
87.We represent that text by the symbol _____ in the encryption formula.
E
B
A
C
88.The formula of ceaser chopper is ______
JUNAID MALIK 14
AL-JUNAID TECH INSTITUTE
C = (E + W)mod26
E = (P +n) mod27
E = (D +n)mod27
C = (P + n) mod26
89.We use MoveFileEx() to ____ the existing file
Copy
Rename
Over write
Delete
90.Which statement is true about hard copy function?
Both the files must not be on same system volume.
Both the files must be in encrypted form
Creates a hard link for copy file
Security attributes will apply on new file name
91.deleteFile() function takes _____ parameter.
4
1
2
3
92.Which of the following API is used for coping a file?
CopyFile(LPCTSTRIPExistingFileName,LPCTSTR IPNewFileName,
bool bfailExists);
Char CopyFile(LPCTSTRIPExistingFileName,LPCTSTR
IPNewFileName, bool bfailExists);
Bool CopyFile(LPCTSTRIPExistingFileName,LPCTSTR
IPNewFileName, bool bfailExists);
String CopyFile(LPCTSTRIPExistingFileName,LPCTSTR
IPNewFileName, bool bfailExists);
93.Correct syntax of MoveFile() function is ______
Bool Move (LIPCTSTR lpNewName, LPCTSTR lpExistingFileName);
Bool Move (LIPCTSTR lpNewName, LPCTSTR lpNewFileName);
Bool MoveFile (bool LIPCTSTR lpNewName, LPCTSTR
lpExistingFileName);
JUNAID MALIK 15
AL-JUNAID TECH INSTITUTE
Bool Move (bool lpNewName, LIPCTSTR LPCTSTR
lpExistingFileName);
94.RemoveDirectory() function takes ______parameter(s)
1
4
3
2
95.Set currentDirectory() function takes ______ parameter(s)
2
1
4
3
96.Return type of GetcurrentDirectory() function is ()
Int
Bool
String
DWORD
97.createDirectory() function takes _____ parameter(s)
4
3
1
2
98.deleteFiles() function takes ______ parameter(s)
1
4
3
2
99.Return type of printMsg() function is ______
DWORD
CHAR
BOOL
WORD
100. Return type of printString() function is ______
JUNAID MALIK 16
AL-JUNAID TECH INSTITUTE
DWORD
CHAR
BOOL
WORD
101. Correct syntax for create console input file is
hln = createFile(_T(“CONOUT$”), GENERIC_READ&NULL,
OPEN_ALWAYS, FILE_ATTRIBURT_NORMALNULL);
hln = createFile(_T(“CONOUT$”), GENERIC_READ,1
GENERIC_WRITE,0&NULL, OPEN_ALWAYS,
FILE_ATTRIBURT_NORMALNULL);
hln = createFile(_T(“CONIN$”), GENERIC_READ,1
GENERIC_WRITE,0&NULL, OPEN_ALWAYS,
FILE_ATTRIBURT_NORMALNULL);
prohln = createFile(_T(“CONIN$”), GENERIC_READ,1
GENERIC_WRITE,0&NULL, OPEN_ALWAYS,
FILE_ATTRIBURT_NORMALNULL);
102. consoleprompt() function takes _____ parameter(s)
2
3
5
4
103. Current syntax of Get currentDirectort() function is _____
lencurDir =GetcurrentDirectory(DIRNAME_LEN,PwdBuffer);
lencurDir =GetcurrentDirectory(DIRNAME_LEN);
lencurDir =GetcurrentDirectory(DIRNAME_LEN);
lencurDir =GetcurrentDirectory(PwdBuffer);
104. Get currentDirectory() function takes _____ parameter(s)
2
3
5
4
105. Return type of prontMsg() function is ______
WORD
JUNAID MALIK 17
AL-JUNAID TECH INSTITUTE
BOOL
CHAR
DWORD
106. Get Directory() function takes _____ parameter(s)
2
3
5
4
107. In NTPS based system ______ is the maximum allowed size for a
single file
2
2
2
2
108. FAT 32 based system ______ is the maximum allowed size for a
single file
2
2
2
2
109. setFilepointer() function takes _____ parameter(s)
2
3
5
4
110. PLONG is a _____
Pointer to a long variable
String
Variable
Pointer to a string
111. Return type of setFilePointerEx() is _____
String
Bool
JUNAID MALIK 18
AL-JUNAID TECH INSTITUTE
Word
DWORD
112. In setfilepointer() function, lpNewFilePointer parameter is placed is
a/an
Handle
PLARGE_INTEGER
DWORD
LARGE_INTEGER
113. In setFilePoiter() function, distance to move parameter is placed in
DWORD
Handle
PLARGE_INTEGER
LARGE_INTEGER
114. There are ______ components of a LARGE integer
2
3
4
5
115. In the Overlapped structure, ULONG_PTR internal is a _____field.
DWORD
Integer
Pointer
Reserved
116. Overlap structure is a structure which is defined in the _____ header
file
Window.h
Stdary.h
Everything.h
Stdio.h
117. In the overlapped structure the data type of ofsetand offsethigh is
DWORD
WORD
INT
JUNAID MALIK 19
AL-JUNAID TECH INSTITUTE
BOOL
118. EOF is short form of _____
Erase of file
End of file AL-JUNAID TECH INSTITUTE
End of folder
Erase of folder
119. Return types of getfilesizeEx() is _____
Bool
Char
Int
DWORD
120. To reduce the filesize we use _____ windows API.
Setfilesize()
Changefilesize()
SetendoffileEx()
setfileEx()
121. File size cn be obtained using the ____ windows API.
GetFileSizwEx()
FileSizeExGet()
GetFileSize()
FileSize()
122. In the RECORD structure, datatype of numRecord is _____
DWORD
BOOL
Double
Int
123. In the RECORD structure, datatype of numNonemptyRecord is _____
DWORD
BOOL
Double
Int
124. What will be next code statement, if the following if statement id
true? If (!setFilePointer Ex(nfilecurrentptr, NULL,FILE_BEGIN))
JUNAID MALIK 20
AL-JUNAID TECH INSTITUTE
RepotError(_T(“RecordAccessError: writeFile header”.)4,TRUE);
RepotError(_T(“RecordAccessError: writeFile header”.)6,TRUE);
RepotError(_T(“RecordAccessError: setpointer”.)4,TRUE);
RepotError(_T(“RecordAccessError: set End of File”.)5,TRUE);
125. What will be next code statement, if the following if statement is true?
If (!readFile(hFile& header, size of(Header),&nXfer,&ovzero))
ReportError (_T(“RecordAccessError:set End of File.”),5,TRUE);
ReportError (_T(“RecordAccessError:set pointer.”),4,TRUE);
ReportError (_T(“RecordAccessError:write File header.”),4,TRUE);
ReportError (_T(“RecordAccessError:readFile header.”),6,TRUE);
JUNAID MALIK 21
AL-JUNAID TECH INSTITUTE
Second ;last
130. Using GetFileTime() API argument(s) is/are provided.
Both creation and last access time
Only last access time
Creation, last access and last write time
Only creation time
131. GetFileAttribute() API need ____ argument(s) to return the attributes
of a file or directory
1
2
3
0
132. compareFileTime() API returns _____ if both the file time are equal
0
2
1
-1
133. Which option is incorrect when the traverseDirectory() API is
required to be use?
It allow non-recutsive traversal
Recursive and non-recursive traversal option is irrelevant
It allows recursive traversal
It allows both non- recursive and recursive traversal
134. Which of the followingis not an argument of the traverse Directory()
API
Option for simple listing or recursive processing
Search pattern
Parent path
File creation time
135. Temporary files are assigned an extension ____ and they are used to
store ____
.temp,final result
.tmpe,intermediate result
JUNAID MALIK 22
AL-JUNAID TECH INSTITUTE
.tmp,intermediate result
.com,intermediate result
136. ______ is not a value argument for setFiletime() function
pModifyTime
NULL
_T(ame)
_P(accesstime)
137. SetFileTime() function takes a total of arguments.
3
5
4
2
138. GetsystemTimeAsFiletime() function receive _____ as an argument.
File array
File pointer
File handle
File objects
139. Which of the following is not a correct argument of options() function
Argc
Argv
_T(amg)
_T(amc)
140. The fseek() C library function uses _____ bit file position
8
16
32
64
141. For file processing windows provides a propriating function
called______
Pseek64()
Fseek()
Fseek64()
Pseek()
JUNAID MALIK 23
AL-JUNAID TECH INSTITUTE
142. In MicrosoftUNIX library, all I/O function are named with _____
prefix.
Semicolon
Dot
Underscore
Colon
143. In lockFileEx() function, the OVERLAPPED data structure contains
______ data members.
3
5
2
4
144. File lock can be _____ or ____
Read-only, write-only
Read-only, write-only
Read-locked, write only
Read-only, read-write
145. The read operation does not conflict with the _____
Existing shared lock
Remove operation
Write operation
Existing exclusive lock
146. Before encountering a/an _____ lock, the read or write operation can
complete its request partially
Exclusive lock
Shared lock
Mutually exclusive lock
Conflicting lock
147. If process-A has a shared lock on a file, and process-B tries to read
without a shared lock then the read attempt will _____
Return exception
Succeed
Return a shared lock
JUNAID MALIK 24
AL-JUNAID TECH INSTITUTE
Fail
148. UNIX system stores information in _____ directory similar to the
registry entry
/etc
/reg
/key
/root
149. Programmers usually access windows build number through _____
Web sockets
Web API
RESI API
Windows API
150. Information about _____ is not present in the registry file.
Power supply
Chipset
Memory
Processor
151. ______information is present in the registry
HKEY_CURRENT_CINFIG.
Display resolution
Process make
Display size
Memory amount
152. The registry HKEY_CURRENT_USER does not contain ____
information.
System fonts
Printers
Environment variable
Application preferences
153. The registry HKEY_LOCAL_MACHNE stores _____ information
about the machine
Physical
Private
JUNAID MALIK 25
AL-JUNAID TECH INSTITUTE
Protected
Logical
154. ______function enumerates subkey names of an open registry key.
RegEnumKey()
RegOpenKey()
RegOpenKeyEx()
RegENUMKeyEx()
155. The RegOpenKeyEx() function opens a named____
Instance
Sub key
Key
List
156. The function RegCreateKeyEx() ha ____ parameters.
8
7
9
6
157. Is Reg() function processes registry keys rather than ____ and ____
Key-value pairs, files
Key-value pairs, properties
Directories, key-value pairs
Directories, files
158. RegSetvalueEx() function is used to set the data of a ____ value.
Final
Fixed
Named
Static
159. The exception could occur within a _____ embedded in the try block.
List
Function
Constructor
Block
JUNAID MALIK 26
AL-JUNAID TECH INSTITUTE
160. If filter_expression returns _____ then windows ignores the exception
handler and searches for an exception handler in the enclosing block.
EXCEPTION_SKIP_EXECUTION
EXCEPTION_CONTINUE_SEARCH
EXCEPTION_CONTINUE_EXECUTION
EXCEPTION_SKIP_SEARCH
161. If the filter-expression was set to continue the execution but it is not
possible to continue, then ______ exception code will be returned.
EXECUTION-NONCONTINUABLE-EXCEPTION
EXECUTION-NONCONTINUABLE-EXECUTION
EXECPTION-NONCONTINUABLE-EXCEPTION
EXECPTION-NONCONTINUABLE-EXCUTION
162. _____ exception code is returned if the process attempts to read or
write a virtual address for which it has no access rights
EXCEPTION-INTEGERS-VOILATION
EXCEPTION-INTEGERS-BREACH
EXCEPTION-ACCESS-VOILATION
EXCEPTION-INTEGERS-BREACH
163. SHE is not supported through_______
Run time support
Windows function
Compiler supported language extensions
Windows registry
164. The filter-expression in the _____ clause is evaluated immediately
after the exception occurs.
-try
-catch
-except
-finaly
165. The value of the ____ determine actions that follow
Filter-except
Filter-expression
Filter-try
JUNAID MALIK 27
AL-JUNAID TECH INSTITUTE
Filter-search
166. ______ function is used to clear the floating-point exception after it is
processed.
_clear()
_clearfp()
_clean()
_cls()
167. Programs can raise their own exception using the____ function
BuildException
RaiseException
Createexception
GenException
168. RaiseException has _____ parameters.
4
2
5
3
169. The exception handler is actually a code portion associated with
_____ block.
-finally
-try
-except
-catch
170. The new value of floating point mask is determined by its value _____
and its two arguments.
Current-value
C-value
Current-mask
Current-val
171. The ______ function terminates the process if the program indicates
that the error is fatal.
Report handle()
Terminate handle()
JUNAID MALIK 28
AL-JUNAID TECH INSTITUTE
Terminate process()
Report error()
172. SIGSEGV error can only be generated bt ____ but not by ____
Windows, Raise
Linux, macos
Windows, linux
Raise windows
173. A single try block must have a single ____ or _____ block
Terminate, Except
Finally, Except
Finally, continue
Terminate, finally
174. ____ function is used within the termination handle to check how the
try block is terminated
Check termination()
Check handle()
Check termination
Abnormal termination
175. ReportException() function have _____ arguments.
3
4
2
5
176. Second arguments of ReportException()function is _____
Exception code
Exception handle
Exception address
Exception name
177. The process or thread can terminate itself using ____ or ___ functions.
Terminate process(), Exist thread()
Terminate process(), Terminate thread()
Exist process(), Exist thread()
Exist thread(), Terminate thread()
JUNAID MALIK 29
AL-JUNAID TECH INSTITUTE
178. The termination handler cannot axecute the____ statement
Break
Report
Continue
Retur
179. C ++ execution handling is implemented using____
SCH
ECH
ESH
SEH
180. A filter function ____ the type of n exception.
Restrick
Evaluates
Exclude
Identifies
181. The _____ exception are enabled with the help of controlfp() function
Floating point
String
Mutex
Integer
182. ecategory is a/an _____
Reference variable
Simple variable
Class
Pointer
183. Which of the following in the number of parameters takes by
controlpf() function
3
4
1
2
184. Which of the following in the number of parameters takes by filter
function
JUNAID MALIK 30
AL-JUNAID TECH INSTITUTE
1
2
3
4
185. Which of the following instruction is used to suspend the execution of
a program for 5 milliseconds?
Sleep(500)
Sleep(5000)
Sleep(5)
Sleep(0.5)
186. Which of the following functions is used to generate a sound beep for
0.7 seconds with the frequency if 750?
Beep (750,800)
Beep(700,750)
Beep(750,700)
Beep(750,0.7)
187. A program can be terminated by passing____ from keyboard
Ctrl +p
Ctrl +N
Ctrl +C
Ctrl +Z
188. The return type of WINAPI Handler() function if _____
Void
Static integer
Static bool
Static float
189. Correct Syntax of getcurrentdirectory()___
lenCurDir = GetCurrentDirectory (DIRNAME_LEN, pwdBuffer)
lenCurDir = GetCurrentDirectory (pwdBuffer, DIRNAME_LEN)
lenCurDir = GetCurrentDirectory (DIRNAME_LEN)
NONE
JUNAID MALIK 31
CS609- SYSTEM
PROGRAMMING
(SOLVED MCQs)
FROM MIDTERM PAPERS
(1 to 92 TOPICS)
4. Windows operating system provides a naming scheme for the resources which allows
maximum character only
❖ 255
❖ 16
❖ 55
❖ 155
5. DOS was a _______ operating system.
❖ GUI based
❖ Command line
125. During searching files/folders, a data structure ______ is used to store the
information about a found file or directory
❖ Directory -64
❖ Attribute
❖ Directory -32
❖ WIN32_FIND DATA
126. What will be next code statement, if the following if statement is true? If
(!writeFile(hFile& header, size of(Header),&nXfer,&ovzero))
❖ ReportError (_T(“RecordAccessError:set End of header.”),6,TRUE);
❖ ReportError (_T(“RecordAccessError:set pointer.”),4,TRUE);
❖ ReportError (_T(“RecordAccessError:write File header.”),5,TRUE);
❖ ReportError (_T(“RecordAccessError:readFile header.”),4,TRUE);
127. The number of arguments required for Findclose()API is ____
❖ 3
❖ 1
❖ 2
❖ 0
128. The field flastAccessTime in a WIN32-FIND-DATA structure is used to represent
a time when a file was ______ time accessed
❖ Closing
❖ Last
❖ First
❖ Second ;last
129. Using GetFileTime() API argument(s) is/are provided.
❖ Both creation and last access time
❖ Only last access time
❖ Creation, last access and last write time
The ___ register of Real Time Clock is used to enable interrupt on various events
like alarm time and time-up duration
Status Register A
Status Register B
MIDTERM EXAMINATION
Spring 2012
CS609- System Programming
1
Question No: 5 ( Marks: 1 ) - Please choose one
DTE is ____________.
►Preemptive
►Non-Preemptive (Page 48)
►Both Preemptive and Non-Preemptive
►None of Given
2
Question No: 10 ( Marks: 1 ) - Please choose one
The keyboard makes use of interrupt number _______ for its input operations.
►9 (Page 34)
►10
►11
►12
3
Question No: 16 ( Marks: 1 ) - Please choose one
LPTs can be swapped.
►True (Page 92)
►False
►Int 16H
►Int 17H (Page 84)
►Int 18H
►Int 19H
►D1
►D2
►D3
►D4 (Page 104)
4
MIDTERM EXAMINATION
Fall 2010
CS609- System Programming
►15H/2FH
►15H/4FH (Page 44)
►15H/FFH
5
Question No: 6 ( Marks: 1 ) - Please choose one
The BIOS interrupt ________ can be used to configure RTC.
►Five
►Seven
►Four
►Six (Page 72)
6
Question No: 12 ( Marks: 1 ) - Please choose one
DCE stands for __________.
►7 (Page 168)
►8
►9
►6
►2 (Page 105)
►3
►4
►5
►40:00H
►40:02H
►40:08H (Page 92)
►40:1AH
7
Question No: 17 ( Marks: 1 ) - Please choose one
The amount of memory above conventional memory (extended memory) can be determined using the service
_______.
►0xFD
►0xED (Page 181)
►0xFF
►0xEE
8
MIDTERM EXAMINATION
Spring 2009
CS609- System Programming (Session - 1)
9
Question No: 6 ( Marks: 1 ) - Please choose one
Each paragraph in keep function is ____ bytes in size.
►4
►8
►16 (Page 24)
►32
►9H
►13H
►15H
►65H (Page 65)
►4
►8 (Page 71)
►16
►32
10
Question No: 12 ( Marks: 1 ) - Please choose one
The interval timer can operate in ____modes.
►Three
►Four
►Five
►Six (Page 72) rep
11
Question No: 18 ( Marks: 1 ) - Please choose one
Interrupt ______ is used to get or set the time.
►0AH
►1AH (Page 136)
►2AH
►3AH
►1A/02H
►1A/03H (Page 138)
►1A/04H
►1A/05H
►Asynchronous serial
►Synchronous serial (not sure)
►Parallel communication
►None of the given
MIDTERM EXAMINATION
Spring 2009
CS609- System Programming (Session - 1)
►Programmed I/O
► Interrupt driven I/O
►Hardware Based I/O (Page 4)
►None of given
12
Question No: 2 ( Marks: 1 ) - Please choose one
The Function of I/O controller is to provide ____________.
►I/O control signals
►Buffering
►Error Correction and Detection
►All of given (Page 5) rep
13
Question No: 8 ( Marks: 1 ) - Please choose one
The microprocessor package has many signals for data. Below are some in Correct priority order (Higher to
Lower).
►Three
►Four
►Five
►Six (Page 72) rep
14
Question No: 13 ( Marks: 1 ) - Please choose one
BIOS DO NOT support ______.
►LPT1
►LPT2
►LPT3
►LPT4 (Page 91)
►D1
►D2
►D3
►D4 (Page 101)
►1
►3
►5
►7 (Page 114)
►INT 10 H
►INT 11 H
►INT 12 H (Page 162)
►INT 13 H
15
Question No: 18 ( Marks: 1 ) - Please choose one
Bit number _______ of coprocessor control word is the Interrupt Enable Flag.
►7 (Page 168)
►8
►9
►10
►0xF3
►0xED (Page 181) rep
►0xE5
►0xFF
MIDTERM EXAMINATION
Spring 2009
CS609- System Programming (Session - 1)
►True
►False
16
Question No: 3 ( Marks: 1 ) - Please choose one
In case of synchronous communication a timing signal is required to identify the start and end of a bit.
►Service#0
►Service#1 (Page 121)
►Service#2
►None of the given option.
17
Question No: 9 ( Marks: 1 ) - Please choose one
The ________function initialize the COM port whose number is passed as parameter using BIOS services.
►Initializecom()
►Initialize() (Page 125)
►Recievechar()
►None of these option
►Synchronous communication
►Asynchronous communication (Page 106)
►Both
►None of given
►Clock counter
►ROM
►Clock
►Real time clock (Page 136)
18
Question No: 14 ( Marks: 1 ) - Please choose one
There are two type of communication synchronous and Anti Synchronous
►True
►False (Page 105)
►STOn()
►SelfTest()
►SelfTestOn() (Page 127)
►Non of these
►True
►False
19
CS609 System Programming
Mid Term Examination – Spring 2006
► 4 bytes
► 6 bytes
► 8 bytes Click here for detail
► 10 bytes
► 0040:0000H
► 0040:0013H
► 0040:0015H
► 0040:0017H (Page 29)
Question No. 4 Marks : 2
If we use keep (0, 1000) in a TSR program, the memory allocated to it is
► 64000 bytes
► 32000 bytes
► 16000 bytes
► 80000 bytes
► 64
► 128
► 256 (Page 10)
► 512
20
CS609 – Solved Quizzes (1 & 2)
Quiz No.1
Question : 1 of 10 ( Marks: 1 ) - Please choose one
Total No. of bytes that can be stored in Keyboard Buffer is____.
►16
►32 (Page 54)
►64
►128
►Service # 0
►Service # 1
► Service # 2 (Page 121)
►None of the given options
21
Question : 6 of 10 ( Marks: 1 ) - Please choose one
------------ is used to read date from RTC
►1A\02H
►1A\03H
►1A\04H (Page 138)
►1A\05H
►Receivebyte ();
►Receive ();
►Receivechar (); (Page 125)
►None of the given option
►1A\02H
►1A\03H (Page 138)
►1A\04H
►1A\05H
22
Quiz No.2
Question : 1 of 10 ( Marks: 1 ) - Please choose one
Software based flow control make use of -------- control characters
►Xon
►XOFF
►Both (Page 135)
►None
►0
►1
►2
►3 (Page 249)
23
Question : 7 of 10 ( Marks: 1 ) - Please choose one
PPI interconnection _______ bits is cleared to indicate low nibble is being sent.
►D1
►D2
► D3
► D4 (Page 101)
►3
►5
►8 (Page 257)
►11
►Contiguous http://www.pgallert.de/english/SysAdmin/OS/file.htm
►Chained
►Indexed
►None
24
Question : 2 of 10 ( Marks: 1 ) - Please choose one
To access the block within cluster using BIOS services the cluster number should be converted into _____.
►CHS
►LBA
►LSN (Page 258)
►None of the given
25
Question : 4 of 10 ( Marks: 1 ) - Please choose one
Control information in files is maintained using
►BPB
►DPB
►FCB (Page 256)
►FPB
►1
►2 (Page 54)
►4
►8
►01
►02
►03
►FF
► 0x0A
►0x0B
► 0x0C
►0x0F (Page 95)
►0xf ,IRQ 7
► 0xa, IRQ 6
► 0x8, IRQ 5
►0x6, IRQ 2
26
Question : 9 of 10 ( Marks: 1 ) - Please choose one
If we want to produce the grave voice from speaker phone then we have to load the ____ divisor values at Port
____.
►high, 0x42
►low, 0x22
►high, 0x22
►low, 0x42
►if (((*scr)&12)==12)
►if (((*scr)&8)==8)
►if (((*scr)&4)==4)
►if (((*scr)&2)==2)
27
CS609 Midterm Subjective Solved with References
((( inport((*lpt) +1)) & 0x80) == 0x80) which condition is checked? 2 marks
Q:2
Which command used before changing the typematic and LEDS? 3 marks.
If data is to be transferred from one computer to another through some media which can carry
digital data then the modem can be eliminated and the UART on both computers can be
interconnected. Such arrangement is called a NULL modem.
• Write on buffer
Interrupt 11H is used to determine the systems information. On return this service returns the
systems info in AX register.
Q.2: When we discuss flow control using RS232C. Which line is used for data transmission and
reception?
Q.3: What the usage of coprocessor control word while testing for coprocessor?
The coprocessor control word contains some control information about the coprocessor. The
bit number 7 of coprocessor control word is the Interrupt Enable Flag and bit number 8 & 9
should contain 11on initialization. The coprocessor status register stores the status of the
coprocessor. Very much like the flags register in the microprocessor the Coprocessor status
word can be used to determine the result of a comparison as shown in the slide.
Q.4: Suppose we have got the status byte of LPT1 port usig BIOS function int 17H.Write the
condition
Answer:
AH=00
AL=ASCII code
DX=Interface#
On exit
AH=Status Byte
in C language that can check the time out, transfer error and out of paper error.
The UART is a device used for asynchronous communications. UART is capable of encapsulating
a byte that might be 5, 6, 7 or 8 bits wide in start and stop bits. Moreover it can attach an extra
parity bit with the data for error detection. The width of stop bits may also vary.
• Write on buffer
temp=*(lpt);
*lpt=*(lpt + 1);
*(lpt + 1)=temp;
Answer:
Similarly some data (as control information) can be send to the keyboard. The processor will
write on the port 60H. The device driver will check the OBF( output buffer full bit of port 64H
which remains set as long as the byte is not received by the keyboard. On receipt of the byte
from the port 60H the keyboard device write a code 0xFA on the port 60H to indicate that the
byte has been received properly.
Answer:
Int 12H is used to determine the amount of conventional memory interfaced with the processor
in kilobytes. The amount of memory above conventional memory (extended memory) can be
determined using the service 15H/88H.
First the low nibble of the byte is sent from the sender in bit D0 to D3 of the data port. D4 bit is
cleared to indicate the low nibble is being sent. The receiver will know the arrival of the low
nibble when its checks BUSY bit which should be set (by the interface) on arrival.
Answer:
The lower 4 bits of this register stores a code indicating the frequency with which the RTC
hardware interrupt can interrupt the processor. The next field is used to specify the time
frequency i.e. the frequency with the time is sampled and hence updated. The most significant
bit indicates that after time sampling if the time has been updated in to the 64 byte RAM or
not.
Answer:
Once an interrupt occurs it may be required to identify the case of the interrupt. This register is
used to identify the cause of the interrupt.
What are the usages of coprocessor control word in coprocessor while testing for
coprocessor? 3 marks
Answer:
The coprocessor control word contains some control information about the coprocessor. The
bit number 7 of coprocessor control word is the Interrupt Enable Flag and bit number 8 & 9
should contain 11 on initialization.
Answer:
In direct parallel port programming it indicate to print a file. While loop terminate when the file
ends.
Unsigned int far * lpt = (unsigned int far *)0x00400008 Direct parallel port programming LPTs
swapping
Answer:
Here we are accessing the base register address of LPT1 that is on the 40 segment 08 offset
Answer:
First the low nibble of the byte is sent from the sender in bit D0 to D3 of the data port. D4 bit is
cleared to indicate the low nibble is being sent. The receiver will know the arrival of the low
nibble when its checks BUSY bit which should be set (by the interface) on arrival.
Answer:
Answer:
Answer:
Data is received through the RxD line. Data is send through the TxD line. DTR (data terminal
Answer:
Real time clock is a device incorporated into the PC to update time even if the computer is off.
It has the characteristics shown in the slide above which enables it to update time even if the
computer is off.
Answer:
Answer:
UART contains a self test mode which can be used by the programmer to self test the software.
In self test mode the output of the UART is routed to its input. So you receive what you send.
Answer:
Moreover if a single computer is available to a developer the UART contains a self-test mode
which can be used by the programmer to self-test the software. In self-test mode the output of
the UART is routed to its input. So you receive what you send.
Answer:
Answer:
First the low nibble of the byte is sent from the sender in bit D0 to D3 of the data port. D4 bit is
cleared to indicate the low nibble is being sent. The receiver will know the arrival of the low
nibble when its checks BUSY bit which should be set (by the interface) on arrival.
A function that will send com port. com port number will be accessed as parameter ?
Answer:
The initialize () function initializes the COM port whose number is passed as parameter using
BIOS services.
Answer: