Has anyone yet made a routine...?

I

Iron Phoenix

... or driver, or whatever... to treat a parallel port as a synchonous
serial port?

perhaps using the system clock (counted-down appropriately for the bps
rate desired) to generate the TX clock, setting another bit on another
pin for the transmit data, reading the receive data / clock from yet
other pins...

I've got a rather long and involved program used for testing of NAS
(National Air Space) control systems. It works, but the problem is
that the test platform is ASCII and asynch serial while the computers
under test are EBCDIC and synch serial (2400bps).

Right now, I'm using a mini with a real kludge of a conversion routine
to translate. Problem? The mini is hardly portable, weighing in at
some 120 kg. I need the ability to test to be portable, preferably on
a reasonably modern laptop. I have not yet seen a laptop with synch
serial ability. Another problem? The conversion routine was written
20 years (?!) ago, and no one still around has a clue ... Another
problem? The mini in question is unique, and dying.

I have some sample code that uses the parallel as synch serial (and it
works!) but it must be run under DOS (and my laptop is WinXP) - no
flavor of windows will allow it to operate, as it wants direct access
to hardware, and redirects IRQ8.

Oh, is there a more speed-efficient way of doing ASCII to EBCDIC
conversion than a table look-up? Not concerned about time going the
other way (EBCDIC to ASCII), but I need *speed* going from ASCII to
EBCDIC...

Any ideas, assistance, or sample code would be greatly appreciated!

Thanks!

Kris
RATCF DAIR Engineer

PS - I am a HARDWARE engineer. I know enough C/C++ to follow along,
modify, and write fairly simple code. But drivers are Magic... :>
 
J

Jack Klein

.. or driver, or whatever... to treat a parallel port as a synchonous
serial port?

[snip]

It's quite possible that someone has, but it's off-topic here.
Standard C does not define or support any access to any hardware
devices whatsoever. All input and output is defined in terms of FILE
* streams.

You need to ask in a support group for your particular
compiler/operating system combination to see what particular platform
specific extensions it might provide for doing this sort of thing.

It is not a C language issue.

--
Jack Klein
Home: http://JK-Technology.Com
FAQs for
comp.lang.c http://www.eskimo.com/~scs/C-faq/top.html
comp.lang.c++ http://www.parashift.com/c++-faq-lite/
alt.comp.lang.learn.c-c++ ftp://snurse-l.org/pub/acllc-c++/faq
 
C

CBFalconer

Iron said:
.. or driver, or whatever... to treat a parallel port as a
synchonous serial port?
.... snip ...

PS - I am a HARDWARE engineer. I know enough C/C++ to follow
along, modify, and write fairly simple code. But drivers are
Magic... :>

This is not a C language question. Maybe comp.arch.embedded would
be more suitable.
 
I

Iron Phoenix

Jack Klein said:
.. or driver, or whatever... to treat a parallel port as a synchonous
serial port?

[snip]

It's quite possible that someone has, but it's off-topic here.
Standard C does not define or support any access to any hardware
devices whatsoever. All input and output is defined in terms of FILE
* streams.

You need to ask in a support group for your particular
compiler/operating system combination to see what particular platform
specific extensions it might provide for doing this sort of thing.

It is not a C language issue.

I disagree.

Even if one disallows writing device drivers in C (even though many
are - tell any Unix/Linux guru otherwise and see what he says...), the
end result of my original question is still well within the abilities
of the language.

On a DOS-based Intel machine, with the appropriate <include xxx.h>
line(s), all part of the ANSI definition, and without using any inline
assembly:

ANSI C allows me *direct* access to the hardware clock:

#define BIOS_TIME_SERVICES_INTERRUPT 0x1a
#define BIOS_GET_RTC_TIME_SERVICE 2

int hour_high,
hour_low,
minute_high,
minute_low;

