home *** CD-ROM | disk | FTP | other *** search
- /* $Id: pc-mach.c,v 1.6 89/05/06 17:13:39 lee Exp $
- *
- * Glib - Generic LIBrarian and editor
- *
- * Machine dependent stuff for MIDI programs.
- * Time Thompson
- *
- * This is for MS-DOS machines. The screen operations should
- * work okay, but the MIDI I/O needs to be worked on. It may
- * or may not be fast enough on some machines.
- * $Log: pc-mach.c,v $
- * Revision 1.6 89/05/06 17:13:39 lee
- * rel. to comp.sources.misc
- *
- */
-
- #include "glib.h"
-
- int Rows = 24;
- int Cols = 80;
-
- char *
- alloc(n)
- {
- char *p;
-
- if ( (p=malloc((unsigned)n)) == (char *)NULL ) {
- printf("*** Whoops *** alloc has failed?!? No more memory!\n");
- fflush(stdout);
- bye();
- }
- return(p);
- }
-
- flushmidi()
- {
- while ( STATMIDI )
- getmidi();
- }
-
- /* getmouse - get currect row and column of mouse */
- getmouse(amr,amc)
- int *amr;
- int *amc;
- {
- *amr = -1;
- *amc = -1;
- }
-
- /* statmouse - return mouse button state (0=nothing pressed,1=left,2=right) */
- statmouse()
- {
- return(-1);
- }
-
- /* Return when either a console key or mouse button is pressed. */
- mouseorkey()
- {
- return(getconsole());
- }
-
- #ifdef C86
- getch()
- {
- struct regval sreg, rreg;
- sreg.ax = 0x0000;
- sysint(0x16, &sreg, &rreg);
- return(rreg.ax & 0x7f);
- }
- #endif
-
- windinit()
- {
- }
-
- windgoto(r,c)
- int r,c;
- {
- #ifdef C86
- struct regval sreg, rreg;
- sreg.ax = 0x200;
- sreg.bx = 0;
- sreg.dx = (r<<8) | c ;
- sysint(0x10, &sreg, &rreg);
- #endif
- #ifdef TURBOC
- gotoxy(1+c,1+r);
- #endif
- }
-
- winderaserow(r)
- {
- #ifdef C86
- struct regval sreg, rreg;
- sreg.ax = 0x0600;
- sreg.bx = 0;
- sreg.cx = (r<<8); /* urow, lcol */
- sreg.dx = (r<<8) | 79;
- sysint(0x10, &sreg, &rreg);
- #endif
- #ifdef TURBOC
- gotoxy(1,r+1);
- clreol();
- #endif
- }
-
- windexit()
- {
- /* windgoto(23,0);
- windrefresh();
- nocbreak();
- nl();
- echo();
- endwin(); */
- }
-
- windclear()
- {
- #ifdef C86
- struct regval sreg, rreg;
- sreg.ax = 0x0600;
- sreg.bx = 0;
- sreg.cx = 0; /* urow, lcol */
- sreg.dx = (24<<8) | 79;
- sysint(0x10, &sreg, &rreg);
- #endif
- #ifdef TURBOC
- clrscr();
- #endif
- }
-
- /* windgets - get a line of input from the console, handling backspaces */
- windgets(s)
- char *s;
- {
- char *origs = s;
- int c;
-
- while ( (c=getconsole()) != '\n' && c!='\r' && c!= EOF ) {
- if ( c == '\b' ) {
- if ( s > origs ) {
- windstr("\b \b");
- s--;
- }
- }
- else {
- windputc(c);
- *s++ = c;
- }
- windrefresh();
- }
- *s = '\0';
- }
-
- windstr(s)
- char *s;
- {
- int c;
-
- while ( (c=(*s++)) != '\0' )
- windputc(c);
- }
-
- windputc(c)
- int c;
- {
- putchar(c);
- }
-
- windrefresh()
- {
- }
-
- beep()
- {
- putchar('\007');
- }
-
- windhigh()
- {
- }
-
- windnorm()
- {
- }
-
- /****************
- * openls(), nextls(), and closels() are used to scan the current directory.
- ***************/
-
- int first = 1;
- openls()
- {
- first = 1;
- }
- char *
- nextls()
- {
- static struct ffblk ffblk;
- int n;
-
- if ( first ) {
- n = findfirst("*.*",&ffblk,0);
- first = 0;
- }
- else
- n = findnext(&ffblk);
-
- if ( n == 0 )
- return(ffblk.ff_name);
- else
- return((char *)NULL);
- }
- closels()
- {
- }
-
- #ifdef OLDSTUFF
- /*
- * The following MPU code has been provided by Steve Frysinger (moss!spf).
- */
-
- #define STATUS_PORT 0x0331
- #define COMMAND_PORT 0x0331
- #define DATA_PORT 0x0330
- #define DATA_READY_MASK 0x40
- #define DATA_AVAIL_MASK 0x80
-
- int send_command_4001(val) /* Patterned after Voyetra's reset_4001() */
- unsigned val;
- {
- unsigned x = 0;
- int flag;
- int ack_count,time_count;
- int retval=1; /* Assume success */
- inportb(DATA_PORT);
- for (time_count=5000,flag=1;time_count&&flag;time_count--)
- {
- if (!(inportb(STATUS_PORT)&DATA_READY_MASK)) flag=0;
- }
- if (flag)
- {
- fprintf(stderr,"Command timeout waiting for port!\n");
- retval = -1;
- }
- else
- {
- outportb(COMMAND_PORT,val);
- for (time_count=10000,ack_count=5,flag=0;!flag;)
- {
- if ((inportb(STATUS_PORT)&DATA_AVAIL_MASK))
- {
- time_count--;
- if (!time_count)
- {
- flag++;
- fprintf(stderr,"Command timeout waiting for ACK.\n");
- retval = -1;
- }
- }
- else
- {
- x = (unsigned)inportb(DATA_PORT);
- if (x == 0xfe)
- {
- flag++;
- fprintf(stderr,"Got command acknowledgement\n");
- }
- else
- {
- ack_count--;
- if (!ack_count)
- {
- printf("Too many data bytes without ACK\n");
- retval = -1;
- }
- }
- }
- }
- }
- return(retval);
- } /* send_command_4001 */
- #endif
-
- /*
- * Acknowledgements to John Helton for additions to support ATT PC6300 w/
- * MPU401 and OP4000 MIDI Interface Controllers.
- * PC6300 support uses Borland TurboC 'C' compiler, large model
- *
- */
- #define QUIT 1
- #define NOQUIT 0
-
- void interrupt (*oldint0)();
- void interrupt (*oldint2)();
- void interrupt (*oldint1b)();
- void interrupt (*oldint23)();
- void interrupt (*oldint24)();
- void interrupt ctr_brk_handler();
- void interrupt fatal_err_hndlr();
-
- void interrupt far tick_isr();
- void interrupt far midi_isr();
- extern unsigned long hzcount;
- extern char midi_buffer[];
- extern int wrt_index, rd_index;
-
- extern unsigned _stklen; /* Turbo C specific */
-
- int Nextpcchar = EOF;
- int Fakemidi = 0;
- int (*Intfunc)() = NULL;
-
- hello()
- {
- _stklen = 50000;
- hzcount = 0L; /* init timer & buffer globals */
- wrt_index = rd_index = 0;
- if (!setup_MIC()) /* Set up the Midi Interface Ctrl */
- {
- if ( fisatty(stdout) )
- printf("Can't initialize midi interface\n");
- Fakemidi = 1;
- reset_ints(NOQUIT); /* restore interrupts to a suitable
- condition to keep running without
- the Midi Interface (for testing) */
- return;
- }
- send_msg(UART, COMMAND_MSG); /* run the MIC in dumb mode */
- return;
- }
-
- rtend()
- {
- reset_MIC();
- }
-
- bye()
- {
- system_exit();
- }
-
- flushconsole()
- { return; }
-
- getconsole()
- {
- int c;
-
- if ( Nextpcchar != EOF ) {
- c = Nextpcchar;
- Nextpcchar = EOF;
- }
- else {
- c = getch();
- }
- return(c);
- }
-
- putconsole(c)
- {
- putch(c);
- }
-
- /* getmidi reads data out of the circular midi buffer */
- getmidi()
- {
- static char mbuff[1];
- unsigned char *p;
-
- while ( wrt_index == rd_index)
- ;
- rd_index++;
- if (rd_index > 511) rd_index = 0;
- mbuff[0] = midi_buffer[rd_index];
- return (mbuff[0] & 0xff);
- }
-
- sendmidi(val)
- int val;
- {
- unsigned char p[1];
- p[0] = val;
- putnmidi(1,p);
- }
-
- putnmidi(n,p)
- char *p;
- {
- while ( n-- > 0 ) {
- int c = (*p++) & 0xff;
- if ( Fakemidi )
- printf("putmidi(d=%d x=%x o=%o)\n",c,c,c);
- else
- write_data_MPU(c);
- }
- }
-
- resetclock()
- {
- hzcount = 0L;
- }
-
- long
- milliclock()
- {
- return (hzcount*5L);
- }
-
- /* filetime - Return the modification time of a file in seconds. */
- long
- filetime(fn)
- char *fn; /* file name */
- {
- struct stat s;
-
- if ( stat(fn,&s) == -1 )
- return(-1);
- return(s.st_mtime);
- }
-
- /* currtime - Return current time in seconds (consistent with filetime()) */
- long
- currtime()
- {
- long time();
- return ( time((long *)0) );
- }
-
- fisatty(f)
- FILE* f;
- {
- return(isatty(fileno(f)));
- }
-
- /*
- * send_msg(COM, TYPE, PTR, LENGTH)
- * will send command to Midi Interface Controller (MIC) Command port,
- * then either return, wait for data or send data
- */
-
- send_msg(com, type, ptr, length)
- int com, type, length;
- char *ptr;
- {
- int acked;
- int x;
-
- while ( NOT_READY_FOR_DATA_MIC());
- disable_ints();
- COMMAND_OUT_MIC((char) com); /* send the command to the MIC */
- for(acked=0; !acked; ) { /* wait until our command is acked */
- x = read_MPU(); /* get a byte back from the MIC */
- if (x == ACK) acked++; /* done if ACK received */
- else write_rcv_buff(x); /* deal with this input stream first */
- }
- if (type == WRITE_MSG) /* if write request... */
- for (; length; ptr++, length--) write_data_MPU(*ptr);
- /* write all the bytes to the MIC */
- enable_ints(); /* ints restored to where they were
- before we shut them off */
- }
-
-
- /* WRITE_RCV_BUFF(INPUT)
- * part of the command handshake sequence. Input read from the
- * midi data port is saved in wraparound FIFO
- */
-
- write_rcv_buff(val)
- int val;
- {
- wrt_index++;
- if (wrt_index > 511) wrt_index = 0;
- midi_buffer[wrt_index] = (char) val;
- }
-
- /*
- * SETUP_MIC()
- * resets MIC, sets up int vectors and enables int system
- * Returns - true if MIC set ok
- */
-
- static setup_MIC()
- {
- int retval;
-
- set_ints(); /* set the new interrupt vectors */
- init_enable_MPU(); /* turn on interrupt system for first time */
- retval = reset_MIC(); /* try to reset MIC */
- if (!retval) retval = reset_MIC(); /* if no good, try again */
- init_enable_TIMER(); /* turn on timer interrupt if reset ok*/
- return(retval);
- }
-
- /*
- * RESET_MIC()
- * attempts to do a low level software reset on the MIC
- * returns - true if success
- */
-
- reset_MIC()
- {
- unsigned x = 0;
- int flag;
- int ack_count, time_count;
- int retval=1; /* assume success */
-
- disable_ints(); /* disable interrupts */
- READ_DATA_MIC(); /* Clear out any data in receiver */
- /* Here we will loop until ready for data, or we give up */
- for (time_count=5000, flag=1; time_count && flag; time_count--) {
- /* if MIC ready for data, we can quit loop */
- if (!(NOT_READY_FOR_DATA_MIC())) flag=0;
- }
- /* if timed out before we got ready for data, return flag couldn't reset */
- if (flag){
- retval = 0;
- }
- else {
- COMMAND_OUT_MIC(RESET); /* Send the reset command */
- /* loop here till time out, or ack recvd */
- for (time_count=10000, ack_count=5, flag=0; !flag;) {
- if ((NOT_DATA_AVAILABLE_MIC())) { /* if no data from MIC */
- time_count--; /* count one more wait */
- if (!time_count) {
- BAD_RESET:
- flag++; /* if time out, note it */
- retval=0; /* and note failure */
- }
- }
- else { /* If there is data coming back form MIC */
- x = (unsigned) READ_DATA_MIC(); /* ...read it */
- if (x == ACK) { /* If data is the ACK message */
- flag++; /* note we are done, and no failure */
- }
- else { /* if data back from MIC wasn't ack */
- ack_count--;/* note that we got something that isn't ack */
- if (!ack_count) goto BAD_RESET;
- /* If we get too many data bytes back from
- MIC with no ack, give up */
- }
- }
- }
- }
- enable_ints(); /* turn ints back on */
- return(retval);
- }
-
- /*
- * SYSTEM_EXIT()
- * called to leave program. resets ints and exits
- */
- system_exit()
- {
- reset_MIC();
- disable_ints();
- reset_ints(QUIT); /* put all the int vectors back where they were */
- reset_TIMER();
- enable_ints();
- windexit(0);
- exit();
- }
-
- /*
- * hi level interrupt routines
- */
-
- void interrupt
- ctr_brk_handler()
- {
- if ( Intfunc != NULL )
- (*Intfunc)();
- printf("interrupts reset; BYE!\n");
- system_exit();
- }
-
- void interrupt
- fatal_err_hndlr()
- {
- fatal_dos_handler();
- }
-
- fatal_dos_handler() /* called by fatal error handler ISR */
- {
- printf("got fatal error; BYE!\n");
- system_exit();
- }
-
- set_ints()
- {
- oldint0 = getvect(0x08); /* timer interrupt on irq0 */
- setvect(0x08, tick_isr);
- oldint2 = getvect(0x0a); /* midi interrupt on irq2 */
- setvect(0x0a, midi_isr);
- oldint1b = getvect(0x1b); /* the rest of these are dos & bios ints */
- setvect(0x1b, ctr_brk_handler);
- oldint23 = getvect(0x23);
- setvect(0x23, ctr_brk_handler);
- oldint24 = getvect(0x24);
- setvect(0x24, fatal_err_hndlr);
- }
-
- reset_ints(reset_type)
- {
- if (reset_type == QUIT) {
- setvect(0x08, oldint0);
- setvect(0x1b, oldint1b);
- setvect(0x23, oldint23);
- setvect(0x24, oldint24);
- }
- setvect(0x0a, oldint2); /* only need to reset one hardware interrupt
- if we're not going to quit */
- }
-
- signal(type,func)
- int (*func)();
- {
- if ( type == SIGINT ) {
- if ( func == SIG_IGN )
- Intfunc = NULL;
- else
- Intfunc = func;
- }
- }
-