339 lines
		
	
	
		
			5.8 KiB
		
	
	
	
		
			C
		
	
	
	
			
		
		
	
	
			339 lines
		
	
	
		
			5.8 KiB
		
	
	
	
		
			C
		
	
	
	
| /*
 | |
|  * io.c -- all the code to make GCC and the libraries run on
 | |
|  *         a bare target board.
 | |
|  */
 | |
| 
 | |
| #include <sys/types.h>
 | |
| #include <sys/stat.h>
 | |
| #include <errno.h>
 | |
| 
 | |
| #include "hppa-defs.h"
 | |
| 
 | |
| extern char *_end;                /* _end is set in the linker command file */
 | |
| 
 | |
| /* just in case, most boards have at least some memory */
 | |
| #ifndef RAMSIZE
 | |
| #  define RAMSIZE             (char *)0x100000
 | |
| #endif
 | |
| 
 | |
| int
 | |
| print(ptr)
 | |
| char *ptr;
 | |
| {
 | |
|   while (*ptr)
 | |
|     outbyte (*ptr++);
 | |
| }
 | |
| 
 | |
| int
 | |
| putnum (Num)
 | |
| unsigned int Num;
 | |
| {
 | |
|   char	Buffer[9];
 | |
|   int	Count;
 | |
|   char	*BufPtr = Buffer;
 | |
|   int	Digit;
 | |
|   
 | |
|   for (Count = 7 ; Count >= 0 ; Count--) {
 | |
|     Digit = (Num >> (Count * 4)) & 0xf;
 | |
|     
 | |
|     if (Digit <= 9)
 | |
|       *BufPtr++ = (char) ('0' + Digit);
 | |
|     else
 | |
|       *BufPtr++ = (char) ('a' - 10 + Digit);
 | |
|   }
 | |
| 
 | |
|   *BufPtr = (char) 0;
 | |
|   print (Buffer);
 | |
|   return;
 | |
| }
 | |
| 
 | |
| int
 | |
| delay (x)
 | |
|      int x;
 | |
| {
 | |
|   int  y = 17;
 | |
|   while (x-- !=0)
 | |
|     y = y^2;
 | |
| }
 | |
| 
 | |
| /*
 | |
|  * strobe -- do a zylons thing, toggling each led in sequence forever...
 | |
|  */
 | |
| int
 | |
| zylons()
 | |
| {
 | |
|   while (1) {
 | |
|     strobe();
 | |
|   }
 | |
| }
 | |
| 
 | |
| /*
 | |
|  * strobe -- toggle each led in sequence up and back once.
 | |
|  */
 | |
| int
 | |
| strobe()
 | |
| {
 | |
|   static unsigned char curled = 1;
 | |
|   static unsigned char dir = 0;
 | |
| 
 | |
|   curled = 1;
 | |
|   dir = 0;
 | |
|   while (curled != 0) {
 | |
|     led_putnum (curled);
 | |
|     delay (70000);
 | |
|     if (dir)
 | |
|       curled >>= 1;
 | |
|     else
 | |
|       curled <<= 1;
 | |
|     
 | |
|     if (curled == 128) {
 | |
|       dir = ~dir;
 | |
|     }
 | |
|   }
 | |
|   curled = 1;
 | |
|   dir = 0;
 | |
| }
 | |
| 
 | |
| /*
 | |
|  * iodc_io_call -- this makes a call into the IODC routine
 | |
|  */
 | |
| int
 | |
| iodc_io_call(ep_address,arg0,arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8,arg9,arg10,arg11)
 | |
| int ep_address, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11;
 | |
| { 
 | |
|   int         (*iodc_entry_point)();
 | |
|   
 | |
|   iodc_entry_point = (int (*)())ep_address;
 | |
| 
 | |
|   return ((*iodc_entry_point)(arg0,arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8,arg9,arg10,arg11));
 | |
| }
 | |
| 
 | |
