Example #1
0
BOOL SBBSExecInt14::handler(VMHANDLE hVM, CLIENT_STRUCT* pRegs, DWORD intno)
{
	BYTE*	buffer;
	BYTE	ch;
	WORD	buflen;
    WORD	rd,wr;
    WORD	avail;
	vm_t*	vm = find_vm(hVM);

	if(vm==NULL || vm->mode!=SBBSEXEC_MODE_FOSSIL) {
		return(FALSE); // Tells VMM that interrupt was not handled
	}


	DBTRACEx(4,"Int14 func",_clientAH);

	switch(_clientAH) {
		case 0x00:	/* Initialize/Set baud rate */
        	DBTRACE(0,"Int14 init");
			_clientAX=PortStatus(vm);
			break;
		case 0x01: /* write char to com port */
        	if(RingBufFree(&vm->out)<2) {
            	DBTRACEx(1,"!OUTPUT BUFFER OVERFLOW, hVM", hVM);
            	vm->output_sem=Create_Semaphore(0);
                Wait_Semaphore(vm->output_sem,BLOCK_THREAD_IDLE);
                Destroy_Semaphore(vm->output_sem);
                vm->output_sem=NULL;
                if(!vm->online) {
                	DBTRACE(0,"!USER HUNG UP");
                	return(true);
                }
            }
			ch=_clientAL;
			RingBufWrite(&vm->out,&ch,1);
#if 0	/* Now done in SBBS.DLL/XTRN.CPP */
			if(ch==0xff) { /* escape TELNET IAC */
				RingBufWrite(&vm->out,&ch,1);
				DBTRACE(1,"Escaped IAC in output stream");
			}
#endif
			vm->overrun=false;
			_clientAX=PortStatus(vm);
			break;
		case 0x02: /* read char from com port */
			if(!RingBufFull(&vm->in)) {
            	DBTRACEx(0,"Waiting on input semaphore, hVM", hVM);
            	vm->input_sem=Create_Semaphore(0);
                Wait_Semaphore(vm->input_sem,BLOCK_THREAD_IDLE);
                Destroy_Semaphore(vm->input_sem);
                vm->input_sem=NULL;
#if 0
				_clientAH=0x80;	/* timed-out */
				return(TRUE);
#endif
			}
			RingBufRead(&vm->in,&ch,1);
			_clientAH=0;
			_clientAL=ch;
			break;
		case 0x03:	/* request status */
			_clientAX=PortStatus(vm);
			break;
		case 0x04:	/* initialize */
			DBTRACE(0,"Int14 func 4 init");
			_clientAX=0x1954;	/* magic number = success */
			_clientBH=5;		/* FOSSIL rev */
			_clientBL=0x1B;		/* maximum FOSSIL func supported */
			break;
        case 0x08:	// flush output buffer
            DBTRACE(0,"Int14 FLUSH OUTPUT BUFFER");
            vm->output_sem=Create_Semaphore(0);
            Wait_Semaphore(vm->output_sem,BLOCK_THREAD_IDLE);
            Destroy_Semaphore(vm->output_sem);
            vm->output_sem=NULL;
			break;
        case 0x09:	// purge output buffer
        	DBTRACE(0,"Int14 PURGE OUTPUT BUFFER");
        	RingBufReInit(&vm->out);
            break;
        case 0x0A:	// purge input buffer
        	DBTRACE(0,"Int14 PURGE INPUT BUFFER");
        	RingBufReInit(&vm->in);
            break;
		case 0x0B: /* write char to com port, no wait */
        	if(RingBufFree(&vm->out)<2) {
            	_clientAX=0; // char was not accepted
                break;
            }
			ch=_clientAL;
			RingBufWrite(&vm->out,&ch,1);
#if 0	/* Now done in SBBS.DLL/XTRN.CPP */
			if(ch==0xff) { /* escape TELNET IAC */
				RingBufWrite(&vm->out,&ch,1);
				DBTRACE(1,"Escaped IAC in output stream");
			}
#endif
			_clientAX=1; // char was accepted
			break;
        case 0x0C:	// non-destructive read-ahead
			if(!RingBufFull(&vm->in)) {
				_clientAX=0xffff;	// no char available
				break;
			}
			RingBufPeek(&vm->in,&ch,1);
			_clientAH=0;
			_clientAL=ch;
			break;
		case 0x13:	/* write to display */
			dprintf("%c",_clientAL);
			break;
        case 0x18:	/* read bock */
        	rd=_clientCX;
            avail=RingBufFull(&vm->in);
            if(rd>avail)
            	rd=avail;
            if(rd) {
	            buffer = (BYTE*)MAPFLAT(CRS.Client_ES, CWRS.Client_DI);
                rd = RingBufRead(&vm->in, buffer, rd);
            }
            _clientAX = rd;
            break;
        case 0x19:	/* write block */
			wr=_clientCX;
            avail=RingBufFree(&vm->out);
            if(wr>avail)
            	wr=avail;
            if(wr) {
	            buffer = (BYTE*)MAPFLAT(CRS.Client_ES, CWRS.Client_DI);
                wr = RingBufWrite(&vm->out, buffer, wr);
            }
            _clientAX = wr;
            break;
#if 1
        case 0x1B:	// driver info
        {
        	DBTRACE(1,"Int14 driver info");
            struct {
                WORD    info_size;
                BYTE	curr_fossil;
                BYTE	curr_rev;
                DWORD	id_string;
                WORD	inbuf_size;
                WORD	inbuf_free;
                WORD	outbuf_size;
                WORD	outbuf_free;
                BYTE	screen_width;
                BYTE	screen_height;
                BYTE	baud_rate;
            } info={ sizeof(info), 5, 1, 0
            		,RINGBUF_SIZE_IN-1, RingBufFree(&vm->in)
                    ,RINGBUF_SIZE_OUT-1, RingBufFree(&vm->out)
                    ,80,25
                    ,1 // 38400
                    };
//			Map_Lin_To_VM_Addr
			buffer = (BYTE*)MAPFLAT(CRS.Client_ES, CWRS.Client_DI);
            wr=sizeof(info);
            if(wr>_clientCX)
            	wr=_clientCX;
            memcpy(buffer, &info, wr);
        	_clientAX=wr;
            break;
		}
#endif
		default:
			DBTRACEx(0,"!UNHANDLED INTERRUPT 14h function",_clientAH);
			break;
	}
	return(TRUE);	// Tells VMM that interrupt was handled
}
Example #2
0
/*
 * Process client requests.
 */
