#include "os.h" #include // for printf() #include #include int done; int dequeue(struct Queue *qp); int enqueue(struct Queue *qp, int data); void SerialIn(); void SerialOut(); void Remote_Display(); void Local_Display(); void Keyboard_Read(); #define QSIZE 16 #define COMPORT 0x3F8 struct Queue { int head; int tail; int size; int semaphore_lock; int data[QSIZE]; }; Queue KeyIn; Queue OutBuffer; Queue InBuffer; /////////////////////////////////////////////////////////////////////////// ///returns and removes data from *qp head ///return -1 upon queue empty ///sort-of locks semaphore for use else suspends upon semaphore locked ///modifies: Queue structure *qp, ////////////////////////////////////////////////////////////////////////// int dequeue(struct Queue *qp) { int num; if(qp->size == 0) return -1; else { //semaphore lock shared resource while(qp->semaphore_lock) OS_Suspend(); qp->semaphore_lock = 1; qp->size--; num = qp->data[qp->head]; qp->head = (qp->head+1)%QSIZE; //unlock semaphore qp->semaphore_lock = 0; return num; } } /////////////////////////////////////////////////////////////////////////// ///adds (push) data to *qp tail ///return -1 upon queue full ///"sort-of" locks semaphore for use else suspends upon semaphore locked ///modifies: Queue structure *qp, ////////////////////////////////////////////////////////////////////////// int enqueue(struct Queue *qp, int data) { if(qp->size >= QSIZE) return -1; //semaphore lock shared resource while(qp->semaphore_lock) OS_Suspend(); qp->semaphore_lock = 1; qp->data[qp->tail] =data; qp->tail = (qp->tail+1)%QSIZE; qp->size++; //unlock semaphore qp->semaphore_lock = 0; return 0; } ////////////////////////////////////////////////////////////////////////// //check and enque keystroke if pressed (in buffer) else suspends //mod: keyboard buffer, KeyIn Queue, done ///////////////////////////////////////////////////////////////////////// void Keyboard_Read() { char status; while(1) { status = 0; //check for keystroke (non-blocking) asm { MOV AH,1 INT 16h JZ nokey MOV status,1 nokey: } //upon keystroke detection get from buffer if(status) { asm { MOV AH,0 INT 16h MOV status,al } if(status == '!') done=1; enqueue(&KeyIn, status); } OS_Suspend(); } }; //////////////////////////////////////////////////////////////////////////// //put from KeyIn Queue to screen at x,y and enqueues char to OutBuffer //mod: cprintf, KeyIn Queue, InBuffer Queue ////////////////////////////////////////////////////////////////////////// void Local_Display() { static int x=1; static int y=1; int ch; int i=0; while(1) { while((ch=dequeue(&KeyIn))!=-1) { //test for text bounds and return stroke if((x>=80) || (ch=='\r')) { x=1; if(y<12) y++; else { gotoxy(1,12); for(i=1;i<80;i++) cprintf(" "); } } //print to screen if(ch!='\r') { gotoxy(x,y); cprintf("%c", ch); x++; } enqueue(&OutBuffer, ch); }//end while OS_Suspend(); }//end while(1) } ////////////////////////////////////////////////////////////////////////////// //check for byte & enqueue to InBuffer else suspend //mod: InBuffer Queue, serial port thingie ///////////////////////////////////////////////////////////////////////////// void SerialIn() { while (1) { if (!(inportb (COMPORT + 5) & 0x01)) OS_Suspend(); else enqueue (&InBuffer, inportb(COMPORT)); } } //////////////////////////////////////////////////////////////////////////// //check for open buffer then dequeue OutBuffer to Serial port xmit //else suspend //mod:OutBuffer Queueueueueue , serial port control thingie /////////////////////////////////////////////////////////////////////////// void SerialOut() { char Temp; while(1) { while (!(inportb (COMPORT + 5) & 0x20)) OS_Suspend(); Temp = dequeue(&OutBuffer); if(Temp != -1) outportb (COMPORT, Temp); else OS_Suspend(); } } //////////////////////////////////////////////////////////////////////////// //put from InBuffer Queue to screen at x,y //mod: cprintf, InBuffer Queue ////////////////////////////////////////////////////////////////////////// void Remote_Display() { static int x=1; static int y=14; int ch; int i=0; while(1) { while((ch=dequeue(&InBuffer))!=-1) { if((x>=80) || (ch=='\r')) { x=1; if(y<25) y++; else { gotoxy(1,25); for(i=1;i<80;i++) cprintf(" "); } } if(ch!='\r') { gotoxy(x,y); cprintf("%c", ch); x++; }//end if }//end while OS_Suspend(); }//end while(1) } //////////////////////main//////////////////////////////////////////////// //inits all Queues starts threads terminates gracefully upon done /////////////////////////////////////////////////////////////////////////// void main() { KeyIn.size = 0; KeyIn.head = 0; KeyIn.tail = 0; KeyIn.semaphore_lock = 0; InBuffer.size=0; InBuffer.head=0; InBuffer.tail=0; InBuffer.semaphore_lock = 0; OutBuffer.size=0; OutBuffer.head=0; OutBuffer.tail=0; OutBuffer.semaphore_lock = 0; done = 0; clrscr(); OS_Startup(); OS_StartThread( OS_CreateThread("Keyboard Read", (int)Keyboard_Read) ); OS_StartThread( OS_CreateThread("Local Display", (int)Local_Display) ); OS_StartThread( OS_CreateThread("Serial Out", (int)SerialOut) ); OS_StartThread( OS_CreateThread("Serial In", (int)SerialIn) ); OS_StartThread( OS_CreateThread("Remote Display", (int)Remote_Display) ); while(done!=1) OS_Suspend(); OS_Shutdown(); }