/* >>:yam5pmmi.c 7-09-82 * * PMMI MM-103 routines installed. These routines will: * * Dial the telephone * * Dial the telephone with ringback protocol * (no ring detect, just waits 8.5 seconds) * * Set baud rate * * Flip between answer and originate mode * * Hang up phone when appropriate * * To use the flip feature in this file, you need to insert the * following code just after the "case 'f':" statement in the main * command loop of yam1.c... * * #ifdef FLIP * if(cmdeq(cp, "lip")) { * if(flip( --argc, argp)==ERROR) * goto usage; * continue; * } * #endif * * versions of yam1.c dated subsequent to 6-12-82 have this feature * already installed * * Use b command (set buad) to turn on modem when dialing manually * (for MCI, SPRINT, etc.) (works like modem7 excpt ans/org is sep * command) * * 7-09-82 changed autodial routine to call terminal function directly * after successful call. Changed set baud routine to support all baud * rates between 61 and 710 ala cnode baud code. Fix error in dtdet() * that caused no return. (pjh) * * 6-27-82 added .7 sec delay in ringback to futher try to fix bug; * removed extra readline() code to shorten file. (pjh) * * 6-17-82 removed mysleep(); cleaned-up file; fixed parameter passing * in flip(); lengthened wait time at on-hook to fix bug in ringback * dial. (pjh) * * 6-13-82 added XMODEM conditional assembly defines for pause when * flipping modem modes. Added reset to default baud in bye(). (pjh) * * 6-12-82 added OK and ERROR on return to yam from flip. Deleted * unnecessary code. (caf) */ /* * setbaud(nbaud) If legal rate, set modem registers and Baudrate */ #include "yam.h" #ifdef PMMI #define MODEMSTUFF setbaud(nbaud) { if ((nbaud < 61) || (nbaud >710 )) { printf("\nbaudrate out of range (61-710)\n"); return ERROR; } outp(Sport+2, 15625/nbaud); /* turn on data terminal below 300 */ if(nbaud<301) outp(Sport+3,0x7F); else /* above 300 baud */ outp(Sport+3,0x5F); Baudrate=nbaud; if(Originate) outp(Sport,0x1D); /* off hook originate mode */ else outp(Sport,0x1E); /* off hook answer mode */ sleep(CLKMHZ/2); /*wait at least 51 msec */ outp(Sport,0x5C); /*setup uart - 8 bits; no parity; 2 stop bits*/ return 0; } onhook() { outp(Sport+3,0x3F); /* idle modem */ outp(Sport,0); /* go onhook */ sleep(16 * CLKMHZ); /* 3.8 sec(s) to go on */ } sendbrk() { outp(Sport+3, 0x7B); /* request transmit break */ sleep(CLKMHZ/2); outp(Sport+3, 0x7F); /* return to normal */ setbaud(Baudrate); } bye() { onhook(); Baudrate=(DEFBAUD); setbaud(Baudrate); } readbaud() { Baudrate=DEFBAUD; } /* * flip - toggle pmmi org/ans mode * adapted from steve passe's cnode flip * Returns OK is successful, ERROR otherwise */ flip(argc,argp) int argc; char **argp; { if (argc != 1) { printf("\007usage: flip 'org' or 'ans'\n"); return ERROR; } if(strcmp("org", argp[0]) == 0) { printf("changing to originate mode"); #ifdef XMODEM sleep(15*CLKMHZ/2); /* wait a sec before you do it */ #endif outp(Sport, 0x1d); sleep(CLKMHZ/2); /* kill at least 51ms. */ outp(Sport, 0x1c); /* enable auto hangup */ Originate = TRUE; } else if(strcmp("ans", argp[0]) == 0) { printf("changing to answer mode"); #ifdef XMODEM sleep(15*CLKMHZ/2); /* wait a sec before you do it */ #endif outp(Sport, 0x1e); sleep(CLKMHZ/2); /* kill at least 51ms. */ outp(Sport, 0x1c); /* enable auto hangup */ Originate = FALSE; } else { printf("\007? looking for 'org' or 'ans'. No action.\n"); return ERROR; } return OK; } #endif /* * Readline from MODEM13.C rewritten to allow much higher * baud rates. * Timeout is in deciseconds (1/10th's) * For top speed, character ready is checked in many places. * returns TIMEOUT if kbd character is ready. * * There are three versions of readline, the first is used if * there is a separate register for error conditions. The second * is used if error condx are in the same register asrx data ready. * The last, and quickest, does not check error conditions. */ #ifdef MIREADYERROR /* Version for 8250, 8251, 2651, etc. with all bits in one register */ readline(decisecs) { if((Mstatus=inp(Sport))&MIREADYMASK) goto getit; while(--decisecs>=0) { if((Mstatus=inp(Sport))&MIREADYMASK) goto getit; if(CDO) return TIMEOUT; if((Mstatus=inp(Sport))&MIREADYMASK) goto getit; if(CIREADY) { CICHAR; /* dismiss character */ return TIMEOUT; } if((Mstatus=inp(Sport))&MIREADYMASK) goto getit; for(Timeout=T1pause; --Timeout; ) if((Mstatus=inp(Sport))&MIREADYMASK) { getit: if(Mstatus & MIERRORMASK) { MICHAR; /* chuck it */ inp(Sport); /* reset err bits */ return ERROR; } else return MICHAR; } } return TIMEOUT; } #define READLINE #endif #ifndef READLINE readline(decisecs) { if(MIREADY) return MICHAR; while(--decisecs>=0) { if(MIREADY) return MICHAR; if(CIREADY) { CICHAR; /* dismiss character */ return TIMEOUT; } if(MIREADY) return MICHAR; for(Timeout=T1pause; --Timeout; ) if(MIREADY) return MICHAR; } return TIMEOUT; } #endif sendline(data) char data; { while(!MOREADY) ; outp(MODATA, data); } purgeline() { while(MIREADY) MICHAR; } #ifdef AUTODIAL /* PMMI AUTODIAL ROUTINES */ dial(name) char *name; { char *s,*n,c, conflg, ringbk, rung1; int chinp, pause; ringbk = FALSE; /* ringback desired */ rung1 = FALSE; /* if true, means we've already called once */ conflg= FALSE; dagain: n=cisubstr(name, "\t")+1; if((s=cisubstr(name, "\tb"))) { printf("\n%s", name); printf("\n\n"); } else return; printf("Waiting for dial tone"); if(!dtdet()){ printf(" No dial tone\n"); onhook(); return; } printf("\nDialing -> "); while((c=*n) != 'b') { printf("%c",c); if (c== 'r') ringbk = TRUE; if (isdigit(c)) { if(click(c) == ERROR) { pause = 0; goto quitnow; } } ++n; } /* if ringback desired let ring only once (more or (less)) */ if(ringbk && !rung1) { printf(" One ringy dingy...\n"); /* wait 8.5 seconds for ring */ if(timer(85) == ERROR) { setbaud(Baudrate); goto quitnow; } onhook(); rung1 = TRUE; sleep(7); /* wait a sec before dialing again */ setbaud(Baudrate); pause = 0; goto dagain; } /* number has been dialed now check for an answer */ printf("\nWaiting for answer "); pause=27; /* 27 seconds */ outp(Sport+3,0x7f); timer(2); outp(Sport,0x5d); while(inp(Sport+2)&4) { printf("."); if(timer(10)==ERROR) pause =0; else pause--; if (pause==0) break; } if(pause == 0) { rung1 = FALSE; ringbk = FALSE; onhook(); printf("\r\n No Answer !!\r\n"); if (conflg) goto dagain; printf(" Call again (Y/N/C)? "); chinp=tolower(getchar()); printf("\n"); if (chinp == 'c') { conflg = TRUE; goto dagain; } else if (chinp == 'y') goto dagain; else return; } printf("\7\7\7\N COMPUTERS ARE ON LINE \7\7\7\N"); Originate = TRUE; if(!setbaud(atoi(s+2))) printf("\n Baudrate set to: %u\n", Baudrate); term(); return OK; quitnow: onhook(); return OK; } dtdet(){ int pause; pause=20; outp(Sport,1); /* off hook */ outp(Sport+3,0x2f); /* set det filters */ while(inp(Sport+2)&1){ printf("."); if(timer(3) == ERROR) pause=0; else --pause; if(pause==0) return FALSE; } return TRUE; } click(num) char num; { unsigned number; number = num - '0'; if (number == 0) number = 10; outp(Sport+2,PPS); while(inp(Sport+2) & 0x80); while((inp(Sport+2)&0x80)^0x80); while (number-- ) { outp(Sport,1); while(inp(Sport+2) & 0x80); outp(Sport,0); while((inp(Sport+2)&0x80)^0x80); } outp(Sport,1); if(CIREADY) { if((CICHAR) == 0x18) return ERROR; } if(timer(5)==ERROR) return ERROR; return OK; } #endif /* uses pmmi timer function for delays. if control-x typed while * here, stops and returns with ERROR. */ timer(tenths) int tenths; { int pause; outp(Sport+2,0xfa); /* value for .1 sec timer pulse */ for(pause = 0;pause < tenths;pause++) { /* wait for timer to go low */ while(!(inp(Sport+2)&0x80)); if(CIREADY) { if((CICHAR) == 0x18) return ERROR; } /* wait for timer to go high */ while(inp(Sport+2)&0x80); } return OK; }