void get_bios_time(void)
{
int hour,minute;
regs.h.ah=BIOS_GET_RTC_TIME_SERVICE;
int86(BIOS_TIME_SERVICES_INTERRUPT,&regs,&regs);
hour=BcdToBinary(regs.h.ch);
minute=BcdToBinary(regs.h.cl);
hour_high=(hour/10);
hour_low=(hour%10);
minute_high=(minute/10);
minute_low=(minute%10);
}
unsigned char BcdToBinary(unsigned char val)
{
return (val/16)*10+val%16;
}


ANSI C allows me to *directly* access the printer port:

#define BIOS_DATA_PAGE 0x0040
#define LPT1 0x0008
#define MAKELP(sel,off) ((void _far*)MAKELONG((off),(sel)))
#define MAKELONG(low,high) ((long)(((unsigned short int)(low))|
(((unsigned long int)((unsigned short int)
(high)))<<16)))
int _far *pPrintPort;
void main(void)
{
pPrintPort=MAKELP(BIOS_DATA_PAGE,LPT1);
outport=*pPrintPort;
inport=outport+1;
if(outport==0)
{
printf("No Printer Port is installed!");
getch();
exit(0);
}
/* do what you want with it with inp() and outp() now... */
}


ANSI C allows me to turn interrupts off (and back on):

_disable();
_enable();



ANSI C allows me see (and, God forfend!) even change interrupt
vectors:

#define TIMER_INTERRUPT 0x08
oldTimerInterrupt=_dos_getvect(TIMER_INTERRUPT);
_dos_setvect(TIMER_INTERRUPT,xmit_clock_out);


Once "outport" is defined as above, ANSI C allows me to write
individual data bits to that port:

outp(outport,databit);


I can even change the speed of the opsys clock! Magic? No, just ANSI
C.

#define TIMER_COUNT_REGISTER 0x40
#define CONTROL_BYTE_REG 0x43
#define TIMER_INTERRUPT 0x08

....

outp(CONTROL_BYTE_REG,54);
outp(TIMER_COUNT_REGISTER,125); /* use the timer to gen a 2400 hz */
outp(TIMER_COUNT_REGISTER,0); /* squarewave */

....

And then I can use that altered clock to generate my very own
synchronous serial port on the parallel port! Miracle? No. ANSI C.

