HARDWARE LAB PROGRAMS
TABLE OF CONTENTS
SR NO. / DESCRIPTION / PAGE1 / TYPE COMMAND / 3
2 / COPY COMMAND / 5
3 / BOOT SECTOR OF FLOPPY / 9
4A / ROOT DIRECTORY OF FLOPPY / 16
4B / DISPLAY FILE CONTENTS USING FAT / 20
5 / PRINTER DEVICE DRIVER / 24
6A / CHAT APPLICATION / 30
6B / FILE TRANSFER / 31
7 / MOUSE INTERFACE / 34
8 / DPMI / 39
9 / TIMER / 43
10 / SERIAL COMMUNICATION / 46
11 / STEPPER MOTOR / 50
1) WRITE AN ALP TO SIMULATE TYPE COMMANDOF DOS USING PSP.
DISP MACRO MSG ;MACRO TO DISPLAY A STRING
LEA DX, MSG
MOV AH, 09H
INT 21H
ENDM
.MODEL SMALL
.DATA
ERROR DB 10, 13, " FILE COULD NOT BE FOUND/OPENED.", 10, 13, '$'
INCORRECT DB 10, 13, " FILENAME NOT SPECIFIED.", 10, 13, '$'
FILENAME DB 10H DUP(00H) ;BUFFER TO STORE FILENAME
FILEHANDLE DW ? ;16 BIT OFFSET OF FILE
BUFFER DB 512 DUP(00H) ;512 BYTES BUFFER
COUNT DW ? ;NUMBER OF BYTES TRANSFERRED
.CODE
START:
MOV AX, @DATA
MOV DS, AX
MOV AH, 62H ;GET PSP DETAILS IN BX
INT 21H
MOV ES, BX ;LOAD PSP ADDRESS IN ES
MOV AL, ES:[80H] ;CHECK IF COMMAND LINE
CMP AL, 00H ;PARAMETER IS SPECIFIED
JNE NOTEMPTY ;OR NOT?
DISP INCORRECT
JMP EXIT
NOTEMPTY: ;FILE NAME IS SPECIFIED
LEA SI, FILENAME
MOV DI, 82H
;COPY COMMAND LINE PARAMETERS STORED FROM ES:[82H]TO THE VARIABLE FILENAME
ACCEPT:
MOV AH, ES:[DI]
CMP AH, 0DH ;COMPARE FOR ENTER KEY
JE ENDACCEPT
CMP AH, 20H ;COMPARE FOR SPACE
JE ENDACCEPT
MOV [SI], AH
INC SI
INC DI
JMP ACCEPT
ENDACCEPT:
CALL OPENFILE
NEXTBUFFER:
CALL READ ;READ AND PRINT
CMP AX, 0000H ;CONTENTS OF FILE
JE FILECLOSE ;TILL END OF FILE IS NOT
CALL PRINT ;REACHED
JMP NEXTBUFFER
FILECLOSE:
CALL CLOSEFILE
EXIT:
MOV AX, 4C00H
INT 21H
OPENFILE PROC NEAR
MOV AH, 3DH
MOV AL, 00H ;OPEN FILE IN READ ONLY MODE
LEA DX, FILENAME
INT 21H
JNC SUCCESS
DISP ERROR
JMP EXIT
SUCCESS:
MOV FILEHANDLE, AX
RET
OPENFILE ENDP
READ PROC NEAR
MOV AH, 3FH
MOV BX, FILEHANDLE
MOV CX, 512 ;NUMBER OF BYTES TO READ
LEA DX, BUFFER
INT 21H ;RETURNS AX=0 IF EOF REACHED
MOV COUNT, AX ;NUMBER OF BYTES TRANSFERRED
RET
READ ENDP
PRINT PROC NEAR
MOV AH, 40H
MOV BX, 0000H ;WRITE ON MONITOR
MOV CX, COUNT
LEA DX, BUFFER
INT 21H
RET
PRINT ENDP
CLOSEFILE PROC NEAR
MOV AH, 3EH
MOV BX, FILEHANDLE
INT 21H
RET
CLOSEFILE ENDP
END START
2) AIM : WRITE AN ALP TO SIMULATE COPY COMMAND OF DOS USING PSP.
DISP MACRO MSG ;MACRO TO DISPLAY A STRING
LEA DX, MSG
MOV AH, 09H
INT 21H
ENDM
.MODEL SMALL
.DATA
ERROR DB 10, 13, " FILE COULD NOT BE FOUND/OPENED.", 10, 13, '$'
INCORRECT DB 10, 13, " FILENAME/S NOT SPECIFIED.", 10, 13, '$'
INVALID DB 10, 13, " PLEASE SPECIFY TWO FILENAMES.", 10, 13, '$'
FILEPRESENT DB 10, 13, " FILE ALREADY PRESENT. OVERWRITE ?(Y/N) : $"
COPIED DB 10, 13, 10, 13, " FILE COPIED SUCCESSFULLY.", 10, 13, '$'
SRCFILE DB 10H DUP(00H) ;BUFFER TO STORE SOURCE FILE NAME
SRCHANDLE DW ? ;16 BIT OFFSET OF SOURCE FILE
DESTFILE DB 10H DUP(00H) ;BUFFER TO STORE DESTINATION FILE NAME
DESTHANDLE DW ? ;16 BIT OFFSET OF DESTINATION FILE
BUFFER DB 512 DUP(00H) ;512 BYTE CHARACTER BUFFER
COUNT DW ?
.CODE
START:
MOV AX, @DATA
MOV DS, AX
MOV AH, 62H ;GET PSP DETAILS IN BX
INT 21H
MOV ES, BX ;LOAD PSP ADDRESS IN ES
MOV AL, ES:[80H] ;CHECK IF COMMAND LINE
CMP AL, 00H ;PARAMETER IS SPECIFIED
JNE NOTEMPTY ;OR NOT?
DISP INCORRECT
JMP EXIT
NOTEMPTY: ;FILE NAME IS SPECIFIED
LEA SI, SRCFILE
MOV DI, 82H
;COPY COMMAND LINE PARAMETERS STORED FROM ES:[82H]
;TILL SPACE TO THE VARIABLE SRCFILE
ACCEPT1:
MOV AH, ES:[DI]
CMP AH, 20H ;COMPARE FOR SPACE
JE ENDACCEPT1
CMP AH, 0DH ;COMPARE FOR ENTER KEY
JE DISPERROR
MOV [SI], AH
INC SI
INC DI
JMP ACCEPT1
DISPERROR:
DISP INVALID
JMP EXIT
ENDACCEPT1:
LEA SI, DESTFILE
;CHECK FOR CONSEQUENT SPACES
NEXTSPACE:
INC DI
MOV AL, ES:[DI]
CMP AL, 0DH ;IF ENTER IS FOUND, DISPLAY ERROR
JE DISPERROR
CMP AL, 20H ;STARTING OF NEXT FILENAME IS NOT SPACE
JNE ACCEPT2
JMP NEXTSPACE
;COPY COMMAND LINE PARAMETERS STORED FROM ES:[DI]
;TILL ENTER KEY TO THE VARIABLE DESTFILE
ACCEPT2:
MOV AH, ES:[DI]
CMP AH, 0DH ;COMPARE FOR ENTER KEY
JE ENDACCEPT2
CMP AH, 20H ;COMPARE FOR SPACE
JE ENDACCEPT2
MOV [SI], AH
INC SI
INC DI
JMP ACCEPT2
ENDACCEPT2:
CALL OPENFILES
NEXTBUFFER:
CALL READ ;READ AND WRITE
CMP AX, 0000H ;CONTENTS OF FILE
JE EOF ;TILL END OF FILE IS NOT
CALL WRITE ;REACHED
JMP NEXTBUFFER
EOF:
DISP COPIED
FILECLOSE:;CLOSES BOTH FILES
CALL CLOSEFILE1
CALL CLOSEFILE2
EXIT:
MOV AX, 4C00H
INT 21H
OPENFILES PROC NEAR
;-----OPEN SOURCE FILE-----
MOV AH, 3DH
MOV AL, 00H ;OPEN FILE IN READ ONLY MODE
LEA DX, SRCFILE
INT 21H
JNC SUCCESS1
DISP ERROR
JMP EXIT
SUCCESS1:
MOV SRCHANDLE, AX;STORE SOURCE FILE-HANDLE
;-----CHECK IF DESTINATION FILE IS PRESENT OR NOT-----
MOV AH, 3DH
MOV AL, 00H ;OPEN FILE IN READ ONLY MODE
LEA DX, DESTFILE
INT 21H
JC NOTPRESENT ;FILE IS NOT PRESENT.
;DIRECTLY CREATE NEW FILE
MOV DESTHANDLE, AX;STORE DESTINATION FILE-HANDLE
DISP FILEPRESENT ;FILE ALEADY EXISTS.
MOV AH, 01H ;ASK TO OVERWRITE
INT 21H
CMP AL, "Y"
JE NOTPRESENT
CMP AL, "y"
JE NOTPRESENT
JMP FILECLOSE;JMP TO CLOSE BOTH FILES
NOTPRESENT:
;-----CREATE/OVERWRITE DESTINATION FILE-----
LEA DX, DESTFILE
MOV AH, 3CH
MOV CX, 0000H ;NORMAL FILE ATTRIBUTES
INT 21H
JNC SUCCESS2
DISP ERROR
CALL CLOSEFILE1 ;SINCE ONLY 1ST FILE OPENED, FIRST CLOSE THEN EXIT.
JMP EXIT
SUCCESS2:
;-----OPEN DESTINATION FILE-----
MOV AH, 3DH
MOV AL, 01H ;OPEN FILE IN WRITE ONLY MODE
LEA DX, DESTFILE
INT 21H
JNC SUCCESS3
DISP ERROR
CALL CLOSEFILE1;SINCE ONLY 1ST FILE OPENED, FIRST CLOSE THEN EXIT.
JMP EXIT
SUCCESS3:
MOV DESTHANDLE, AX;STORE DESTINATION FILE-HANDLE
RET
OPENFILES ENDP
READ PROC NEAR
MOV AH, 3FH
MOV BX, SRCHANDLE
MOV CX, 512 ;NUMBER OF BYTES TO READ
LEA DX, BUFFER
INT 21H ;RETURNS AX=0 IF EOF REACHED
MOV COUNT, AX
RET
READ ENDP
WRITE PROC NEAR
MOV AH, 40H
MOV BX, DESTHANDLE
MOV CX, COUNT ;NUMBER OF BYTES TO WRITE
LEA DX, BUFFER
INT 21H
RET
WRITE ENDP
CLOSEFILE1 PROC NEAR
;CLOSE SOURCE FILE
MOV AH, 3EH
MOV BX, SRCHANDLE
INT 21H
RET
CLOSEFILE1 ENDP
CLOSEFILE2 PROC NEAR
;CLOSE DESTINATION FILE
MOV AH, 3EH
MOV BX, DESTHANDLE
INT 21H
RET
CLOSEFILE2 ENDP
END START
3)AIM : WRITE AN ALP/IN-LINE CODE FOR DISPLAYINGBOOT SECTOR OF FLOPPY.
DECIMAL VALUES(CLUSTER NUMBERS)
Boot Sector(Below)
#include<stdio.h>
#include<conio.h>
#include<process.h>
int main()
{
char buff[512], *ptr, *ptr2;
int i, j;
clrscr();
asm{
MOV AL, 0x00//DRIVE NUMBER
MOV CX, 0x0001//NO. OF SECTORS TO READ
MOV DX, 0x00//STARTING SECTOR NO.
LEA BX, buff//LOAD OFFSET OF BUFFER
INT 0x25
JNC success
}
printf("\n Error");
getch();
exit(0);
success:
printf("\n BOOT SECTOR OF FLOPPY (3.5 INCH 1.44 MB) PAGE 1\n\n");
ptr = buff; //PURPOSE : PTR TO DISPLAY HEX VALUES
ptr2 = buff; //PURPOSE : PTR TO DISPLAY CHAR VALLUES
for(i = 0x0000; i <= 0x007F; i = i + 0x0008)
{
printf(" %.4X : ", i); //DISPLAY HEX NUM IN 4 DIGITS
for(j = 0; j < 8; j ++)
{
printf(" %.2X", *(unsigned char*)ptr); //DISPLAY HEX IN 2 DIGITS
ptr ++;
}
printf(" ");
for(j = 0; j < 8; j ++)
{
printf("%c", *(unsigned char*)ptr2); //NOW DISPLAY CHARACTER
ptr2 ++; //VALUES(SEE OUTPUT)
}
printf("\n");
}
getch();
clrscr();
printf("\n BOOT SECTOR OF FLOPPY (3.5 INCH 1.44 MB) PAGE 2\n\n");
for(i = 0x0080; i <= 0x00FF; i = i + 0x0008)
{
printf(" %.4X : ", i);
for(j = 0; j < 8; j ++)
{
printf(" %.2X", *(unsigned char*)ptr);
ptr ++;
}
printf(" ");
for(j = 0; j < 8; j ++)
{
printf("%c", *(unsigned char*)ptr2);
ptr2 ++;
}
printf("\n");
}
getch();
clrscr();
printf("\n BOOT SECTOR OF FLOPPY (3.5 INCH 1.44 MB) PAGE 3\n\n");
for(i = 0x0100; i <= 0x017F; i = i + 0x0008)
{
printf(" %.4X : ", i);
for(j = 0; j < 8; j ++)
{
printf(" %.2X", *(unsigned char*)ptr);
ptr ++;
}
printf(" ");
for(j = 0; j < 8; j ++)
{
printf("%c", *(unsigned char*)ptr2);
ptr2 ++;
}
printf("\n");
}
getch();
clrscr();
printf("\n BOOT SECTOR OF FLOPPY (3.5 INCH 1.44 MB) PAGE 4\n\n");
for(i = 0x0180; i <= 0x01FF; i = i + 0x0008)
{
printf(" %.4X : ", i);
for(j = 0; j < 8; j ++)
{
printf(" %.2X", *(unsigned char*)ptr);
ptr ++;
}
printf(" ");
for(j = 0; j < 8; j ++)
{
printf("%c", *(unsigned char*)ptr2);
ptr2 ++;
}
printf("\n");
}
getch();
clrscr();
printf("\n Complete Details Of Boot Sector Of Floppy :\n\n");
ptr = buff + 0x00;
printf("\n Jump To Boot Strap : %X%X", *(unsigned char *)ptr, *(unsigned char *)(ptr+1));
printf(" %X", *(unsigned char *)(ptr + 2));
printf("\n OEM Name And Version : ");
ptr = buff + 0x03;
for(i = 0; i < 8; i ++)
{
printf("%c", *(unsigned char*)ptr);
ptr ++;
}
ptr = buff + 0x0B;
printf("\n Bytes Per Sector : %d ", *(int *)ptr);
ptr = buff + 0x0D;
printf("\n Sector Per Allocation Unit : %d", *(unsigned char *)ptr);
ptr = buff + 0x0E;
printf("\n Reserved Sectors, Starting At Zero: %d", *(unsigned int *)ptr);
ptr = buff + 0x10;
printf("\n No. Of FATs : %d", *(unsigned char *)ptr);
ptr = buff + 0x11;
printf("\n No. Of Root Directory Entries : %d", *(int *)ptr);
ptr = buff + 0x13;
printf("\n Total Sectors In Logical Volumes : %d", *(int *)ptr);
ptr = buff + 0x15;
printf("\n Media Descriptor Byte : %XH", *(unsigned char *)ptr);
ptr = buff + 0x16;
printf("\n No. Of Sectors Per FAT : %d", *(int *)ptr);
ptr = buff + 0x18;
printf("\n Sectors Per Track : %d", *(int *)ptr);
ptr = buff + 0x1A;
printf("\n Number Of Heads : %d", *(int *)ptr);
ptr = buff + 0x1C;//TO ACCESS 4 BYTES, USE LONG DATA-TYPE
printf("\n Number Of Hidden Sectors : %ld", *(long *)ptr);
ptr = buff + 0x20;//TO ACCESS 4 BYTES, USE LONG DATA-TYPE
printf("\n Total Sectors In Logical Volume : %ld", *(long *)ptr);
ptr = buff + 0x24;
printf("\n Physical Drive Number : %d", *(unsigned char *)ptr);
ptr = buff + 0x26;
printf("\n Extended Boot Signature Record(29H) : %XH", *(unsigned char *)ptr);
ptr = buff + 0x27;
printf("\n 32 Bit(4 Bytes) Binary Volume ID : ");
for(i = 0; i < 4; i ++)
{
printf("%X", *(unsigned char *)ptr);
ptr ++;
}
ptr = buff + 0x2B;
printf("\n Volume Label : ");
for(i = 0; i < 11; i ++)
{
printf("%c", *(unsigned char *)ptr);
ptr ++;
}
ptr = buff + 0x36;
printf("\n File System Type : ");
for(i = 0; i < 8; i ++)
{
printf("%c", *(unsigned char *)ptr);
ptr ++;
}
getch();
return 0;
}
/*
OUTPUT :
BOOT SECTOR OF FLOPPY (3.5 INCH 1.44 MB) PAGE 1
0000 : EB 3C 90 4D 53 44 4F 53 d<ÉMSDOS
0008 : 35 2E 30 00 02 01 01 00 5.0 ???
0010 : 02 E0 00 40 0B F0 09 00 ?a @?=
0018 : 12 00 02 00 00 00 00 00 ? ?
0020 : 00 00 00 00 00 00 29 4B )K
0028 : 8C D7 48 4E 4F 20 4E 41 î+HNO NA
0030 : 4D 45 20 20 20 20 46 41 ME FA
0038 : 54 31 32 20 20 20 33 C9 T12 3+
0040 : 8E D1 BC F0 7B 8E D9 B8 Ä-+={Ä++
0048 : 00 20 8E C0 FC BD 00 7C Ä+n+ |
0050 : 38 4E 24 7D 24 8B C1 99 8N$}$ï-Ö
0058 : E8 3C 01 72 1C 83 EB 3A F<?r?âd:
0060 : 66 A1 1C 7C 26 66 3B 07 fí?|&f;
0068 : 26 8A 57 FC 75 06 80 CA &èWnu?Ç-
0070 : 02 88 56 02 80 C3 10 73 ?êV?Ç+?s
0078 : EB 33 C9 8A 46 10 98 F7 d3+èF?ÿ˜
BOOT SECTOR OF FLOPPY (3.5 INCH 1.44 MB) PAGE 2
0080 : 66 16 03 46 1C 13 56 1E f??F??V?
0088 : 03 46 0E 13 D1 8B 76 11 ?F??-ïv?
0090 : 60 89 46 FC 89 56 FE B8 `ëFnëV¦+
0098 : 20 00 F7 E6 8B 5E 0B 03 ˜µï^??
00A0 : C3 48 F7 F3 01 46 FC 11 +H˜=?Fn?
00A8 : 4E FE 61 BF 00 00 E8 E6 N¦a+ Fµ
00B0 : 00 72 39 26 38 2D 74 17 r9&8-t?
00B8 : 60 B1 0B BE A1 7D F3 A6 `¦?+í}=ª
00C0 : 61 74 32 4E 74 09 83 C7 at2Nt â¦
00C8 : 20 3B FB 72 E6 EB DC A0 ;vrµd_á
00D0 : FB 7D B4 7D 8B F0 AC 98 v}¦}ï=¼ÿ
00D8 : 40 74 0C 48 74 13 B4 0E @t?Ht?¦?
00E0 : BB 07 00 CD 10 EB EF A0 + -?dná
00E8 : FD 7D EB E6 A0 FC 7D EB ²}dµán}d
00F0 : E1 CD 16 CD 19 26 8B 55 ß-?-?&ïU
00F8 : 1A 52 B0 01 BB 00 00 E8 R¦?+ F
BOOT SECTOR OF FLOPPY (3.5 INCH 1.44 MB) PAGE 3
0100 : 3B 00 72 E8 5B 8A 56 24 ; rF[èV$
0108 : BE 0B 7C 8B FC C7 46 F0 +?|ïn¦F=
0110 : 3D 7D C7 46 F4 29 7D 8C =}¦F()}î
0118 : D9 89 4E F2 89 4E F6 C6 +ëN=ëN÷¦
0120 : 06 96 7D CB EA 03 00 00 ?û}-O?
0128 : 20 0F B6 C8 66 8B 46 F8 ¤¦+fïF°
0130 : 66 03 46 1C 66 8B D0 66 f?F?fï-f
0138 : C1 EA 10 EB 5E 0F B6 C8 -O?d^¤¦+
0140 : 4A 4A 8A 46 0D 32 E4 F7 JJèF
0148 : E2 03 46 FC 13 56 FE EB G?Fn?V¦d
0150 : 4A 52 50 06 53 6A 01 6A JRP?Sj?j
0158 : 10 91 8B 46 18 96 92 33 ?æïF?ûÆ3
0160 : D2 F7 F6 91 F7 F6 42 87 -˜÷æ˜÷Bç
0168 : CA F7 76 1A 8A F2 8A E8 -˜vè=èF
0170 : C0 CC 02 0A CC B8 01 02 +¦?
¦+??
0178 : 80 7E 02 0E 75 04 B4 42 Ç~??u?¦B
BOOT SECTOR OF FLOPPY (3.5 INCH 1.44 MB) PAGE 4
0180 : 8B F4 8A 56 24 CD 13 61 ï(èV$-?a
0188 : 61 72 0B 40 75 01 42 03 ar?@u?B?
0190 : 5E 0B 49 75 06 F8 C3 41 ^?Iu?°+A
0198 : BB 00 00 60 66 6A 00 EB + `fj d
01A0 : B0 4E 54 4C 44 52 20 20 ¦NTLDR
01A8 : 20 20 20 20 0D 0A 52 65
Re
01B0 : 6D 6F 76 65 20 64 69 73 move dis
01B8 : 6B 73 20 6F 72 20 6F 74 ks or ot
01C0 : 68 65 72 20 6D 65 64 69 her medi
01C8 : 61 2E FF 0D 0A 44 69 73 a.
Dis
01D0 : 6B 20 65 72 72 6F 72 FF k error
01D8 : 0D 0A 50 72 65 73 73 20
Press
01E0 : 61 6E 79 20 6B 65 79 20 any key
01E8 : 74 6F 20 72 65 73 74 61 to resta
01F0 : 72 74 0D 0A 00 00 00 00 rt
01F8 : 00 00 00 AC CB D8 55 AA ¼-+U¬
Complete Details Of Boot Sector Of Floppy :
Jump To Boot Strap : EB3C 90
OEM Name And Version : MSDOS5.0
Bytes Per Sector : 512
Sector Per Allocation Unit : 1
Reserved Sectors, Starting At Zero: 1
No. Of FATs : 2
No. Of Root Directory Entries : 224
Total Sectors In Logical Volumes : 2880
Media Descriptor Byte : F0H
No. Of Sectors Per FAT : 9
Sectors Per Track : 18
Number Of Heads : 2
Number Of Hidden Sectors : 0000
Total Sectors In Logical Volume : 0000
Physical Drive Number : 0
Extended Boot Signature Record(29H) : 29H
32 Bit(4 Bytes) Binary Volume ID : 4B8CD748
Volume Label : NO NAME
File System Type : FAT12
*/
4a)AIM : WRITE AN ALP/IN-LINE CODE FOR DISPLAYINGROOT DIRECTORY OF FLOPPY.
#include<stdio.h>
#include<conio.h>
#include<process.h>
int main()
{
unsigned char *ptr, buff[512 * 14];//BUFFER FOR 14 SECTORS
int i, j, temp; //TEMP FOR 16 BIT DATA
unsigned long temp32; //TEMP32 FOR 32 BIT DATA
clrscr();
asm{
MOV AL, 0x00//DRIVE NUMBER
MOV CX, 14//NO. OF SECTORS TO READ
MOV DX, 19//STARTING SECTOR NO.
LEA BX, buff//LOAD OFFSET OF BUFFER
INT 0x25
JNC success
}
printf("\n Error");
getch();
exit(0);
success:
printf("\n Attributes : ");
printf("\n R: Read Only H: Hidden S: System File");
printf("\n V: Volume Label D: Directory A: Archive\n\n");
printf("\n Name\t Ext\tAttr\tTime\t Date\t StCluster\t Size(Bytes)\n");
//INCREMENT I BY 32 BECAUSE EACH ENTRY IS OF 32 BYTES
for(i = 0; i < 512 * 14; i = i + 32)
{
ptr = buff + i;
if(*ptr != 0xE5 & *ptr != 0x00 & *ptr != 0x05)
{
printf("\n ");
//FILENAME FROM OFFSET 00H TO 07H(8 BYTES)
ptr = buff + i + 0x00;
for(j = 0; j < 8; j ++)
{
printf("%c", *(unsigned char *)ptr);
ptr ++;
}
printf(" ");
//EXTENSION FROM OFFSET 08H TO 0AH(3 BYTES)
ptr = buff + i + 0x08;
for(j = 0; j < 3; j ++)
{
printf("%c", *(unsigned char *)ptr);
ptr ++;
}
printf("\t");
//FILE ATTRIBUTES FROM 0BH(1 BYTE)
//BIT 0: READ ONLY
//BIT 1: HIDDEN FILE
//BIT 2: SYSTEM FILE
//BIT 3: VOLUME LABEL
//BIT 4: DIRECTORY
//BIT 5: ARCHIVE
ptr = buff + i + 0x0B;
temp = *ptr & 1;
if(temp == 1) //TEST BIT 0
printf("R");
temp = *ptr & 2;
if(temp == 2) //TEST BIT 1
printf("H");
temp = *ptr & 4;
if(temp == 4) //TEST BIT 2
printf("S");
temp = *ptr & 8;
if(temp == 8) //TEST BIT 3
printf("V");
temp = *ptr & 16;
if(temp == 16) //TEST BIT 4
printf("D");
temp = *ptr & 32;
if(temp == 32) //TEST BIT 5
printf("A");
printf("\t");
//TIME FROM 16H TO 17H(2 BYTES)
//BITS 15 TO 11 : HOURS
//BITS 10 TO 05 : MINUTES
//BITS 00 TO 04 : 2 SECONDS INCREMENTS
ptr = buff + i + 0x16;
//HOURS
temp = *(int *)ptr;
temp = temp > 11; //SHIFT RIGHT BY 11 BITS
temp = temp & 0x1f; //TO GET BITS 15 TO 11 AND
printf("%.2d", temp);//'AND' THOSE BITS WITH 1
//MINUTES
temp = *(int *)ptr;
temp = temp > 5; //SHIFT RIGHT BY 5 BITS
temp = temp & 0x3f;//TO GET BITS 10 TO 5 AND
printf(":%.2d", temp);//'AND' THOSE BITS WITH 1
//SECONDS
temp = *(int *)ptr;
temp = temp & 0x1F;//AND LAST 5 BITS WITH 1
temp = temp < 1;//SHIFT 1 BIT TOWARDS LEFT
printf(":%.2d", temp);//TO GET ACTUAL TIME
printf(" ");
//DATE FROM 18H TO 19H(2 BYTES)
//BITS 15 TO 09 : YEARS + 1980
//BITS 08 TO 05 : MONTH
//BITS 00 TO 04 : DAY
ptr = buff + i + 0x18;
//DAY
temp = *(int *)ptr;
temp = temp & 0x1F;//AND LAST 5 BITS WITH 1
printf("%.2d", temp);//TO GET ACTUAL DAY
//MONTH
temp = *(int *)ptr;
temp = temp > 5;//SHIFT RIGHT BY 5 BITS
temp = temp & 0x0F;//TO GET BITS 8 TO 5 AND
printf("/%.2d", temp);//'AND' THOSE BITS WITH 1
//YEAR
temp = *(int *)ptr;
temp = temp > 9;//SHIFT RIGHT BY 9 BITS
temp = (temp & 0x7F) + 1980;//TO GET BITS 15 TO 9
printf("/%.4d", temp);//'AND' THOSE BITS WITH 1
//ADD 1980 TO GET ACTUAL YEAR
printf(" ");
//STARTING CLUSTER
ptr = buff + i + 0x1A;
temp = *(int *)ptr;
printf("%.3d(%.3XH)", temp, temp);
printf("\t ");
//FILE SIZE FROM 1CH TO 1F(4 BYTES)
//TO DIRECTLY ACCESS 4 BYTES, USE LONG DATA-TYPE
ptr = buff + i + 0x1C;
temp32 = *(long *)ptr;
printf("%ld", temp32);
}
}
getch();
return 0;
}
/*
OUTPUT OF ROOT DIRECTORY:
Attributes :
R: Read Only H: Hidden S: System File
V: Volume Label D: Directory A: Archive
Name Ext Attr Time Date StCluster Size(Bytes)
TRY1 CPP RHA 15:33:10 13/04/1994 002(002H) 1581
BOOT C 09:26:02 14/08/2012 006(006H) 2193
TIMEIT CPP RH 13:46:48 10/04/1994 011(00BH) 1186
INCLUDE HD 10:58:30 14/08/2012 014(00EH) 0
TEMC EXE A 03:00:00 18/02/1992 390(186H) 43296
*/
4B) AIM : WRITE AN ALP/IN-LINE CODE FOR DISPLAYINGFILE CONTENT USING ROOT DIRECTORY ANDFAT FOR FLOPPY DISK.
#include<stdio.h>
#include<conio.h>
#include<string.h>
#include<process.h>
void main()
{
unsigned char rootbuff[512 * 14], fatbuff[512 * 9];
unsigned char filebuff[512], filename[13];
unsigned char *rootptr, *fnameptr;
int i, j, clusternum, offsetinFAT, FATentry;
int fatchain[100];
clrscr();
//READ ROOT DIRECTORY
asm{
MOV AL, 0x00//DRIVE NUMBER
MOV CX, 14//NO. OF SECTORS TO READ
MOV DX, 19//STARTING SECTOR NO. OF ROOT DIR
LEA BX, rootbuff//LOAD OFFSET OF BUFFER
INT 0x25
JNC READFAT
}
printf("\n Error In Reading Root Directory.");
getch();
exit(0);
READFAT:
//READ FILE ALLOCATION TABLE
asm{
MOV AL, 0x00//DRIVE NUMBER
MOV CX, 9//NO. OF SECTORS TO READ
MOV DX, 1//STARTING SECTOR NO. OF FAT
LEA BX, fatbuff//LOAD OFFSET OF BUFFER
INT 0x25
JNC SUCCESS
}
printf("Error In Reading FAT.");
getch();
exit(0);
SUCCESS:
printf("\n Enter Filename (With Extension) : ");
scanf("%s", &filename);
strupr(filename);//CONVERT FILENAME TO UPPERCASE
//INCREMENT I BY 32 BECAUSE EACH ENTRY IS OF 32 BYTES
for(i = 0; i < 512 * 14; i = i + 32)
{
//POINT rootptr TO FIRST BYTE OF INDIVIDUAL ENTRY(FILE NAME)
rootptr = rootbuff + i + 0x00;
fnameptr = filename;
if(*rootptr != 0xE5 & *rootptr != 0x00 & *rootptr != 0x05)
{
//FIRST MATCH ONLY FILENAME
for(j = 0; j < 8; j ++)
{
if(*rootptr != *fnameptr)
{
if(*rootptr == 0x20 & *fnameptr == '.')
goto namefound;
else
goto nextentry;
}
else
{
rootptr ++;
fnameptr ++;
}
}
namefound:
//NOW MATCH EXTENSION
//POINT rootptr TO 8TH BYTE(EXTENSION)
rootptr = rootbuff + i + 0x08;
if(*fnameptr != '.')
goto nextentry;
//SINCE fnameptr POINTS TO '.', INCREMENT IT
fnameptr ++;
for(j = 0; j < 3; j ++)
{
if(*rootptr != *fnameptr)
{
if(*rootptr == 0x20 & *fnameptr == '\0')
goto extfound;
goto nextentry;
}
else
{
rootptr ++;
fnameptr ++;
}
}
extfound:
printf("\n\n");
//GET THE STARTING CLUSTER NUMBER OF THE FILE
//AND ASSIGN IT TO fatentry(ASSUME IT TO BE FAT ENTRY).
FATentry = *(int *)(rootbuff + i + 0x1A);
i = 0; //INITIALIZE i FOR ACCESSING fatchain ARRAY
do
{
clusternum = (FATentry - 2) + 33;
fatchain[i ++] = clusternum;//STORE THE CLUSTER NUMBER
//READ THE CLUSTER
asm{
MOV AL, 0x00//DRIVE NUMBER
MOV CX, 1//NO. OF SECTORS TO READ
MOV DX, clusternum//STARTING SECTOR NUMBER
LEA BX, filebuff//LOAD OFFSET OF BUFFER
INT 0x25
}
//DISPLAY THE CLUSTER
for(j = 0; j < 512; j ++)
{
if(filebuff[j] != 0x00) //DISPLAY ONLY VALID BYTES
printf("%c", filebuff[j]);
}
//CALCULATE ADDRESS OF NEXT CLUSTER
//IF PREVIOUS FAT ENTRY IS A EVEN NUMBER,
//CONSIDER ONLY LOWER 3 NIBBLES OF NEW FAT ENTRY
if(FATentry % 2 == 0)
{
offsetinFAT = FATentry * 1.5;
FATentry = *(int *)(fatbuff + offsetinFAT);
//NEW FAT ENTRY(CHAIN)
FATentry = FATentry & 0x0FFF;
if(FATentry == 0x0FFF)
goto finish;
}
//IF PREVIOUS FAT ENTRY IS ODD NUMBER,
//CONSIDER ONLY UPPER 3 NIBBLES OF NEW FAT ENTRY
else
{
offsetinFAT = FATentry * 1.5;
FATentry = *(int *)(fatbuff + offsetinFAT);
//NEW FAT ENTRY(CHAIN)
FATentry = (FATentry > 4) & 0x0FFF;
if(FATentry == 0x0FFF)
goto finish;
}
getch();
}while(1);
finish:
//FOR DISPLAYING FATCHAIN
getch();
printf("\n\n FAT CHAIN : ");
for(j = 0; j < i; j ++)
printf(" %d", fatchain[j]);
goto exit;
}
nextentry:
}
printf("\n File Not Found.");
exit:
getch();
}
/*
OUTPUT OF FAT:
Enter Filename (With Extension) : fatinfo.txt
The file allocation table (FAT) is divided into fields that correspond
directly to the assignable clusters on the disk. These fields are 12 bits
in MS-DOS versions 1 and 2 and may be either 12 bits or 16 bits in
versions 3.0 and later, depending on the size of the medium (12 bits if
the disk contains fewer than 4087 clusters, 16 bits otherwise).
The first two fields in the FAT are always reserved. On IBM-compatible
media, the first 8 bits of the first reserved FAT entry contain a copy of
the media descriptor byte, which is also found in the BPB in the boot
sector. The second, third, and (if applicable) fourth bytes, which
constitute the remainder of the first two reserved FAT fields, always
contain 0FF Interpreting the File Allocation Table
If the FAT has 12-bit entries, use the following procedure:
1. Use the directory entry to find the starting cluster of the file in
question.
2. Multiply the cluster number by 1.5.
3. Use the integral part of the product as the offset into the FAT and
move the word at that offset into a register. Remember that a FAT
position can span a physical disk-sector boundary.
4. If the product is a whole number, AND the register with 0FFFH.
5. Otherwise, "logical shift" the register right 4 bits.
6. If the result is a value from 0FF8H through 0FFFH, the file has no
more clusters. Otherwise, the result is the number of the next cluster
in the file.
To convert cluster numbers to logical sectors, subtract 2, multiply the
result by the number of sectors per cluster, and add the logical-sector
number of the beginning of the data area (this can be calculated from the
information in the BPB).
FAT CHAIN : 33 34 35 36
*/
5) AIM : WRITE AN INSTALLABLE DOS DEVICE DRIVER FOR PRINTERS.
.MODEL TINY
.CODE
ORG 0000H
START:
DRIVER_HEADER: ;DEFINITION OF DRIVER HEADER STRUCTURE
BACKLINK DD -1 ;LINK TO NEXT DRIVER
ATTRIBUTE DW 8000H ;DEVICE ATTRIBUTE WORD(HERE CHARACTER DEVICE)
STRAT DW STRATEGY_ROUTINE ;STRATEGY ENTRY POINT, OFFSET
INTR DW INTERRUPT_ROUTINE ;INTERRUPT ENTRY POINT, OFFSET
LOGICNAME DB 'PRINTER1' ;PRINTER DRIVER LOGICAL NAME
REQ_HEADER_OFFSET DW ? ;REQUEST HEADER OFFSET
REQ_HEADER_SEGMENT DW ? ;REQUEST HEADER SEGMENT
MESSAGE DB 10, 13, 'DEVICE DRIVER INITIALIZED...', 10, 13, 10, 13, '$'
;MS-DOS CALLS THE STRATEGY ROUTINE (STRAT) FOR THE DEVICE
;WHEN THE DRIVER IS FIRST LOADED AND INSTALLED, AND AGAIN
;WHENEVER AN APPLICATION PROGRAM ISSUES AN I/O REQUEST FOR
;THE DEVICE. MS-DOS PASSES THE STRATEGY ROUTINE A DOUBLE-WORD
;POINTER TO A DATA STRUCTURE CALLED A REQUEST HEADER.
;THIS STRUCTURE CONTAINS INFORMATION ABOUT THE TYPE OF
;OPERATION TO BE PERFORMED.
STRATEGYROUTINE:
STRATEGY_ROUTINE PROC FAR
MOV REQ_HEADER_OFFSET, BX ;STORE ADDRESS OF REQUEST HEADER OFFSET
MOV REQ_HEADER_SEGMENT, ES ;STORE ADDRESS OF REQUEST HEADER SEGMENT
RETF
STRATEGY_ROUTINE ENDP
;THE LAST AND MOST COMPLEX PART OF A DEVICE DRIVER IS THE INTERRUPT
;ROUTINE (INTR), WHICH MS-DOS CALLS IMMEDIATELY AFTER IT CALLS THE
;STRATEGY ROUTINE. IT IMPLEMENTS THE DEVICE DRIVER PROPER; IT PERFORMS
;THE ACTUAL I/O OPERATIONS, BASED ON THE INFORMATION PASSED IN THE
;REQUEST HEADER.
;THE INTERRUPT ROUTINE CONSISTS OF THE FOLLOWING ELEMENTS:
;1) COMMAND-CODE ROUTINE
;2) A CENTRALIZED ENTRY POINT THAT SAVES ALL AFFECTED REGISTERS, EXTRACTS