| /*
 | |
|  * pdc_call -- this makes a call into the PDC routine
 | |
|  */
 | |
| int
 | |
| pdc_call(arg0,arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8,arg9,arg10,arg11)
 | |
|      int arg0, arg1, arg2, arg3,  arg4, arg5;
 | |
|      int arg6, arg7, arg9, arg10, arg11;
 | |
| {
 | |
|    return ( CALL_PDC(arg0,arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8,arg9,arg10,arg11));
 | |
| }
 | |
| 
 | |
| /*
 | |
|  * put_led -- put a bit pattern on the LED's. 
 | |
|  */
 | |
| int
 | |
| led_putnum (byte)
 | |
|      unsigned short byte;
 | |
| {
 | |
|   return (pdc_call(OPT_PDC_CHASSIS,0,byte));
 | |
| }
 | |
| 
 | |
| 
 | |
| /*
 | |
|  * outbyte -- shove a byte out the serial port
 | |
|  */
 | |
| int
 | |
| outbyte(byte)
 | |
|      unsigned char byte;
 | |
| {
 | |
|   int status;
 | |
|   int R_addr[32];
 | |
|   struct _dev *console = (struct _dev *)PGZ_CONSOLE_STRUCT;
 | |
| 
 | |
|   status = iodc_io_call(console->iodc_io, console->hpa, IO_CONSOLE_OUTPUT, console->spa,
 | |
| 			console->layer[0], R_addr, 0, &byte, 1,	0);
 | |
| 
 | |
|   switch(status)
 | |
|     {
 | |
|     case 0:  return(1);
 | |
|     default: return (-1);
 | |
|     }
 | |
| }
 | |
| 
 | |
| /*
 | |
|  * inbyte -- get a byte from the serial port
 | |
|  */
 | |
| unsigned char
 | |
| inbyte()
 | |
| {
 | |
|   int status;
 | |
|   int R_addr[32];
 | |
|   char inbuf;
 | |
|   struct _dev *console = (struct _dev *)PGZ_CONSOLE_STRUCT;
 | |
| 
 | |
|   while (status == 0) {
 | |
|     status = iodc_io_call(console->iodc_io, console->hpa, IO_CONSOLE_INPUT, console->spa,
 | |
| 			  console->layer[0], R_addr, 0, &inbuf, 1, 0);
 | |
|     
 | |
|     switch (status) {
 | |
|     case 0:
 | |
|     case 2:  					/* recoverable error */
 | |
|       if (R_addr[0] != 0) {			/* found a character */
 | |
| 	return(inbuf);
 | |
|       }
 | |
|       else
 | |
| 	break; 					/* error, no character */
 | |
|     default: 					/* error, no character */
 | |
|       return(0);	
 | |
|     }
 | |
|   }
 | |
| }
 | |
| 
 | |
| /*
 | |
|  * read  -- read bytes from the serial port. Ignore fd, since
 | |
|  *          we only have stdin.
 | |
|  */
 | |
| int
 | |
| read(fd, buf, nbytes)
 | |
|      int fd;
 | |
|      char *buf;
 | |
|      int nbytes;
 | |
| {
 | |
|   int i = 0;
 | |
|   
 | |
|   for (i = 0; i < nbytes; i++) {
 | |
|     *(buf + i) = inbyte();
 | |
|     if ((*(buf + i) == '\n') || (*(buf + i) == '\r')) {
 | |
|       (*(buf + i)) = 0;
 | |
|       break;
 | |
|     }
 | |
|   }
 | |
|   return (i);
 | |
| }
 | |
| 
 | |
| /*
 | |
|  * write -- write bytes to the serial port. Ignore fd, since
 | |
|  *          stdout and stderr are the same. Since we have no filesystem,
 | |
|  *          open will only return an error.
 | |
|  */
 | |
| int
 | |
| write(fd, buf, nbytes)
 | |
|      int fd;
 | |
|      char *buf;
 | |
|      int nbytes;
 | |
