Direct Memory Access

Direct Memory Access Controller
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.
 

DMA Interfacing
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 is 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.
 
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.

DMA Modes
Block Transfer Mode
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.
Single Transfer Mode
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 Mode
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.

DMA Internals
DMA Status Register
In status register terminal count if reached signifies that the whole of the block as requested through some DMA channel has been transferred. The below status register maintains the status of Terminal count (TC) and DREQ for each channel within the DMA.

DMA Command Register
 It is used to program various common parameters of transfer for all the channels.

DMA Request Register
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.

DMA Mask-1 Register
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.
 

DMA Mask-2 Register
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.

DMA Mode Register
This register can be used to set the mode on each. The figure shows the detail of the values and bits which should be placed in the register in order to program a required mode.
 

UART in self test mode

UART in self test mode

#include <dos.h>
#include <bios.h>
/* The initialize() loads the divisor value of 0x0180 high
 byte in base +1 and low byte in base +0. It also program
the line control register for all the required line parameters.*/
void initialize (unsigned int far *com)
{
            outportb ( (*com)+3, inport ((*com)+3) | 0x80);
            outportb ( (*com),0x80);
            outportb( (*com) +1, 0x01);
            outportb ( (*com)+3, 0x1b);
}

/* Its simply enables the self test facility within the modem
   control register.*/
void SelfTestOn(unsigned int far * com)
{
            outportb((*com)+4,inport((*com)+4)|0x10);
}

/* The SelfTestOff() function turns loop back facility off*/
void SelfTestOff(unsigned int far * com)
{
outportb( (*com)+4, inport((*com)+4) & 0xEf);
}

/* The writechar() function writes the a byte passed to this function
    on the data port*/
void writechar( char ch, unsigned int far * com)
{
            while ( !((inportb((*com)+5) & 0x20) == 0x20));
            outport(*com,ch);
}

/*The readchar() function reads a byte from the data port./*
char readchar( unsigned int far *com)
{
            while (!((inportb((*com)+5) & 0x01)==0x01));
            return inportb(*com);
}

/*get the com1 port address from BIOS data area*/
unsigned int far *com=(unsigned int far*) 0x00400000;
void main ()

            char ch = 0; int i = 1;int j= 1;
            char ch2=’A’;
            initialize( com);
            SelfTestOn(com);
            clrscr();
           /* Exit from loop on ESC*/
           while (ch!=27)
            {  
               if (i==80)
               {
                        j++;
                        i=0;
                }
            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);
}

 

UART Internals

Serial Communication basics
 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 i.e. synchronous communication and asynchronous.

Serial Communication using UART
The UART is a device used for asynchronous communications. UART is capable o encapsulating a byte that might be 5,6,7 or 8 bits wide in start and stop bits. Moreover itcan attach an extra parity bit with the data for error detection. The width of stop bits may also vary.

RS-232C Standard
RS-232C is a standard for physical dimension of the connector interconnecting a DTE(Data  terminal equipment) and DCE (Data communication equipment).

RS-232C Connectors and Signals
DB25 Pin Connector

DB9 Pin Connector
 

Flow Control Using RS-232C

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.

UART internals

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 control bit to load the divisor value.

Line Status Register
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.

Interrupt enable Register.
If interrupt driven output is to be performed then this register is used to enable interrupt for the UART

Interrupt ID register
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.

Modem Control Register
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.
 

Modem Status Register
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.

Web Refrences
http://www.lammertbies.nl/comm/info/serial-uart.html

Computer Connectivity

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 communications can be performed.

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. Below is the explanation;

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.

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.

Checking the Algorithm
Sending a 9A byte

Intervel Timer

Interval Timer
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.

Interval Timer Programming
Load the Command byte into command register required to program the specific channel.The divisor word is then serially loaded byte by byte.

Command Registers
It is 8-bit Command port. Need to be programmed before loading the divisor value for a channel. 3 channels each require a 16-bit divisor value to generate the output frequency.


Ports & Channels
3-Channels; each has 16-bit wide divisor value i.e. 0~65535. 8-bit port for each channel therefore the divisor word is loaded serially byte by byte. Its port address is as follow;
43H = Command Port
40H = 8-bit port for Channel 0
41H = 8-bit port for Channel 1
42H = 8-bit port for Channel 2

Programming the Interval Timer for PC Speaker:


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);
}

Disk Partition

Disk Partition
Partition Table contains information pertaining to disk partitions. Partition Table is the first physical sector i.e.  Head = 0, Track/Cylinder = 0, Sec = 1 or LBA = 0. Partition Table at CHS = 001 is also called MBR (Master Boot Record).

