/* ssx.c Personal PBX Call Processing Source Code (c) 1994-2006 Richard Newman 1110 W. North Ave, Pittsburgh PA 15233 */ /* #define DEBUG 1 this is commented out for PRODUCTION CODE */ #define TRUE 1 #include <8051io.h> /* for putc,printf,getch i/o functions */ #include <8051int.h> /* for interupt service macro */ #include <8051reg.h> /* to access registers by name */ #include <8051bit.h> /* to access bits in registers directly */ /* Extention Related Process */ #define exhm 1 /* 00 - 32 Extention Hook Monitor Process */ #define exdm 33 /* 33 - 64 Extention Dialing Monitor Process */ #define exsm 97 /* 65 - 96 Extention Signaling Monitor */ #define excm 65 /* 97 - 128 Extention Conversation Monitor */ /* Global Definitions used by various functions */ #define maxstat 16 /* Number of stations in system */ #define maxpath 8 /* Max talk paths and conversations */ #define maxrecs 1 /* Max number of dtmf reciever- cpg sender combos */ #define maxsend 1 /* Max number of cpg reciever- dtmf sender combos */ #define maxdigits 20 /* Max number of digits to collect on call */ #define first_digit 20 /* time until busy on first dialed digit */ #define inter_digit 6 /* timeout between dialed digits */ #define lock_out 30 /* time until station lockout is performed */ #define acs_register_length 16 #define total_routes 4 #define registers_per_route 7 #define maxrad 1 /* max recorded anouncement device */ #define BUSY 1 #define IDLE 0xFF #define SILENCE 0xFF #define DIAL 0x00 #define SPECIALA 0x02 #define ALERT 0x04 #define RING 0x06 #define PREMPT 0x08 #define HIBELL 0x0A #define LOBELL 0x0C /* also re-order */ #define REORDER 0x0C #define SPECIALB 0x0E #define SPECIALC 0x10 #define DTMF* 0x18 /* Call Control Block */ static unsigned char ccb_acp[maxpath]; /* associated completion path */ static unsigned char ccb_path[maxpath]; /* idle means whole CCB free, else marked busy */ static unsigned char ccb_digits[maxpath][maxdigits]; /* max collected digits */ static unsigned char ccb_enque[maxpath]; static unsigned char ccb_route[maxpath]; static unsigned char ccb; static unsigned char route; /* Common Resource Control Block */ static unsigned char recs_status[maxrecs]; static unsigned char send_status[maxsend]; static unsigned char ccb_deque[maxpath]; /* Global Variables accessable from any module */ static unsigned int hour,minute,hundsec,second,tens; static unsigned char rfreq; static unsigned char ext_process[maxstat]; /* ext process to execute 0 - 15 */ static unsigned char ext_substate[maxstat]; static unsigned char ext_status[maxstat]; /* marks the associated CCB and SPEECH path talking on */ static unsigned char ext_return[maxstat]; static unsigned char ext_temp[maxstat]; static unsigned char *rap[maxrad]; /* recorded announcement device directory pointer */ static unsigned char rads[maxrad]; /* recorded announcemtnt device status */ static unsigned char radm[maxrad]; /* recorded announcement device message */ static unsigned char ext_check; /* Scheduler process to execute */ static unsigned char table_pointer_begin[16]; /* pointer to 8xx tables */ static unsigned char table_pointer_end; static unsigned char table_8xx[200]; /* actual 8xx table */ static unsigned char *port; static unsigned char cross; /* speech path cross connect variable */ static unsigned int ext_timer[maxstat]; /* station timing variable */ static unsigned char ext_route[maxstat]; /* route selected for station */ static unsigned char ring_trip; /* counter to determine ring trip */ static unsigned char ring_hv; /* flag to generate ringing hv */ static unsigned char message_hv; /* flag to generate message waiting hv */ static unsigned char shadow_D006; static unsigned char shadow_D000; static unsigned char shadow_D002; static unsigned char shadow_D004; static unsigned char shadow_C002; static unsigned char route_update_next; /* this is the current route being examined by the route routine */ static unsigned char acs[total_routes*registers_per_route][acs_register_length]; #ifdef DEBUG static unsigned char rtdisp; #endif char cpg(tone) char tone; { /* is a generator connected to this call ? */ /* if so then send the desired tone- return sucess by indicating the */ /* associated CCB/Path. If not locate a free generator and associate */ /* it with the call and indicate sucess by returning the associated */ /* CCB/path. if no generator is available and there is no generator */ /* currently assigned to the call indicate unsucessful operation by */ /* returning IDLE indication of 0xFF */ char i,j,k,enable; if (tone==SILENCE) { enable=0xFF; } else { enable=0xFE; } k=0; /* start by indicating not found */ /* check for a generator connected to this call */ for (i=0;i7) { port=port+2; k=station-8; } else { k=station; } for (i=1; i <= k;i++) { j=j+j; /* j now contains bit to AND against */ } /* port contains port number to READ from */ if (!((*port) & j)) /* Is the phone off hook? */ { /* The phone IS off hook so return a 1 */ return(1); } else { /* The phone is NOT off hook so return a 0 */ return(0); } } cleanup(void) { /* Clean up the call control block associated with the */ /* station. 1) Disconnect all hardware from the associated */ /* speech path. 2) see if any call progress resources assigned */ /* if so clear their control blocks making them idle */ /* 3) specify that the speech path is now idle */ unsigned char i,j,k; ccb=ext_status[ext_check]; /* locate phones ccb/speech path */ #ifdef DEBUG printf("Cleanup ccb= %x\n",ccb); #endif if (ext_status[ext_check]!=IDLE) /* is cleanup already performed? lockout ? */ { clear_common(); /* release common controls/ reciever-generator */ ext_route[ext_check]=0x27; /* route is dont do anything */ ext_status[ext_check]=IDLE; /* unassociate phone with ccb */ /* if we are the only phone left on ccb then free if */ /* otherwise leave ccb busy indication alone */ j=0; /* start by reseting this byte */ for (k=0;k=6) { j=cross+2; } else { j=cross; } } if (cross>12) { port=0xC007; /* point to the second m093b1 (#2) */ if (cross>=19) { j=(cross-12)+2; } else { j=(cross-12); } } j=j*0x10; /* move to most significant nibble */ /* do not set bit 3 (0000 0000) means to disconnect */ j=j+path; /* path is control block/path so add it too. */ *port=j; /* send the constructed control byte to the xpoint */ #ifdef DEBUG printf("DISCONNECT cross:%02x path:%02x port:%02x control word %02x \n" ,cross,path,port,j); #endif } connect(path) char path; { unsigned char i,j,k; if (cross<=12) { port=0xC006; /* point to the first m093b1 (#1) */ if (cross >=6) { j=cross+2; } else { j=cross; } } if (cross>12) { port=0xC007; /* point to the second m093b1 (#2) */ if (cross>=19) { j=(cross-12)+2; } else { j=(cross-12); } } j=j*0x10; /* move to most significant nibble */ j=j+0x08; /* set bit 3 (0000 1000) means to connect */ j=j+path; /* i is control block/path so add it too. */ *port=j; /* send the constructed control byte to the xpoint */ #ifdef DEBUG printf("CONNECT cross:%02 path:%02x port:%02x control word %02x \n" ,cross,path,port,j); #endif } INTERRUPT(_TF0_) clock_int_handler() { unsigned char *port; /* use a local variable register in interupt */ unsigned char i; clrbit(IE.7); tens++; rfreq++; if (rfreq==5) rfreq=0; if (tens==10) { tens=0; hundsec++; /* update the dast used segment directory */ for (i=0;i=0 && rfreq<=1) { /* reset bit 6 set bit 5 */ shadow_D006=shadow_D006 & 0x1F; /* clear upper 3 bits */ shadow_D006=shadow_D006 | 0x20; /* set bit 5 */ *port=shadow_D006; } else if (rfreq>=2 && rfreq<=3) { shadow_D006=shadow_D006 & 0x1F; /* clear upper 3 bits */ shadow_D006=shadow_D006 | 0x40; /* set bit 6 */ *port=shadow_D006; } } else { port=0xD006; shadow_D006=shadow_D006 | 0x60; /* set bits 5 and 6 */ *port=shadow_D006; } if (ring_trip > 3) /* This is 3/100 of a second */ { ring_hv=0; /* turn off ring generator coils */ ring_trip++; } if (ring_trip>20) { shadow_D006=shadow_D006 | 0x60; /* set bits 5 and 6 */ *port=shadow_D006; shadow_D000=0x00; /* open all ringing relays */ port=0xD000; *port=shadow_D000; shadow_D002=0x00; port=0xD002; *port=shadow_D002; } TL0=0; TH0=0; /* Reset TH0 */ setbit(IE.7); } set_timer_int() { /* Setup timer 0 to create an interupt 100 times per second. */ clrbit(TMOD.3); /* Gate=0 in TMOD, indicates internal count of clock */ clrbit(TMOD.2); /* C/T=0 in TMOD, indicating counter mode */ clrbit(TMOD.1); /* M1=0 in TMOD */ setbit(TMOD.0); /* M0=1 in TMOD & M1=0 indicates timer mode 1 */ setbit(IP.1); /* PT0=0 in IP, indicating timer 0 int. is low prio. */ TL0=0x00; /* Set TL0 to 31 hex */ TH0=0x00; setbit(TCON.4); /* TR0=1 in TCON, indicating RUN */ setbit(IE.7); setbit(IE.1); } /* Extention Service Routines */ f_exhm() { /* Extention Off Hook Monitor */ unsigned char i,j,k; if (k=off_hook(0xff)) /* Is the phone off hook? */ { if (ext_status[ext_check] == IDLE) /* is phone not assigned to a CCB?*/ { /* no ccb assigned, locate a free ccb and assign it */ for (i=0; i=0) & (ext_route[ext_check]<=0x10)) { ext_process[ext_check]=99; clear_common(); /* remove this if we want fake ringback */ #ifdef DEBUG printf("f_exdm changed station process to 99\n"); #endif return; } /* check for an extention call after dialing timer has expired */ if ((ext_timer[ext_check]==0) && ((ext_route[ext_check]>0x2F) && (ext_route[ext_check]<0x40))) { #ifdef DEBUG printf("Extention call placed \n"); #endif /* route is between 0x30 - 0x40 so we have dialed */ /* another station on the system. 1st check to see */ /* if the called station is busy */ /* determine the physical port number */ i=ext_route[ext_check]-0x30; /* route 0x31 becomes port 0x01 */ /* i is now the physical port number */ if ((ext_process[i]==1) && (off_hook(i)==0)) { #ifdef DEBUG printf("Destination is idle \n"); #endif /* the port being called is indeed idle */ ext_process[i]=66; /* ring the called station */ ext_status[i]=ext_status[ext_check]; /* associate the dest ccb with the source ccb */ ext_process[ext_check]=37; /* we get ringback tone */ return; } else { #ifdef DEBUG printf("Destination is busy \n"); #endif ext_process[ext_check]=38; /* give busy tone while offhook */ ext_timer[ext_check]=lock_out*100; /* setup for lockout */ return; } } if ((j=*port) & 0x10) /* quiet, qaiting for tones */ { if ((j=j & 0x0F)==0x0A) j=0; /* convert 0x0a to 0x00 */ #ifdef DEBUG printf("Digit detected %02x \n",j); #endif ext_process[ext_check]=34; /* we hear a tone */ /* Store the digit away */ if (ccb_enque[ccb] < maxdigits) { ext_timer[ext_check]=inter_digit*50; /*load interdigit timeout timer */ #ifdef DEBUG printf("ccb_enque[%02x] = %02x ",ccb, ccb_enque[ccb]); #endif ccb_digits[ccb][ccb_enque[ccb]]=j; ccb_enque[ccb]++; /* advance the enque pointer */ /* remove any tones being supplied */ cpg(SILENCE); search(ccb_enque[ccb]); /* see if what user has dialed matches a route table */ /* search routine updates stations route */ } else { #ifdef DEBUG printf("Max digit collection exceeded.\n"); #endif } } } else if (ext_process[ext_check]==34) /* waiting for quiet */ { if (!(*port & 0x10)) /* see if we still hear a tone */ { ext_process[ext_check]=33; } } else if (ext_process[ext_check]==35) /* proc 35 = station error occured, reorder tone being played */ { /* Give reorder tone while offhook */ ext_timer[ext_check]--; if (ext_timer[ext_check]==0) /* dialing time expired do lockout */ { cleanup(); /* Cleanup ? */ ext_process[ext_check]=36; /* lockout station */ } if (hundsec & 0x04) /* 0110 0000 */ { /* turn tones on */ if (ext_substate[ext_check] != 0) { ext_substate[ext_check]=0; cpg(REORDER); } } else { /* turn tones off */ if (ext_substate[ext_check] != 1) { ext_substate[ext_check]=1; cpg(SILENCE); } } } else if (ext_process[ext_check]==36) /* proc 36 = station locked out waiting for onhook */ { /* dont do anything , just wait around until on hook */ } else if (ext_process[ext_check]==37) { /* we give ringback tone wait until station */ /* in route goes into conversation mode. we then */ /* free up any common controls associated with our */ /* CCB (recievers/senders) and go into conversation */ /* mode ourselves */ if ((second & 0x03)==3) /* 0000 0011 = 0000 0011 */ { /* turn tones on */ if (ext_substate[ext_check] != 0) { ext_substate[ext_check]=0; cpg(RING); } } else { /* turn tones off */ if (ext_substate[ext_check] != 1) { ext_substate[ext_check]=1; cpg(SILENCE); } } i=ext_route[ext_check]-0x30; /* point to dest */ if (ext_process[i]==98) /* dest has answered */ { clear_common(); /* release common control */ ext_process[ext_check]=98; /* go into conversation ourselves */ } } else if (ext_process[ext_check]==38) /* do busy tone while offhook */ { ext_timer[ext_check]--; if (ext_timer[ext_check]==0) /* dialing time expired do lockout */ { cleanup(); /* Cleanup ? */ ext_process[ext_check]=36; /* lockout station */ } if (second & 0x01) /* 0110 0000 */ { /* turn tones on -busy */ if (ext_substate[ext_check] != 0) { ext_substate[ext_check]=0; cpg(LOBELL); } } else { /* turn tones off */ if (ext_substate[ext_check] != 1) { ext_substate[ext_check]=1; cpg(SILENCE); } } } return; /* we found associated reciever- why continue */ } } } else { /* Phone is no longer off hook */ if (ext_route[ext_check]>0x29 & ext_route[ext_check]<0x40) { i=ext_route[ext_check]-0x30; ext_process[i]=67; /* command destination to exit ringing */ } else if (ext_route[ext_check]>=0 & ext_route[ext_check]<=0x0A) { for (i=0;i5) { if (off_hook(0xFF)) { if (ext_substate[ext_check]!=1) { ring_hv=0; ext_timer[ext_check]=0; ext_substate[ext_check]=1; } else { connect(ccb); ext_process[ext_check]=98; } } else { if ((second & 0x03)==3) { /* we are in the ringing cycle */ if (ext_substate[ext_check] !=2) /* lets not keep reseting rint_trip */ { ring_relay(1); ext_substate[ext_check]=2; ring_hv=1; ring_trip=0; } } else { if (ext_substate[ext_check]!=0) { ring_hv=0; ext_timer[ext_check]=0; ext_substate[ext_check]=0; } else { ring_relay(0); } } } } else { ext_timer[ext_check]++; } } else if (ext_process[ext_check]==67) { /* exit ringing mode, stop any current */ /* ringing cycles on the hardware clean */ /* up any data if necissary and change */ /* ext process back to a 1 */ ring_hv=0; ext_process[ext_check]=68; ext_timer[ext_check]=0; } else if (ext_process[ext_check]==68) { /* This is the post ringing debounce cycle */ ext_timer[ext_check]++; if (ext_timer[ext_check]>5) { ring_relay(0); cleanup(); ext_process[ext_check]=1; } } } f_excm() /* Extention Conversation Monitor EXCM */ { /* checks for onhooks , determines if flash has */ /* occured, initiates conferencing if so, */ /* generates smdr records or call pricing ticket */ /* touch tone administration */ /* 98 - */ char i,j,k; ccb=ext_status[ext_check]; if (ext_process[ext_check]==98) /* ext to ext conversation monitor */ { if (!off_hook(0xFF)) { /* station has hung up, clear everything */ cleanup(); ext_process[ext_check]=1; /* go to check for off hook */ } else { } } else if (ext_process[ext_check]==99) { if (!off_hook(0xFF)) { /* locate the associated trunk and can it */ /* check to see if acp is IDLE */ /* if so then locate trunk by ccb else */ /* locate the trunk by acp */ if (ccb_acp[ccb]==IDLE) { /* trunk is cut throught because we dont have a seperate acp */ for (i=0;i=100 && ext_process[ext_check]<=128) { if (!off_hook(0xFF)) { cleanup(); ext_process[ext_check]=1; return; } } if (ext_process[ext_check]==100) /* enter programming from tt phone */ { ext_substate[ext_check]=2; /* beep twice to confirm programing entry */ ext_return[ext_check]=103; /* after beeping twice goto get register routine */ ext_process[ext_check]=101; /* goto sound tones routine */ return; } else if (ext_process[ext_check]==101) /* sound hi bell for short period */ { if (ext_timer[ext_check]==0) { ext_timer[ext_check]=20; cpg(HIBELL); ext_process[ext_check]=102; } else { ext_timer[ext_check]--; } return; } else if (ext_process[ext_check]==102) /* sound silence for short period */ { if (ext_timer[ext_check]==0) { ext_timer[ext_check]=20; cpg(SILENCE); ext_substate[ext_check]--; if (ext_substate[ext_check]!=0) { ext_process[ext_check]=101; } else { ext_process[ext_check]=ext_return[ext_check]; } } else { ext_timer[ext_check]--; } return; } else if (ext_process[ext_check]==103) { /* collect a digit to see which maint routine to jump to */ ccb_enque[ccb]=0x00; /* reset the digit collection pointer */ ext_temp[ext_check]=1; /* collect one digit */ ext_return[ext_check]=106; /* goto 106 to process it */ ext_process[ext_check]=104; return; } for (i=0;i15)) /* if not more than 0 or less than 15 signal error */ { ext_substate[ext_check]=10; /* signal error */ ext_return[ext_check]=103; /* goto get register routine */ ext_process[ext_check]=101; /* goto sound tones routine */ return; } /* scan directory for this message and delete it if it exists */ for (rap[i]=0xFF00;rap[i]<0xFFFF;rap[i]++) { if (*rap[i]==(radm[i] & 0x0F)) *rap[i]=0x00; } /* scan directory for the first blank message space */ for (rap[i]=0xFF00;rap[i]<0xFFFF;rap[i]++) { if (*rap[i]==0x00) break; } #ifdef DEBUG printf("First blank segment *rap[i] set to %04x\n",rap[i]); #endif /* address the dast to this space */ if (i==0) { port=0xD002; *port=rap[i]-0xff00; } ext_substate[ext_check]=1; /* beep once */ ext_return[ext_check]=110 ; /* after beeping */ ext_process[ext_check]=101; /* goto sound tones routine */ return; } else if (ext_process[ext_check]==110) { /* command dast to begin recording here */ for (i=0;i15)) { ext_substate[ext_check]=10; ext_return[ext_check]=103; ext_process[ext_check]=101; return; } /* scan directory for message starting point */ for (rap[i]=0xff00;rap[i]<0xffff;rap[i]++) { if (*rap[i]==(radm[i] & 0x0f)) break; } /* if message is not in directory then signal error */ if (rap[i]==0xffff) { ext_substate[ext_check]=10; ext_return[ext_check]=103; ext_process[ext_check]=101; return; } /* address the dast to the message */ if (i==0) { port=0xD002; *port=rap[i]-0xff00; #ifdef DEBUG printf("DAST address %04x\n",rap[i]-0xff00); #endif } /* start the DAST device playing */ j=0xFB; P1=j; /* set PD high */ j=0xF9; P1=j; /* set PD low now */ j=0xFD; P1=j; /* set P/R to high for playback */ j=0xFC; P1=j; /* set /CE to low */ j=0xFD; P1=j; /* set /CE to high, this will start playback */ #ifdef DEBUG printf("Dast playing message "); #endif ext_process[ext_check]=113; /* goto wait for end of message */ return; } else if (ext_process[ext_check]==113) { /* the rad is playing , wait for it to stop */ /* look to P1 bit 4 to go high, then disconnect the dast */ /* idle it and exit */ for (i=0;i0) /* we need to delay for the dast to settle */ { ext_timer[ext_check]--; return; } for (i=0;i 15) return; /* we only search through 15 digits, ignoring all others */ for(x=table_pointer_begin[length] ;x0x0b) { /* search wildcards here */ switch(table_8xx[y+x]) { case 0x0c: /* compare against user dialed # */ if (ccb_digits[ccb][y]==0x0c) { match=1; } else { match=0; } break; case 0x0d: /* compare against a user dialed 0 or 1 */ if ((ccb_digits[ccb][y]==0x01) | (ccb_digits[ccb][y]==0x00)) { match=1; } else { match=0; } break; case 0x0e: /* compare against any user dialed digit 2-9 */ for (i=2;i<=9;i++) { if (ccb_digits[ccb][y]==i) { match=1; break; } else { match=0; break; } } break; case 0x0f: /* compare against anything */ match=1; break; } } else { /* search exact match */ if (ccb_digits[ccb][y]==table_8xx[y+x]) { match=1; } else { match=0; break; } } } if (match==1) { #ifdef DEBUG printf("Match found %x\n",table_8xx[y+x]); #endif if(((table_8xx[y+x]>=0)&(table_8xx[y+x]<=0x10)) | ((table_8xx[y+x]>=0x30) & (table_8xx[y+x]<=0x40))) { #ifdef DEBUG printf("ext_route updated \n"); #endif ext_route[ext_check]=table_8xx[y+x]; /* update route table */ } else { /* or change ext process to go to programming */ /* or change ext process to go to speed dial or alarm call */ /* or personal speed programming */ switch(table_8xx[y+x]) { case 0x21: /* deny this call */ ext_timer[ext_check]=lock_out*50; ext_route[ext_check]=0x27; /* do nothing */ ext_process[ext_check]=35; /* give re-order */ break; case 0x24: /* go into touch tone programming mode */ ext_route[ext_check]=0x24; ext_process[ext_check]=100; ext_timer[ext_check]=0; break; case 0x26: /* last digit of phone number dialed */ if (ext_route[ext_check]!=0x27) { /* we have a route in process */ ext_timer[ext_check]=1; /* extention dialing monitor will update process based on route */ } else { /* no route yes selected and dialing is finished */ /* send to re-order tone */ ext_timer[ext_check]=lock_out*50; ext_process[ext_check]=35; /* give ro-order */ } break; } } return; /* exact match found return */ } #ifdef DEBUG printf("\n"); #endif } } clear_common() { char i,j; for (i=0;i7) { port=port+2; k=ext_check-8; } else { k=ext_check; } for (i=1; i <= k;i++) { j=j+j; /* j now contains bit to AND against */ } /* port contains port number to READ from */ if (port==0xD000) { if (state==1) /* we want to set */ { shadow_D000=shadow_D000 | j; *port=shadow_D000; } else { /* we want to reset */ j=0xFF-j; shadow_D000=shadow_D000 & j; *port=shadow_D000; } } else if (port==0xD002) { if (state==1) /* we want to set */ { shadow_D002=shadow_D002 | j; *port=shadow_D002; } else { /* we want to reset */ j=0xFF-j; shadow_D002=shadow_D002 & j; *port=shadow_D002; } } } do_route() { /* This process runs once after all the extention's have */ /* been processed. When it runs it processes one active ccb */ /* and then returns. So if four ccb's are active it takes four */ /* trips around to update them all. */ char i,j,k; route_update_next++; if (route_update_next==maxpath+1) { route_update_next=0; } /* search for a active ccb */ if (ccb_path[route_update_next]!=IDLE) { /* we found active ccb */ for (j=0;j=0 & ext_route[j]<=0x0C) { for (i=0;i<16;i++) { k=acs[((ext_route[j]-1)*7)+6][i]; /* k points to trunks in acs */ #ifdef DEBUG printf("do route looking at trunk %02x process=%02x \n",k,trunk_process[k]); #endif if (k==0xFF) break; /* end of list, check again later */ if (trunk_process[k] == 1) { /* this trunk is not busy */ #ifdef DEBUG printf("route activated %02x \n",k); #endif trunk_status[k]=route_update_next; /* associate ccb */ trunk_process[k]=65; ccb_route[route_update_next]=ext_route[j]; /* update the route */ break; } } } else { ccb_route[route_update_next]=ext_route[j]; } } return; } } } } acs_add(rte,reg,che) unsigned char rte; unsigned char reg; unsigned char *che; { unsigned char i,j,k; i=0; while (*(che-1) != 0xFF) { acs[((rte-1)*7)+reg][i]=*che; #ifdef DEBUG printf("%02x",*che); #endif i++; che++; } #ifdef DEBUG printf(" \n"); #endif } defx() /* default volatile database */ { unsigned char i,j; printf("Default data loaded\n"); /* clear misc data memory */ for (port=0xFF00;port<0xFFFF;port++) { *port=0x00; } /* set up default route tables */ init_tables(); add(4,"\x09\x05\x00\x01"); /* send 950 to route 1 */ add(4,"\x0F\x0F\x0C\x26"); /* #9 #9 # end of dialing */ add(3,"\x0C\x0C\x24"); /* ## programming security code */ add(3,"\x04\x00\x30"); /* ext 40 route to port 10 */ add(3,"\x04\x01\x31"); /* ext 41 route to port 11 */ add(3,"\x04\x02\x32"); /* ext 42 route to port 12 */ add(3,"\x04\x03\x33"); /* ext 43 route to port 13 */ add(2,"\x03\x01"); /* send 3 anything to route 1 */ add(2,"\x06\x01"); /* send 6 anything to route 1 also */ add(2,"\x02\x01"); /* send 2 anything to route 1 */ add(2,"\x07\x01"); /* send 7 anything to route 1 */ add(2,"\x05\x04"); /* send 5 anything to route 4 */ add(2,"\x08\x21"); /* deny 8 anything calls */ add(2,"\x00\x02"); /* 0 anything to route 2 */ add(2,"\x01\x03"); /* 1 anything to route 3 */ /* Clear all route registers - Routes 1-X Registers 1-X */ for (i=0;i %04x\n",dtime); rtp=0; } } } #endif /* dispatch extentions */ ext_check=0; do { cross=ext_check; /* so we know which port to connect to */ if (ext_process[ext_check] >= 0 && ext_process[ext_check] <=32) f_exhm(); else if (ext_process[ext_check] >= 33 && ext_process[ext_check] <=64) f_exdm(); else if (ext_process[ext_check] >= 65 && ext_process[ext_check] <=96) f_exsm(); else if (ext_process[ext_check] >= 97 && ext_process[ext_check] <=128) f_excm(); ext_check++; /* Point to next extention equipt. to service */ } while (ext_check < maxstat); /* Process from 0-15 */ do_route(); /* Now update routes */ } } check_sum(ch) char ch; { int *l; int k; char *m; printf("Regs: SP: %02x \n",SP); l=0x0008; /* point to external stack pointer */ printf("External Stack Pointer: %04x \n",*l); /* Perform checksum of CODE space */ k=0; /* start the checksum at 0 */ printf("CODE Checksum running... "); for (m=0x2000;m<0xBFFF;m++) { k = k + *m; } printf("%04x\n",k); }