#pragma check_stack(off)
void _cdecl _interrupt _far xmit_clock_out()
{
static int number_of_zeros,
output_char=0,
shift_out=0,
divide=0,
idle=0,
parity_bit=0,
old_direction=3,
xmit_data[60],
counter,
sync_flag=0,
make_xmit_data=0;
static double delay=0;
int xmit_msg_number,
data_on_port=0,
sample=1;

if((++divide)%2)
{
if(clockout==1)
{
data_on_port=inp(outport);
outp(outport,(data_on_port&254));
clockout=0;

.... etc - not pasting the entire 360-line long func here ...


Once "inport" is defined as above, ANSI C allows me to read individual
data bits from that port:

#pragma check_stack(off)
int in_port_SR_bit4(void)
{
int rtrn_value;
if((inp(inport)&16)==16)
rtrn_value=1;
else
rtrn_value=0;
return(rtrn_value);
}
#pragma check_stack(on)

#pragma check_stack(off)
int in_port_SR_bit5(void)
{
int rtrn_value;
if((inp(inport)&32)==32)
rtrn_value=1;
else
rtrn_value=0;
return(rtrn_value);
}
#pragma check_stack(on)

All code snippets above are from a functioning program, written for
and compiled under Microsoft C 6.0 (c.1990), with the "MS Extensions"
disabled. Note I did *not* say "Visual" - This is not windows-based.
Note I also did not say C++ - Just straight ANSI C.

I am not a professional C programmer, though I know enough to follow
most of what someone else is talking about, and write what you would
likely consider simple routines. I also know enough to challenge when
someone tells me something that I know to be incorrect.

This message was also read by a professional C/C++ programmer who
codes for the National Air Space control systems, and has for as long
as that system has used the language. Upon reading the statement that
"Standard C does not define or support any access to any hardware
devices whatsoever. All input and output is defined in terms of FILE
* streams", his reaction was 3 minutes of laughter liberally
intermingled with the colloquialism for which "BS" is a common
abbreviation. Once he stopped laughing long enough to speak clearly,
he clarified that the above statement may be technically correct (as
some details are opsys specific - ie, what is the clock interrupt?
where is the printer port?, etc) but is certainly not accurate on a
*practical* level by anyone literate in the language.

Accordingly, I consider your statement to be ... ah... well, not
well-considered.

"I don't know" and "I don't know how" are acceptable responses. The
above, on the other hand... when I ask my kids where their homework
is, I don't accept "It's cartoon time, Dad. The clock does not support
thinking at the moment. Why don't you ask Mom?"

Kris
 
J

Joona I Palaste

Iron Phoenix said:
Jack Klein said:
.. or driver, or whatever... to treat a parallel port as a synchonous
serial port?

[snip]

It's quite possible that someone has, but it's off-topic here.
Standard C does not define or support any access to any hardware
devices whatsoever. All input and output is defined in terms of FILE
* streams.

You need to ask in a support group for your particular
compiler/operating system combination to see what particular platform
specific extensions it might provide for doing this sort of thing.

It is not a C language issue.
I disagree.

I disagree.
Even if one disallows writing device drivers in C (even though many
are - tell any Unix/Linux guru otherwise and see what he says...), the
end result of my original question is still well within the abilities
of the language.
On a DOS-based Intel machine, with the appropriate <include xxx.h>
line(s), all part of the ANSI definition, and without using any inline
assembly:
ANSI C allows me *direct* access to the hardware clock:

No it doesn't.
#define BIOS_TIME_SERVICES_INTERRUPT 0x1a
#define BIOS_GET_RTC_TIME_SERVICE 2

Which part of the ANSI C standard guarantees 0x1a is a valid interrupt
value, is readable by your program, and contains sensible data? Hmm?
Which part of the ANSI C standard even mentions interrupts?
int hour_high,
hour_low,
minute_high,
minute_low;
void get_bios_time(void)
{
int hour,minute;
regs.h.ah=BIOS_GET_RTC_TIME_SERVICE;

What is regs? You don't seem to have it defined anywhere.
int86(BIOS_TIME_SERVICES_INTERRUPT,&regs,&regs);

Umm... since when was int86() an ANSI C function?
hour=BcdToBinary(regs.h.ch);
minute=BcdToBinary(regs.h.cl);
hour_high=(hour/10);
hour_low=(hour%10);
minute_high=(minute/10);
minute_low=(minute%10);
}
unsigned char BcdToBinary(unsigned char val)
{
return (val/16)*10+val%16;
}

ANSI C allows me to *directly* access the printer port:
#define BIOS_DATA_PAGE 0x0040
#define LPT1 0x0008
#define MAKELP(sel,off) ((void _far*)MAKELONG((off),(sel)))

What the heck is _far?
#define MAKELONG(low,high) ((long)(((unsigned short int)(low))|
(((unsigned long int)((unsigned short int)
(high)))<<16)))

(Snip further MS-DOS-specific code)

You apparently think that MS-DOS-specific data structures and functions
are ANSI standard C. If so, then please show us how you compile your
example programs on a UNIX box. Or for more challenge, do it on a
MicroVAX.
Honestly, are you really this stupid or just trolling?
 
M

Mike Wahler

Iron Phoenix said:
.. or driver, or whatever... to treat a parallel port as a synchonous
serial port?

[snip]

It's quite possible that someone has, but it's off-topic here.
Standard C does not define or support any access to any hardware
devices whatsoever. All input and output is defined in terms of FILE
* streams.

You need to ask in a support group for your particular
compiler/operating system combination to see what particular platform
specific extensions it might provide for doing this sort of thing.

It is not a C language issue.

I disagree.[/QUOTE]

It is of course your prerogative whether to agree or disagree
with proven facts.
Even if one disallows writing device drivers in C


This cannot be done with standard C. It can be done with
extensions (which are not part of the standard language),
however.
(even though many
are - tell any Unix/Linux guru otherwise and see what he says...),


A true 'guru' will tell you that it cannot be done with only
the standard language.
the
end result of my original question is still well within the abilities
of the language.

Not the language discussed here, which is standard C, defined
by ISO/IEC 9899.
On a DOS-based Intel machine, with the appropriate <include xxx.h>
line(s), all part of the ANSI definition, and without using any inline
assembly:

The platform is irrelevant to a platform-independent langauge,
which is what C is.
ANSI C allows me *direct* access to the hardware clock:

No it does not. It doesn't even require that the host system
have a clock at all.

[snip code]

That code is *not* ANSI C.
All code snippets above are from a functioning program,

Many functioning programs are written using extensions to
the standard language. The extensions prevent them from
being standard C programs.
written for
and compiled under Microsoft C 6.0 (c.1990), with the "MS Extensions"
disabled. Note I did *not* say "Visual" - This is not windows-based.
Note I also did not say C++ - Just straight ANSI C.

What you posted is *not* ANSI C.
I am not a professional C programmer,

Surprise, surprise!
though I know enough to follow
most of what someone else is talking about,

But apparently not enough about C.
and write what you would
likely consider simple routines. I also know enough to challenge when
someone tells me something that I know to be incorrect.

But how do you know?
This message was also read by a professional C/C++

There is no such thing as a language called 'C/C++'. There is
C, and there is C++, two separate, distinct languages.
programmer who
codes for the National Air Space control systems,
Hmmm.

and has for as long
as that system has used the language. Upon reading the statement that
"Standard C does not define or support any access to any hardware
devices whatsoever. All input and output is defined in terms of FILE
* streams", his reaction was 3 minutes of laughter liberally
intermingled with the colloquialism for which "BS" is a common
abbreviation.


Be afraid, very afraid. Someone who doesn't understand this
fundamental issue is writing space control systems? Be afraid.
Once he stopped laughing long enough to speak clearly,
he clarified that the above statement may be technically correct

It *is* correct.
(as
some details are opsys specific


ANSI C, by definition, is platform-independent. So the existence
of any platform specific entities in a program prevent it from
being a standard C program.
- ie, what is the clock interrupt?

The language defines no concept of 'interrupt' or 'clock interrupt'
at all. Any introduction of such items into a program prevent it
from being a standard C program.

where is the printer port?, etc)


The language defines no concept of 'printer' or 'printer port',
or any particular hardware devices (or drivers for them) at all.
Any introduction of such items into a program prevent it from
being a standard C program.

Has it never occurred to you that some (actually the vast majority)
of computer systems which can host ANSI C programs have no printer
at all?
but is certainly not accurate on a
*practical* level by anyone literate in the language.

It is exactly accurate. It is you who is illiterate with C.

Why not obtain a textbook or two and actually *learn*, rather
than making a fool out of yourself here?
Accordingly, I consider your statement to be ... ah... well, not
well-considered.

It is exactly accurate, and supported by the ANSI standard itself.
Or would you care to quote from it any items which support your position?
"I don't know" and "I don't know how" are acceptable responses.

But Jack *does* know. Jack knows more about C than most.
The
above, on the other hand... when I ask my kids where their homework
is, I don't accept "It's cartoon time, Dad. The clock does not support
thinking at the moment. Why don't you ask Mom?"

Non sequitur. Try a course in logic.

-Mike
 
M

Morris Dovey

Kris said:
... or driver, or whatever... to treat a parallel port as a
synchonous serial port?
<snip

Right now, I'm using a mini with a real kludge of a conversion
routine to translate. Problem? The mini is hardly portable,
weighing in at some 120 kg. I need the ability to test to be
portable, preferably on a reasonably modern laptop.

Kris...

This is not a C language issue; but rather a how-to issue. In the
interest of providing a constructive response and shortening this
off-topic thread as much as possible, I suggest doing a Google
search for "dlportio", a package which should be able to handle
2400bps.

The table approach for translation will probably work - just
translate each character immediately before sending:

char message = "Hello, World", *msg = message;
:
:
while (*msg) send_sync(ebcdic[*(msg++)]);

By portable, I assume you mean the computer. Your code solution
will not be portable to other platforms.

Good luck.
 
R

Richard Heathfield

Iron said:
ANSI C allows me *direct* access to the hardware clock:
Really?


#define BIOS_TIME_SERVICES_INTERRUPT 0x1a
#define BIOS_GET_RTC_TIME_SERVICE 2

int hour_high,
hour_low,
minute_high,
minute_low;

void get_bios_time(void)
{
int hour,minute;
regs.h.ah=BIOS_GET_RTC_TIME_SERVICE;
int86(BIOS_TIME_SERVICES_INTERRUPT,&regs,&regs);
hour=BcdToBinary(regs.h.ch);
minute=BcdToBinary(regs.h.cl);
hour_high=(hour/10);
hour_low=(hour%10);
minute_high=(minute/10);
minute_low=(minute%10);
}
unsigned char BcdToBinary(unsigned char val)
{
return (val/16)*10+val%16;
}

rjh@tux:~/scratch> cat foo.c
#define BIOS_TIME_SERVICES_INTERRUPT 0x1a
#define BIOS_GET_RTC_TIME_SERVICE 2

int hour_high,
hour_low,
minute_high,
minute_low;

void get_bios_time(void)
{
int hour,minute;
regs.h.ah=BIOS_GET_RTC_TIME_SERVICE;
int86(BIOS_TIME_SERVICES_INTERRUPT,&regs,&regs);
hour=BcdToBinary(regs.h.ch);
minute=BcdToBinary(regs.h.cl);
hour_high=(hour/10);
hour_low=(hour%10);
minute_high=(minute/10);
minute_low=(minute%10);
}

rjh@tux:~/scratch> gcc -W -Wall -ansi -pedantic -O2 -c -o foo.o foo.c
foo.c: In function `get_bios_time':
foo.c:12: `regs' undeclared (first use in this function)
foo.c:12: (Each undeclared identifier is reported only once
foo.c:12: for each function it appears in.)
foo.c:13: warning: implicit declaration of function `int86'
foo.c:14: warning: implicit declaration of function `BcdToBinary'

The compiler refused to provide an object file.

So much for that.
 
R

Robert Stankowic

Iron Phoenix said:
.. or driver, or whatever... to treat a parallel port as a synchonous
serial port?
[.....]
[OT] a google search for "tvicport" may help [/OT]
Robert
 
D

Dan Pop

In said:
Is it possible to argue that it *allows* it, but doesn't *support* it?

Yes, most definitely: once you invoke undefined behaviour, ANSI C
certainly allows access to the hardware clock, without guaranteeing
anything at all.

The typical invocation of undefined behaviour in this case is by
including a non-standard header you don't provide and by calling a
non-standard function you don't define.

Dan
 
J

Joona I Palaste

Is it possible to argue that it *allows* it, but doesn't *support* it?

Hmm, you could say that. But Iron Phoenix here is claiming that ANSI C
supports the whole of MS-DOS. Implementors must be thinking that ANSI
(or ISO) is crazy for making them implement an MS-DOS emulation layer,
when they could have implementations producing commercial-quality code
without it... =)
 
P

Programmer Dude

Dan said:
The typical invocation of undefined behaviour in this case is by
including a non-standard header you don't provide and by calling a
non-standard function you don't define.

Using a compiler you didn't write while working in an office you
didn't build! (-:
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,539
Members
45,024
Latest member
ARDU_PROgrammER

Latest Threads

Top