Structure of Partitioning Table
Total size of Partition Table is 512 bytes. First 446 bytes contains code which loads the boot block of active partition and is executed at Boot Time. Rest of the 66 bytes is the Data part. Last two bytes of the Data part is the Partition table signature.

OS on each Partition
On a single disk there can be 4 different file systems and hence 4 different O.S. Each O.S. will have its individual partition on disk. Data related to each partition is stored in a 16-bytes chunk within the Data Part of Partition Table.

Structure of Data Part of P.T
The following table shows the data part of partition table;
 Data_Part_of_PT

Information stored in 16 bytes chunk
PT_16bytes_chunk

PT_16bytes_chunk1

System ID byte in 16 bytes Chunk
SystemID_1

SystemID_2

Primary Partition
Partition defined in the MBR (Master Boot Record) is primary partition. Each Primary Partition contains information about its respective O.S. However if only one O.S. is to be installed then extended partitions.

Extended Partition
If a single operating system is to be kept for instance, then the disk can be divided into primary and extended partitions. Information about primary and extended partition is kept in the first physical block. The extended partition may again be divided into a number of partitions, information about further partitions will be kept in extended partition table which will be the first physical block within extended partition (i.e. it will not the first block of primary partition.). Moreover there can be extended partitions within extended partitions and such that in then end there are number of logical partitions this can go on till the last drive number in DOS.
Extended_PT_1

Extended_PT_2

Extended_PT_3

Chain of Extended Partition
 PT_Chian

Extended P.T Example:
 PT_Example
First Partition:
System ID = 0c = Windows FAT32 partition (LBA MApped)
first block = 3F
No. of blocks = 01388afc
end cylinder# = 1023
end sec # = 63 indicating a LBA disk
 
Second Partition:
System ID = 0f = Extended windows partition
Start block (relative to the start) = 01388b3b = 20482875
No. of blocks = 0390620a = 59793930

Refrence:
http://www.p-dd.com/chapter1.html

FAT32 based file system

Disassembling a File

FAT32 File System :
The following figure shows the anatomy of FAT32;
img1
No fixed space reserved for root directory. FCB of root directory are saved in a cluster and the cluster # for root directory is saved in BPB.

