![]() |
| |||
| ||||
Programming and access to ports
Firstly some procedure is due to have to be able to determine which is the base address of the port.
As it were said previously, the parallel port has its base address in two-way traffic consecutive of memory. Then the content of these directions of memory is due to read, in order to determine if a port exists and which is its direction.
Under MSDOS the external command can be used debug.exe in the following way:
Exec the command: debug.exe, soon appears the symbol -
Write after this sign d 40:0008
Depending on the equipment appears the state of the memory of the following form: (the data can vary)
0040:0000 ______________________78 03 00 00 00 00 00 00
The direction of the port is in inverted form (78 03), then the direction is:
0378 in hexadecimal. It is possible to make notice that this direction can be different in other PC.
(Write Q to leave debug.exe)
In Turbo Pascal with assembler
Program buscar_base;
use crt;
Var bases: Word;
begin
asm
mov ax, 0040h {Colocar 0040h in reg. Ax}
mov is, ax { the segment is with the value of ax}
mov ax, es: [if] { in ax the content of the memory direction [0040: 0008]}
mov bases, ax; {update the bases variable with the value of ax}
end;
writeln (“the base address in decimal is: ”, bases);
end.
Program buscar_base;
use crt;
Var bases: Word;
Begin
base: =memW [$0040: $0008];
writeln (“the base address in decimal is: ”, it bases);
end.
This analyzer is used to determine the base address of the port and in addition he allows to visualize the content of the records in continuous form and binary format and hexadecimal.
This program compiles with Turbo Pascal.
{File analisis.pas}
{Analyzing of state of the Parallel port}
{Author: Juan Carlos Galarza Roca}
{December of 1997}
{Version: 1.0}
Program analisis_PP;
use crt dos, cadena, utiles;
var
dir_base,
dir_estado,
dir_control: Word;
puntero_int_1C: Pointer;
tick: Integer;
sw_m_t: Integer;
{$F+, s, W}
procedure manejador; interrupt;
{This manejador is used to temporizar the unfolding of
exploration indicator, so that the reading becomes of
data and simultaneously the indicator unfolds}
var
a,
b,
x,
Y
: Integer;begin
if sw_m_t=0 then begin;
{sw_m_t is the flag of the manejador of tasks
This flag is updated by the program
main
}
x: =whereX;
and: =whereY;
{keeps the position from the cursor in the screen}
tick: =tick+1;
{The variable tick is increased every 18.20677500572 seconds}
a: =6;
b: =3;
textcolor (7);
gotoxy (39+a, b); write (“Exploring… ”);
textcolor (2);
case of
13: begin gotoxy (60+a, b); write (“>”);
gotoxy (52+a, b); write (“<”); end;
15: begin gotoxy (60+a, b); write (“- >”);
gotoxy (52+a, b); write (“<-”); end;
17: begin gotoxy (60+a, b); write (“- >”);
gotoxy (52+a, b); write (“< -”); end;
19: begin gotoxy (60+a, b); write (“- >”);
gotoxy (52+a, b); write (“< -”); end;
21: begin gotoxy (60+a, b); write (“- >”);
gotoxy (52+a, b); write (“< -”); end;
23: begin gotoxy (60+a, b); write (“- >”);
gotoxy (52+a, b); write (“< -”); end;
25: begin gotoxy (60+a, b); write (“< -”);
gotoxy (52+a, b); write (“<”); end;
27: begin gotoxy (60+a, b); write (“< -”);
gotoxy (52+a, b); write (“- >”); end;
29: begin gotoxy (60+a, b); write (“< -”);
gotoxy (52+a, b); write (“- >”); end;
31: begin gotoxy (60+a, b); write (“< -”);
gotoxy (52+a, b); write (“- >”); end;
33: begin gotoxy (60+a, b); write (“< -”);
gotoxy (52+a, b); write (“- >”); end;
34: tick: =13;
end;
gotoxy (x, and);
{Devolver the original position of the cursor}
end;
end;
{$F-, S+}
begin
cursor_off;
tick: =0;
{Colocar the manejador of tasks}
GetIntVec ($1C, puntero_int_1C);
SetIntVec ($1C, Addr (manejador));
clrscr;
it dir_base: =memW [$0040: 0008];
dir_estado: =dir_base+1;
dir_control: =dir_base+2;
textcolor (2);
gotoxy (23,2); writeln (“Analyzing of the Parallel port”);
textcolor (9);
gotoxy (8,4); writeln (“Directions: ”);
textcolor (9);
gotoxy (10,5); writeln (“Data: ”, dec_a_hexa (it dir_base), “(h)”);
gotoxy (10,6); writeln (“Been: ”, dec_a_hexa (dir_estado), “(h)”);
gotoxy (10,7); writeln (“Control: ”, dec_a_hexa (dir_control), “(h)”);
{Main repetivo Cycle}
repeat
sw_m_t: =1;
textcolor (9);
gotoxy (34,4); writeln (“Been: ”);
gotoxy (36,5); write (“Data: ”, port [dir_base]: 3, “(d)”);
dec_bin (port [dir_base]); write (“(b)”);
gotoxy (36,6); write (“Been: ”, port [dir_estado]: 3, “(d)”);
dec_bin (port [dir_estado]); write (“(b)”);
gotoxy (36,7); write (“Control: ”, port [dir_control]: 3, “(d)”);
dec_bin (port [dir_control]); write (“(b)”);
textcolor (7);
gotoxy (9,9); write (“Registry of Data”);
gotoxy (25,10); write (“Pins 9 8 7 6 5 4 3 2”);
gotoxy (25,11); write (“Name D7 D6 D5 D4 D3 D2 D1 D0”);
textcolor (2);
gotoxy (25,12); write (“Value”); dec_bin2 (port [dir_base]);
textcolor (7);
gotoxy (9,14); write (“Registry of State”);
gotoxy (25,15); write (“15 Pins 11 10 12 13 ** ** **”);
gotoxy (25,16); write (“Name - S7 S6 S5 S4 S3 ** ** **”);
textcolor (2);
gotoxy (25,17); write (“Value”); dec_bin2 (port [dir_estado]);
textcolor (7);
gotoxy (9,19); write (“Registry of Control”);
gotoxy (25,20); write (“Pins ** ** ** ** 17 16 14 1”);
gotoxy (25,21); write (“Name ** ** ** ** - C3 C2 - C1 - C0”);
textcolor (2);
gotoxy (25,22); write (“Value”); dec_bin2 (port [dir_control]);
textcolor (2);
gotoxy (8,24); write (“[Copyrigth (c) 1997 by JCGR Soft <pparalelo@hotmail.com>]”);
textcolor (7);
sw_m_t: =0;
delay (100);
until keypressed;
cursor_on;
{Manejador Restaurar of tasks}
SetIntVec ($1C, puntero_int_1C);
end.
Shipment and reading of data of the port
Shipment from data to the port
The parallel port can be used like a direct communication with the PC, in this way is possible to develop applications in time-real that need a fast response time.
The access is made writing a byte (8 bits) in certain record. This byte must talk about to each one of the bits of the record. This means that the byte is due to define to write in binary system.
For example if we want to write in the data recoprd the bit D0 and the bit then D2 the byte is:
0 | 0 | 0 | 0 | 0 | 1 | 0 | 1 | = 5 In decimal |
D7 | D6 | D5 | D4 | D3 | D2 | D1 | D0 |
data record |
Soon, one is due to write 5 in the data record (base address):
Notes:
dir_base and dir_estado it is of Word type, and data is of type byte.
In Turbo Pascal
Port [dir_base]: =5;
In C
Outportb (it dir_base, 5);
In assembler
mov dx, dir_base {Direccionar in dx the base address}
mov to, 5 {Colocar in ² to ² number 5}
out dx, to {Enviar to the port}
The reading of data is made accesando a byte of the certain registry. When doing the reading is due to turn the binary byte to determining he or the bits that interest. Notice that only the state registry is due to read, that is, the direction base+1.
In Turbo Pascal
Var data: byte;
data: =Port [dir_estado];
In C
unsigned int data;
dato=inportb (dir_estado);
In assembler
mov dx, dir_estado {Direccionar dx with the registry of state of the port}
in a, dx {Leer of the port. In the registry ² to ² is the read data}
For example, if the read data is equal to 96, it means that the bits S5 and S6 are active (they have a high level, a 1).
0 | 1 | 1 | 0 | 0 | 0 | 0 | 0 | = 96 In decimal |
S7 | S6 | S5 | S4 | S3 | S2 | S1 | S0 | Registry of state |
Masking As much in the shipment as reception of binary data, operations at level of bits are made. These operations allow to isolate one more bits. This process denominates
masking. For example, to know if certain bit that has been ***reflxed mng of the state registry it is in a high level (1 logical one) is possible to be conducted the operation “and” logic (AND) of the reading with a value that turns out to elevate 2 to the position that occupies that bit in the byte, and soon to make the comparison. If the bit that is desired to know is bit 5, then the operation is: Masc: =2^5=32 (Byte_leido AND masc) In the case that bit 5 is in a high level: Byte_leido 0 1 1 0 0 0 0 0 96 S7 S6 S5 S4 S3 S2 S1 S0 Position AND 0 0 1 0 0 0 0 0 Mask = 32 It is 0 0 1 0 0 0 0 0 32= mask In the case that bit 5 is not in a high level: Byte_leido 0 1 0 1 0 0 0 0 80 S7 S6 S5 S4 S3 S2 S1 S0 Position AND 0 0 1 0 0 0 0 0 Mask = 32 It is 0 0 0 0 0 0 0 0 0 <> mask
If bit 5 is 1, then the result is 16, or equal to masc.
Making the comparison:
If (Byte_leido AND masc) = masc then
Beginning
/* the actions to make when 4to bit is 1 *
Aim
If bit 5 is 0, then the result always is 0, which is different from masc.
In case it is desired to make the camouflage of more of a bit, it is made the sum the values.
Ej. Mask for bit 5 and the 7
Masc= 2^5+2^7=160
Questions? pparalelo@hotmail.com