Subject: Re: How to port inportb/outportb to NetBSD ???
To: Brian Stark <bstark@uswest.net>
From: Grant Stockly <gussie@stockly.com>
List: port-i386
Date: 11/26/1999 19:14:19
You need to set access for the parallel port first...

Here is a sample program.  I created it with help of other port-i386 users
a few months back.

Grant

#include <stdio.h>
#include <err.h>

#include <sys/types.h>

#include <machine/pio.h>
#include <machine/sysarch.h>

#define	DATA	0x378
#define	STATUS	0x378+1
#define	CONTROL	0x378+2

#define	BUSYo	0x80
#define	STROBEo	0x01
#define	BUSYa	0x7F
#define	STROBEa	0xFE

#define mp3_second 128000
#define file_second mp3_second


static inline void
setaccess(u_long * map, u_int bit, int allow)
{
	u_int           word;
	u_int           shift;
	u_long          mask;

	word = bit / 32;
	shift = bit - (word * 32);

	mask = 0x000000001 << shift;
	if (allow)
		map[word] &= ~mask;
	else
		map[word] |= mask;
}

static void
dumpmap(u_long * map)
{
	u_int           i;

	for (i = 0; i < 32; i++)
		printf("%2u: %08x\n", i, map[i]);
}

int
main(int argc, char **argv)
{
	u_long          iomap[32];
	u_long		i;

        FILE    *mpeg_file;
        u_long  filesize;
        u_long  curread;
        char    mpeg_storage[file_second];
        int     stop;
        char    *namefile;


        if( (mpeg_file = fopen("./sample.file", "rb")) == NULL) {
                printf("Error reading %s!\n", namefile);
                exit(1);
        };

        fseek(mpeg_file, 0, SEEK_SET);

        filesize = 0;
        curread = 0;
	stop = 0;


	if (i386_get_ioperm(iomap) == -1)
		errx(1, "i386_get_ioperm failed");


	setaccess(iomap, CONTROL, 1);
	setaccess(iomap, STATUS, 1);
	setaccess(iomap, DATA, 1);

	if (i386_set_ioperm(iomap) == -1)
		errx(1, "i386_set_ioperm failed");

	do {
		curread = fread(mpeg_storage, 1, file_second, mpeg_file);
		filesize = filesize + curread;
		printf("Played %d bytes\n", filesize);
		if ( curread < file_second ) {
			stop = 1;
		};

		i = 0;

		do {
			while((inb(STATUS) & BUSYo) == BUSYo);
			outb(DATA, mpeg_storage[i]);
			outb(CONTROL, (inb(CONTROL) | STROBEo));
			while((inb(STATUS) & BUSYo) != BUSYo);
			outb(CONTROL, (inb(CONTROL) & STROBEa));
			i++;
		} while( i != curread ) ;

	} while( stop != 1 );

	return(1);


};




>Hello,
>
>I'm having some trouble porting some code from a MS-DOS system to NetBSD
>and I hope someone can tell me what I might be doing wrong.
>
>I wrote some code using Borland C++ 3.10 on a to NetBSD and my code made
>use of the following Borland functions for reading and writing ports:
>
>  unsigned      inport  (unsigned portid);
>  unsigned char inportb (unsigned portid);
>  void          outport (unsigned portid, unsigned      value);
>  void          outportb(unsigned portid, unsigned char value);
>
>I found the header file /usr/include/machine/pio.h, and it looks like
>it contains some definitions that will work for me (inw, inb, outw, outb),
>so I modified my code to be like this:
>
>#include <machine/types.h>
>#include <machine/pio.h>
>
>/* This function will read a 16-bit word */
>u_int16_t inport (int portid)
>{
>  return (inw(portid));
>}
>
>/* This function will read a 8-bit byte */
>u_int8_t inportb (int portid)
>{
>  return (inb(portid));
>}
>
>/* This function will write a 16-bit word */
>void outport(int portid, u_int16_t value)
>{
>  outw(portid,value);
>}
>
>/* This function will write a 8-bit word */
>void outportb(int portid, u_int8_t value)
>{
>  outb(portid,value);
>}
>
>int DetectESP(int EIO)
>/* Look for a Hayes ESP signature at port EIO */
>{
>  if (0xF3 == inportb(EIO))
>    return 1;
>  else
>    return 0;
>}
>
>
>But, when I attempt to run my program it crashes inside the inb()
>function:
>
>callisto:bstark$ ./esic check 0x300
>Hayes Enhanced Serial Interface (ESI) Utility
>Copyright 1996-1999 by Brian P. Stark. All rights reserved.
>
>Bus error (core dumped)
>callisto:bstark$ gdb esic esic.core
>GNU gdb 4.17
>Copyright 1998 Free Software Foundation, Inc.
>GDB is free software, covered by the GNU General Public License, and you
>are
>welcome to change it and/or distribute copies of it under certain
>conditions.
>Type "show copying" to see the conditions.
>There is absolutely no warranty for GDB.  Type "show warranty" for
>details.
>This GDB was configured as "i386--netbsd"...
>Core was generated by `esic'.
>Program terminated with signal 10, Bus error.
>Reading symbols from /usr/libexec/ld.so...done.
>Reading symbols from /usr/lib/libc.so.12.40...done.
>#0  0x37a2 in inportb (portid=768) at /usr/include/i386/pio.h:79
>79              return data;
>(gdb) where
>#0  0x37a2 in inportb (portid=768) at /usr/include/i386/pio.h:79
>#1  0x30a7 in DetectESP (EIO=768) at ../s/esi.c:639
>#2  0x1e04 in DoCheck (EIO=768) at ../s/esic.c:134
>#3  0x23fd in main (argc=3, argv=0xefbfd3e8) at ../s/esic.c:275
>(gdb) list
>74      static __inline u_int8_t
>75      __inb(int port)
>76      {
>77              u_int8_t data;
>78              __asm __volatile("inb %w1,%0" : "=a" (data) : "d" (port));
>79              return data;
>80      }
>81
>82      static __inline void
>83      insb(int port, void *addr, int cnt)
>(gdb)
>
>
>Since this is the first program I've worked on for NetBSD that needs to
>read and write a port, I'm not sure if what I am doing is correct.
>Should I be able to read and write the ports from inside my program
>by calling these functions? Is there any special setup/initialization
>code I am missing here?
>
>Thanks,
>
>
>Brian
>bstark@uswest.net