Starting Sector # for a Cluster
Starting Sector = Reserved Sect. + (Fat Size * Fat Copies) +
(cluster # – 2) * size of cluster
Dump of BPB in Boot Block
1. Finding the reserved block size
img2
Offset 14 = 0x0E = Reserved Sect. = 0x0024

2. Finding the fat copies and its size
img2
Offset 16 = 0x10 = Count of FAT’S = 0x0002

img2
Offset 36 = 0x24 = Sectors occupied by single FAT = 0x0000253E

3. Finding Cluster # for Root Dir
img2
Offset 44 = 0x2C = 0x0000 0002

4. Size of Cluster in Sectors
img2
Offset 13 = 0x0D = 0x20 = 32 blocks

Starting Sector for Cluster # 2
Starting Sector = Reserved Sect. + (Fat Size *Fat Copies) +
(Cluster # – 2) * Size of cluster
= 0x0024 + 0x0000 253E *0x0002 + (2 – 2) * 0x20
= 0x4AA0
= 19104D

Creation of File on Root
img2

Now examine the contents of root directory which is located on cluster # 2;
img3

img4

Cluster No. within FCB
Cluster # Low Word = 29C9
Cluster # Hi Word    = 0009H
0009 29C9 & 0FFF FFFF = 009 29C9

File Data Sectors
Starting Sector = Reserved Sect. + Fat Size * Fat Copies +
(cluster # – 2) *   size of cluster
= 0024 + 253E * 2 + (929C9 – 2) * 0x20
= 4AA0 + 12538E0
= 1258380
= 19235712

Dump of File Data
img4

Computer Viruses

A computer virus is a special program which has following two essential characteristics:
1. A virus can embed itself in a system resource like Partition Table, Boot Sector and File etc.
2. A virus can propagate (spread) itself to other system resources for instance, it can infect more files on a system or it can infect another hard disk which might be connected with this infected system etc.
Thus, a computer virus attaches itself to some form of executable code and when that executable code is executed then the malicious code of the attached virus also executes and harms the computer. A computer virus can be in any of its following three states:

Dormant State:
A virus is said to be in dormant state when it has embedded itself in a system resource and it is observing the activities of the system.

Activation State:
When a tries to perform its intended malicious operation then it is said to be in activation state. For instance, it can try to damage the hard disk or it can corrupt the data of user etc. A virus can be activated as a result of some event in the system e.g., a virus can become active at some predefined instant of time etc.

Infection State:
In infection state a virus tries to spread itself. For instance, a virus can try to infect more files or it can infect another hard disk which might be connected to this infected system. Usually, a virus enters the infection state as result of any disk operation e.g., if a user is copying data from one hard disk to another hard disk then the virus can also infect the other hard disk. Thus, a computer virus is a program which is deliberately designed to harm the computer and to spread itself to other computers.

Types of Viruses:

Partition Table Viruses:
Partition Table viruses embed themselves in the code part of partition table.Thus, when code of partition table is executed at boot time then the code of virus also executes and loads itself in memory.

How Partition Table Viruses Works
The Partition Table Code is executed at boot time to choose the Active Partition. Partition Table Viruses embed themselves in the Partition Table of the disk. If the Virus Code is large and cannot be accommodated in the Code Part of 512-bytes Partition Table block then it may also use other Physically Addressed Blocks to reside itself. Hence at Boot time when Partition Table is to be executed to select the Active Partition, the virus executes. The Virus when executed loads itself in the Memory, where it can not be reached by the OS and then executes the original Partition Table Code (stored in some other blocks after infection) so that the system may be booted properly. When the system boots the Virus will be resident in memory and will typically intercept 13H (the disk interrupt). Whenever a disk operation occurs int 13H occurs. The Virus on occurrence of 13H checks if removable media has been accessed through int 13H. If so then it will copy its code properly to the disk first Physical Block (and other blocks depending upon size of Virus Code). The removable disk is now infected. If the disk is now removed and is then used in some other system, the Hard Drive of this system will not be infected unless the system is booted from this disk. Because only on booting from this removable disk its first physical block will get the chance to be executed. 

How Partition Table Virus Loads itself
The transient part of Command.Com loads itself such that its last byte is loaded in the last byte of Conventional Memory. If somehow there is some Memory beyond Command.Com’s transient part it will not be accessible by DOS. At 40:13H a word contains the amount of KBs in Conventional Memory which is typically 640. If the value at 40:13H is somehow reduced to 638 the transient part of Command.Com will load itself such that its last byte is loaded at the last byte of 638KB mark in Conventional RAM. In this way last 2KB will be left unused by DOS. This amount of memory is used by the Virus according to its own size.

Boot Sector virus
Boot Sector viruses embed themselves in the code part of boot sector.

How Boot Sector Virus Works
Boot Sector also works in almost the same pattern, the only difference is that it will embed itself within the Boot Block Code.

File Viruses
Various Viruses embeds themselves in different executable files. Theoretically any file that can contain any executable code, a Virus can be embedded into it. i.e. .COM, .EXE are executable files so Viruses can be embedded into them, Plain Text Files, Plain Bitmap Files are pure data and cannot be executed so Viruses cannot be actively embedded into them, and even if they are somehow embedded they will never get a chance to execute itself.

COM File
COM File is a mirror image of the program code. Its image on disk is as it is loaded into the memory.COM Files are single segment files in which both Code and Data resides.COM File will typically have a Three Bytes Near Jump Instruction as the first instruction in program which will transfer the execution to the Code Part of the Program

How COM File Virus Infects Files
A COM File Virus if resident may infect COM Files on execution. Typically COM File Virus will interrupt 21H Service 4B. This Service is used to load a Program. Whenever a Program is to be loaded int 21H Service # 4BH is used to Load a Program. The Virus if resident will check the parameters of this Service to get the file path. If the File is .COM File then the Virus appends itself to the file and tempers with the first 3-bytes of .COM File so that the execution branches to the Virus Code when the program is executed.

How COM Virus Loads Itself
When a file is loaded in Memory it will occupy a number of Paragraphs controlled by some MCB. If the file is infected the Virus is also loaded within the Memory Area allocated to the Program. In this case the Virus does not exist as an Independent Program as it does not have its own PSP. If the Program is terminated the Virus Code will also be unloaded with the program. The Virus will try to attain an Independent Status for which it needs to relocate itself and create its own PSP and MCB in Memory. When the program runs the Virus Code executes first. The Virus creates an MCB, defines a new PSP initializes the PSP and relocates itself, updates the last MCB, so that it can exist as an Individual Program, and then transfers the execution back to the Original Program Code. Now if the Original Program Terminates the Virus will still remain resident.

EXE File Viruses
The EXE File Viruses also works the same way in relocating themselves. The main difference in COM File and DOS EXE File is that the COM File starts its execution from the first instruction, whereas the entry point of execution in EXE File can be anywhere in the Program. The entry point in case of EXE File is tempered by the Virus which is stored in a 27-byte header in EXE File.
Detection
Viruses can be detected by searching for their Signature in Memory or Executable Files. Signature is a binary subset of Virus Code. It is a part of Virus Code that is unique for that particular Virus only and hence can be used to identify the Virus. Signature for a Virus is selected by choosing a unique part of its Code. To find a Virus this Code should be searched in memory and in files. If a match is found then the system is infected.
 
Removal
Partition Table and Boot Sector Viruses can be removed by re-writing the Partition Table or Boot Sector Code. If the Virus is resident it may exhibit stealth i.e. prevent other programs from writing on Partition Table or Boot Sector by intercepting int 13H. In case it’s a stealth Virus the system should be booted from a clean disk will not give the Virus any chance to execute or load itself.
 File Viruses
 
If the Virus size is known Viruses can be removed easily from file. Firstly, the original value of first 3-bytes in case of COM File or the entry point in case of EXE should be restored. The appended portion of Virus can be removed by copying the contents of original file into a temporary file. The Virus Code is not copied. The original file is then deleted and the temporary file is renamed as the original file.

A TSR based clock in C

The following is the code of the program;

#include <dos.h>

/* interrupt pointer for old timer ISR */
void interrupt (*oldTimer)();

/* new ISR for timer interrupt */
void interrupt newTimer();

/* far pointer to display memory */
char far *screenPtr = (char far *) 0xb8000000;

/* variable used to keep track of timer ticks */
int timerTick = 0;

/* variable to hold value of hour */
unsigned char hour = 0;

/* variable to hold value of minute */
unsigned char minute = 0;

/* variable to hold value of second */
unsigned char second = 0;

/* flag to keep track of AM and PM */
int isAM = 0;

/*———————– main function —————————*/
void main()
{
 /* declare a time structure variable */
 struct time currentTime;

 /* get current time by using gettime function */
 gettime(&currentTime);

 /* get value of current hour */
 hour = currentTime.ti_hour;

 /* get value of current minute */
 minute = currentTime.ti_min;

 /* get value of current second */
 second = currentTime.ti_sec;

 /* determine if it is AM or PM */
 if ( hour < 12 )
 {
  isAM = 1;
 }
 else
 {
  isAM = 0;
 }

 /* convert current time to standard time */
 if ( hour == 0 || hour == 12 )
 {
  hour = 12;
 }
 else
 {
  hour = hour % 12;
 }

 /* get vector of INT 8 */
 oldTimer = getvect(0x08);

 /* set vector of INT 8 */
 setvect(0x08, newTimer);

 /* make the program TSR */
 keep(0, 1000);

}

/*———————– new timer ISR ———————–*/
void interrupt newTimer()
{
 /* check if 1 second have elapsed */
 if ( timerTick >= 18 )
 {
  /* increment second */
  ++second;

  /* increment minute after 60 seconds */
  if ( second > 59 )
  {
   second = 0;
   ++minute;

   /* increment hour after 60 seconds */
   if ( minute > 59 )
   {
    minute = 0;
    ++hour;

    /* toggle AM or PM */
    if ( hour == 12 )
    {
     if ( isAM == 1 )
     {
      isAM = 0;
     }
     else
     {
      isAM = 1;
     }
    }

    /* reset hour */
    if ( hour > 12 )
    {
     hour = 1;
    }
   }
  }

  /* reset timer tick count */
  timerTick = 0;
 }

 /* display 1st digit of hour */
 *(screenPtr + 130) = ( hour / 10 ) + 48;
 *(screenPtr + 131) = 0x70;

 /* display 2nd digit of hour */
 *(screenPtr + 132) = ( hour % 10 ) + 48;
 *(screenPtr + 133) = 0x70;

 /* display separator */
 *(screenPtr + 134) = ‘:’;
 *(screenPtr + 135) = 0x70;

 /* display 1st digit of minute */
 *(screenPtr + 136) = ( minute / 10 ) + 48;
 *(screenPtr + 137) = 0x70;

 /* display 2nd digit of minute */
 *(screenPtr + 138) = ( minute % 10 ) + 48;
 *(screenPtr + 139) = 0x70;

 /* display separator */
 *(screenPtr + 140) = ‘:’;
 *(screenPtr + 141) = 0x70;

 /* display 1st digit of second */
 *(screenPtr + 142) = ( second / 10 ) + 48;
 *(screenPtr + 143) = 0x70;

 /* display 2nd digit of second */
 *(screenPtr + 144) = ( second % 10 ) + 48;
 *(screenPtr + 145) = 0x70;

 /* display a space */
 *(screenPtr + 146) = ‘ ‘;
 *(screenPtr + 147) = 0x70;

 /* display A or P */
 if ( isAM == 1 )
 {
  *(screenPtr + 148) = ‘A’;
 }
 else
 {
  *(screenPtr + 148) = ‘P’;
 }
 *(screenPtr + 149) = 0x70;

 /* display M */
 *(screenPtr + 150) = ‘M’;
 *(screenPtr + 151) = 0x70;

 /* increment timer tick count */
 ++timerTick;

 /* call original old timer ISR */
 (*oldTimer)();
}

Below is the output of a program.

example pic