| {
 | |
|   int i;
 | |
| 
 | |
|   for (i = 0; i < nbytes; i++) {
 | |
|     if (*(buf + i) == '\n') {
 | |
|       outbyte ('\r');
 | |
|     }
 | |
|     outbyte (*(buf + i));
 | |
|   }
 | |
|   return (nbytes);
 | |
| }
 | |
| 
 | |
| /*
 | |
|  * open -- open a file descriptor. We don't have a filesystem, so
 | |
|  *         we return an error.
 | |
|  */
 | |
| int
 | |
| open(buf, flags, mode)
 | |
|      char *buf;
 | |
|      int flags;
 | |
|      int mode;
 | |
| {
 | |
|   errno = EIO;
 | |
|   return (-1);
 | |
| }
 | |
| 
 | |
| /*
 | |
|  * close -- close a file descriptor. We don't need
 | |
|  *          to do anything, but pretend we did.
 | |
|  */
 | |
| int
 | |
| close(fd)
 | |
|      int fd;
 | |
| {
 | |
|   return (0);
 | |
| }
 | |
| 
 | |
| /*
 | |
|  * sbrk -- changes heap size size. Get nbytes more
 | |
|  *         RAM. We just increment a pointer in what's
 | |
|  *         left of memory on the board.
 | |
|  */
 | |
| char *
 | |
| sbrk(nbytes)
 | |
|      int nbytes;
 | |
| {
 | |
|   static char * heap_ptr = NULL;
 | |
|   char *        base;
 | |
| 
 | |
|   if (heap_ptr == NULL) {
 | |
|     heap_ptr = (char *)&_end;
 | |
|   }
 | |
| 
 | |
|   if ((RAMSIZE - heap_ptr) >= 0) {
 | |
|     base = heap_ptr;
 | |
|     heap_ptr += nbytes;
 | |
|     return (heap_ptr);
 | |
|   } else {
 | |
|     errno = ENOMEM;
 | |
|     return ((char *)-1);
 | |
|   }
 | |
| }
 | |
| 
 | |
| /*
 | |
|  * isatty -- returns 1 if connected to a terminal device,
 | |
|  *           returns 0 if not. Since we're hooked up to a
 | |
|  *           serial port, we'll say yes return a 1.
 | |
|  */
 | |
| int
 | |
| isatty(fd)
 | |
|      int fd;
 | |
| {
 | |
|   return (1);
 | |
| }
 | |
| 
 | |
| /*
 | |
|  * lseek -- move read/write pointer. Since a serial port
 | |
|  *          is non-seekable, we return an error.
 | |
|  */
 | |
| off_t
 | |
| lseek(fd,  offset, whence)
 | |
|      int fd;
 | |
|      off_t offset;
 | |
|      int whence;
 | |
| {
 | |
|   errno = ESPIPE;
 | |
|   return ((off_t)-1);
 | |
| }
 | |
| 
 | |
| /*
 | |
|  * fstat -- get status of a file. Since we have no file
 | |
|  *          system, we just return an error.
 | |
|  */
 | |
| int
 | |
| fstat(fd, buf)
 | |
|      int fd;
 | |
|      struct stat *buf;
 | |
| {
 | |
|   errno = EIO;
 | |
|   return (-1);
 | |
| }
 | |
| 
 | |
| /*
 | |
|  * getpid -- only one process, so just return 1.
 | |
|  */
 | |
| #define __MYPID 1
 | |
| int
 | |
| getpid()
 | |
| {
 | |
|   return __MYPID;
 | |
| }
 | |
| 
 | |
| /*
 | |
|  * kill -- assume mvme.S, and go out via exit...
 | |
|  */
 | |
| int
 | |
| kill(pid, sig)
 | |
|      int pid;
 | |
|      int sig;
 | |
| {
 | |
|   if(pid == __MYPID)
 | |
|     _exit(sig);
 | |
|   return 0;
 | |
| }
 |