#include "comcs.h" unsigned char comcs_cmd[132]; //all sendings, excepting the i' am here //are only possible if this is not 0 int comcs_available = 0; int comcs_timeout = 0; #ifdef ELAPP_C167 void loop1_10ms( unsigned int nr ) { unsigned int i; int ct = 0; while( ct < nr ){ for(i=0;i<200;i++){;} ct++; } } #endif #ifdef ELAPP_UNC20 void loop1_10ms( unsigned int nr ) { unsigned long _ct; unsigned long _fix = 625; unsigned int ct = 0; while( ct < nr ){ _ct = 0; while( _ct < _fix ){ _ct++; } ct++; } } #endif /* the low-level one char receiver/sender functions used by transports cmd's/strings, .... not for setting the comcs_lookup-flags. */ unsigned char comcs_rcv( void ) { unsigned char val; //first we show, that we are ready to receive //setting complete output to 0x01 CSCOMCS_W = 0x01; //then we wait till sender is ready to send //showing it by setting bit 8 low while( (CSCOMCS_R & 0x80) != 0 ){;} //ok now the byte should be valid val = CSCOMCS_R; //we show, that we have the byte, setting to 0xff //so general after sending port has always a value //which can not be misunderstand by sending functions //( also if this is the last byte to receive ) CSCOMCS_W = 0xff; //waiting till sender is ready while( CSCOMCS_R != 0xff ){;} return(val); } void _comcs_scv( unsigned char val ){ //first we wait till receiver is ready //indicated by port complete 0 while( CSCOMCS_R != 0x01 ){;} //then we set the byte indicated by high bit = low CSCOMCS_W = val & 0x7f; //then we wait till receiver has the byte acknowledged //by a 0xff while( CSCOMCS_R != 0xff ){;} //setting bit 8 high, and general //to a value which cannot be complicated for //comcs_lookup, if this is the last byte to send CSCOMCS_W = 0xff; } unsigned char comcs_rcv_hl( void ) { unsigned char low,high,val; high = comcs_rcv() << 4; low = comcs_rcv(); high = high & 0xf0; low = low & 0x0f; val = high | low; return( val ); } void _comcs_scv_hl( unsigned char val ){ unsigned char high,low; high = val >> 4; high = high & 0x0f; _comcs_scv( high ); low = val & 0x0f; _comcs_scv( low ); } int _comcs_porttest( void ) { unsigned int ct; unsigned char val; ct = 0x00; val = CSCOMCS_R; //max wait for timeout 500 ms. while( ( ct < 5000 ) && ( val != 0xff ) ){ //looking every 1_10 ms. loop1_10ms( 0x01 ); val = CSCOMCS_R; ct++; } if( val != 0xff ){ comcs_timeout = 1; CSCOMCS_W = 0xff; return(0); } return(1); } /* the sender functions */ int _comcs_shootup( unsigned char cmd ){ unsigned int ct; unsigned char val; ct = 0; val = CSCOMCS_R; //max wait for timeout 5 sec. while( ( ct < 5000 ) && ( val != 0xff ) ){ //looking every 1 ms. loop1_10ms(10); val = CSCOMCS_R; ct++; } if( val != 0xff ){ comcs_timeout = 1; CSCOMCS_W = 0xff; return(0); } CSCOMCS_W = cmd; ct = 0; val = CSCOMCS_R; //max wait for timeout 5 sec. while( ( ct < 5000 ) && ( val != cmd ) ){ //looking every 1 ms. loop1_10ms(10); val = CSCOMCS_R; ct++; } CSCOMCS_W = 0xff; if( val != cmd ){ comcs_timeout = 1; return(0); } ct = 0; val = CSCOMCS_R; //max wait for comcs_lookup ready 500 ms while( ( ct < 500 ) && ( val != 0xff ) ){ //looking every 1 ms. loop1_10ms(10); val = CSCOMCS_R; ct++; } if( val != 0xff ){ comcs_timeout = 1; return(0); } return(1); } int comcs_start( void ){ if( comcs_available ){ return(1); } if(! _comcs_shootup( COMCS_LOOKUP_STARTS )){ return(0); } comcs_available = 1; comcs_timeout = 0; return(1); } int comcs_end( void ){ if( ! comcs_available ){ return(1); } comcs_available = 0; return( _comcs_shootup( COMCS_LOOKUP_ENDS )); } int comcs_send_programend( void ){ if( ! comcs_available ){ return(0); } comcs_available = 0; return( _comcs_shootup( COMCS_LOOKUP_PROGRAMEND )); } int comcs_send_cmd( unsigned char cmd ){ if( comcs_available ){ if( ! _comcs_porttest() ){ return(0); } CSCOMCS_W = COMCS_LOOKUP_CMD; _comcs_scv_hl( cmd ); return(1); } else { return(0); } } int comcs_send_strcmd( unsigned char cmd, unsigned char param, unsigned char *buf ){ unsigned char ct; if( comcs_available ){ if( ! _comcs_porttest() ){ return(0); } CSCOMCS_W = COMCS_LOOKUP_CMDSTR; _comcs_scv(cmd); _comcs_scv(param); ct = 0; while( ( ct < 128 ) && ( buf[ct] != 0 ) && ( buf[ct] != 0x0d ) && ( buf[ct] != 0x0a ) ){ _comcs_scv( buf[ct] ); ct++; } _comcs_scv( 0 ); return(1); } else { return(0); } } int comcs_send_bincmd( unsigned char cmd, unsigned char len, unsigned char *buf ){ unsigned char ct; if( comcs_available ){ if( ! _comcs_porttest() ){ return(0); } CSCOMCS_W = COMCS_LOOKUP_CMDBIN; _comcs_scv_hl(cmd); _comcs_scv_hl(len); ct = 0; while( ( ct < len ) && ( ct < 128 ) ){ _comcs_scv_hl( buf[ct] ); ct++; } return(1); } else { return(0); } } #ifdef ELAPP_UNC20 int comcs_send_h86file( char *filename ){ int ct; unsigned char str[132]; FILE *fp; if( ( ! comcs_available ) || ( ! _comcs_porttest()) ){ return(0); } fp = fopen(filename,"rt"); if( fp == NULL ){ return(0); } CSCOMCS_W = COMCS_LOOKUP_STRH86; rewind(fp); while( feof(fp) == 0 ){ fgets(str,130,fp); if(str[0] != 0x3a){ continue; } ct = 0; while( ( ct < 128 ) && ( str[ct] != 0x00 ) && ( str[ct] != 0x0d ) && ( str[ct] != 0x0a ) ){ _comcs_scv( str[ct] ); ct++; } _comcs_scv( 0x00 ); } _comcs_scv( 0x30 ); _comcs_scv( 0x30 ); _comcs_scv( 0x30 ); _comcs_scv( 0x00 ); fclose(fp); return(1); } int comcs_send_h86file_and_start( char *filename ){ if( comcs_available ){ if( comcs_send_h86file( filename )){ return(comcs_send_programend()); } } return(0); } #endif /* ---------------------- the receiver functions ---------------------- */ #ifdef ELAPP_C167_BASE unsigned char h86charhextochar( unsigned char val ) { if( ( val >= '0') && ( val <= '9')){ return( val - '0' ); } if( ( val >= 'A') && ( val <= 'F')){ return( val - 'A' + 10 ); } if( ( val >= 'a') && ( val <= 'f')){ return( val - 'a' + 10 ); } return(0); } unsigned char h86char2hextochar( unsigned char * p){ unsigned char v; v = h86charhextochar( p[0] ); v = v << 4; v = v & 0xf0; v = v + h86charhextochar( p[1] ); return( v ); } unsigned int h86char4hextoint( unsigned char * p){ unsigned int v; v = h86char2hextochar( &p[0] ); v = v << 8; v = v & 0xff00; v = v + h86char2hextochar( &p[2] ); return( v ); } unsigned int h86ltr_seg; int h86loadToRam( void ) { unsigned int addr; unsigned int nr; unsigned char type; unsigned char val; int ct; if( comcs_cmd[0] != 0x3a){ return(0); } ct = 1; nr = ( unsigned int ) h86char2hextochar( &comcs_cmd[ct] ); ct = ct + 2; addr = h86char4hextoint( &comcs_cmd[ct] ); ct = ct + 4; type = h86char2hextochar( &comcs_cmd[ct] ); if( type == 1 ){ return( 0 ); } if( type == 2 ){ //8086 segment address record ct = ct + 2; h86ltr_seg = 0; h86ltr_seg = h86char4hextoint( &comcs_cmd[ct] ); if( h86ltr_seg > 0 ){ h86ltr_seg = h86ltr_seg / 0x1000; } return(1); } if( type == 4 ){ //extended linear address mode ct = ct + 2; h86ltr_seg = h86char4hextoint( &comcs_cmd[ct] ); return(1); } if( type == 0 ){ while( nr > 0 ){ ct = ct + 2; val = h86char2hextochar( &comcs_cmd[ct] ); // now write it to ram writeFarByte( h86ltr_seg, addr, val ); addr++; nr--; } } return(1); } #endif /* the generally function, which should be used in both sides in the normally mainloop it looks, if the other is available, or send something if there is only a 0xff, or 0 on port which means the other is not valid, or has no stuff to send, then it returns immediately with 0 ( COMCS_LOOKUP_NOTHING ). all other stuff will be handled by this function. the returnvalues depends on the type of receive. see the definitions COMCS_LOOKUP_X */ unsigned char comcs_lookup( void ){ unsigned char nr,ct; unsigned char val = CSCOMCS_R; //direct command values are only the last 4 bits if( ( val == 0xff ) || ( val == 0x00 ) || (( val & 0xf0 ) != 0x80 ) ){ //CSCOMCS_W = 0xff; return( COMCS_LOOKUP_NOTHING); } switch( val ){ //the i'm here answer flag case COMCS_LOOKUP_STARTS: if( ! comcs_available ){ CSCOMCS_W = COMCS_LOOKUP_STARTS; //hold it for 50 ms loop1_10ms( 500 ); CSCOMCS_W = 0xff; comcs_available = 1; return(COMCS_LOOKUP_STARTS); } break; //only a binary byte as command case COMCS_LOOKUP_CMD: if( comcs_available ){ //receive commandbyte now val = comcs_rcv_hl(); comcs_cmd[0] = val; CSCOMCS_W = 0xff; return( COMCS_LOOKUP_CMD); } break; case COMCS_LOOKUP_CMDSTR: if( comcs_available ){ //receive string now ct = 0; val = 0xff; while( (ct < 132) && (val != 0x00) ){ val = comcs_rcv(); comcs_cmd[ct] = val; ct++; } comcs_cmd[ct] = 0; CSCOMCS_W = 0xff; return( COMCS_LOOKUP_CMDSTR ); } break; case COMCS_LOOKUP_CMDBIN: if( comcs_available ){ //receive buffer now val = comcs_rcv_hl(); nr = comcs_rcv_hl(); comcs_cmd[0] = val; comcs_cmd[1] = nr; ct = 0; while( (ct < nr) && (ct < 128) ){ val = comcs_rcv_hl(); comcs_cmd[ct + 2] = val; ct++; } CSCOMCS_W = 0xff; return( COMCS_LOOKUP_CMDBIN ); } break; //the i'm no more here flag case COMCS_LOOKUP_ENDS: if( comcs_available ){ comcs_available = 0; comcs_timeout = 0; CSCOMCS_W = COMCS_LOOKUP_ENDS; loop1_10ms( 500 ); CSCOMCS_W = 0xff; return( COMCS_LOOKUP_ENDS ); } break; #ifdef ELAPP_C167_BASE //a special only for c167-side case COMCS_LOOKUP_STRH86: if( comcs_available ){ //receive H86-file now, and store comcs_cmd[0] = 0x3a; while( comcs_cmd[0] == 0x3a){ ct = 0; val = 0xff; while( (ct < 130) && (val != 0x00)){ val = comcs_rcv(); comcs_cmd[ct] = val; ct++; } h86loadToRam(); } CSCOMCS_W = 0xff; return( COMCS_LOOKUP_STRH86 ); } break; #endif //the generally programend case COMCS_LOOKUP_PROGRAMEND: if( comcs_available ){ comcs_available = 0; comcs_timeout = 0; CSCOMCS_W = COMCS_LOOKUP_PROGRAMEND; loop1_10ms( 500 ); CSCOMCS_W = 0xff; return( COMCS_LOOKUP_PROGRAMEND ); } break; default: break; } CSCOMCS_W = 0xff; return( COMCS_LOOKUP_NOTHING ); } void system_reboot( void ){ if( comcs_start() ){ comcs_send_cmd( COMCS_CMD_REBOOT ); } //not necessary comcs_available = 0; #ifdef ELAPP_C167 reset_to_rom(); #else system("reboot"); exit(0); #endif }