void ProcessRequests(FILE * stream)
{
    char buff[128];
    char *cp;
    int stat = -1;

    fputs("200 Welcome to portdio. Type help to get help.\r\n", stream);
    for (;;) {
        fflush(stream);

        /*
         * Read a line from the client. Ignore
         * blank lines.
         */
        if (fgets(buff, sizeof(buff), stream) == 0)
            break;
        if ((cp = strchr(buff, '\r')) != 0)
            *cp = 0;
        if ((cp = strchr(buff, '\n')) != 0)
            *cp = 0;
        if (buff[0] == 0)
            continue;

        /*
         * Memory info.
         */
        if (strncmp(buff, "memory", strlen(buff)) == 0) {
            fprintf(stream, "210 %u bytes RAM free\r\n", (unsigned int)NutHeapAvailable());
            continue;
        }

#ifdef OUTBANK
        /*
         * Reset output bit.
         */
        if (strlen(buff) > 1 && strncmp(buff, "reset", strlen(buff) - 1) == 0) {
            int ok = 1;
            switch (buff[strlen(buff) - 1]) {
#ifdef OUTPIN1
            case '1':
                GpioPinSetLow(OUTBANK, OUTPIN1);
                break;
#endif
#ifdef OUTPIN2
            case '2':
                GpioPinSetLow(OUTBANK, OUTPIN2);
                break;
#endif
#ifdef OUTPIN3
            case '3':
                GpioPinSetLow(OUTBANK, OUTPIN3);
                break;
#endif
#ifdef OUTPIN4
            case '4':
                GpioPinSetLow(OUTBANK, OUTPIN4);
                break;
#endif
            default:
                ok = 0;
                break;
            }
            if (ok) {
                fputs("210 OK\r\n", stream);
            } else
                fputs("410 Bad pin\r\n", stream);
            continue;
        }

        /*
         * Set output bit.
         */
        if (strlen(buff) > 1 && strncmp(buff, "set", strlen(buff) - 1) == 0) {
            int ok = 1;
            switch (buff[strlen(buff) - 1]) {
#ifdef OUTPIN1
            case '1':
                GpioPinSetHigh(OUTBANK, OUTPIN1);
                break;
#endif
#ifdef OUTPIN2
            case '2':
                GpioPinSetHigh(OUTBANK, OUTPIN2);
                break;
#endif
#ifdef OUTPIN3
            case '3':
                GpioPinSetHigh(OUTBANK, OUTPIN3);
                break;
#endif
#ifdef OUTPIN4
            case '4':
                GpioPinSetHigh(OUTBANK, OUTPIN4);
                break;
#endif
            default:
                ok = 0;
                break;
            }
            if (ok) {
                fputs("210 OK\r\n", stream);
            } else
                fputs("410 Bad pin\r\n", stream);
            continue;
        }
#endif /* OUTBANK */

#ifdef INBANK
        /*
         * Port status.
         */
        if (strncmp(buff, "query", strlen(buff)) == 0) {
            stat = PortStatus();
            fprintf(stream, "210 %02X\r\n", stat);
            continue;
        }

        /*
         * wait for status change.
         */
        if (strncmp(buff, "wait", strlen(buff)) == 0) {
            while (stat == PortStatus())
                NutThreadYield();
            stat = PortStatus();
            fprintf(stream, "210 %02X\r\n", stat);
            continue;
        }
#endif /* INBANK */

        /*
         * Help.
         */
        fputs("400 List of commands follows\r\n", stream);
        fputs("memory\tQueries number of RAM bytes free\r\n", stream);
#if OUTBANK
        fputs("reset#\tSet output bit 1..4 low\r\n", stream);
        fputs("set#\tSet output bit 1..4 high\r\n", stream);
#endif
#if INBANK
        fputs("query\tQuery digital i/o status\r\n", stream);
        fputs("wait\tWaits for digital i/o change\r\n", stream);
#endif
        fputs(".\r\n", stream);
    }
}