/* * Glib - Generic LIBrarian and editor * * Machine dependent stuff for MIDI programs. * * 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. */ #include "dos.h" #include "glib.h" #define C86 #ifdef C86 #define inp inportb #define outp outportb #endif int Rows = 24; int Cols = 80; 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()); } flushconsole() { } statconsole() { struct regval sreg, rreg; sreg.ax = 0x0100; sysint(0x16, &sreg, &rreg); if ( rreg.ax != 0 ) return(1); else return(0); } getconsole() { struct regval sreg, rreg; sreg.ax = 0x0000; sysint(0x16, &sreg, &rreg); return(rreg.ax & 0x7f); } long milliclock() { static int hour1 = -1, min1, sec1, hund1; struct regval sreg, rreg; int hours, mins, secs, hunds; long mills; sreg.ax = 0x2c00; sysint(0x21, &sreg, &rreg); hours = (rreg.cx >> 8) & 0x7f; mins = rreg.cx & 0x7f; secs = (rreg.dx >> 8) & 0x7f; hunds = rreg.dx & 0x7f ; if ( hour1 < 0 ) { mills = 0L; hour1 = hours; min1 = mins; sec1 = secs; hund1 = hunds; } else { mills = 10L*(hunds-hund1)+1000L*(secs-sec1) +60000L*(mins-min1)+360000L*(hours-hour1); } return( mills ); } 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); } windinit() { } windgoto(r,c) int r,c; { struct regval sreg, rreg; sreg.ax = 0x200; sreg.bx = 0; sreg.dx = (r<<8) | c ; sysint(0x10, &sreg, &rreg); } winderaserow(r) { 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); } windexit(r) int r; { /* windgoto(23,0); windrefresh(); nocbreak(); nl(); echo(); endwin(); */ } windclear() { struct regval sreg, rreg; sreg.ax = 0x0600; sreg.bx = 0; sreg.cx = 0; /* urow, lcol */ sreg.dx = (24<<8) | 79; sysint(0x10, &sreg, &rreg); } /* 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. ***************/ openls() { } char * nextls() { return(NULL); } closels() { } /* * 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 */ inp(DATA_PORT); for (time_count=5000,flag=1;time_count&&flag;time_count--) { if (!(inp(STATUS_PORT)&DATA_READY_MASK)) flag=0; } if (flag) { fprintf(stderr,"Command timeout waiting for port!\n"); retval = -1; } else { outp(COMMAND_PORT,val); for (time_count=10000,ack_count=5,flag=0;!flag;) { if ((inp(STATUS_PORT)&DATA_AVAIL_MASK)) { time_count--; if (!time_count) { flag++; fprintf(stderr,"Command timeout waiting for ACK.\n"); retval = -1; } } else { x = (unsigned)inp(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 */ getmidi() { while (inp(STATUS_PORT) & DATA_AVAIL_MASK) ; /* Wait for data available */ return(inp(DATA_PORT)); } statmidi() { if ( inp(STATUS_PORT) & DATA_AVAIL_MASK) /* data available ? */ return(0); else return(1); } sendmidi(val) int val; { int timeout = 10000; unsigned status; status=inp(STATUS_PORT); while (status & DATA_READY_MASK) printf("Busy; read %d ",getmidi()); /* This printf lets me know what's holding up the transfer; I usually get 254 back, unless I press a synth key, when I get the key press parameters. */ outp(DATA_PORT,val); } hello() { send_command_4001(0xff); /* reset */ send_command_4001(0x96); /* kill RT? */ send_command_4001(0x94); /* ?? */ send_command_4001(0x90); /* ?? */ send_command_4001(0x3f); /* go into uart mode */ } bye() { send_command_4001(0xff); /* reset */ windexit(0); }