#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "main.h" #include char infotext[] = "\x1b#3\x9b""1mV A X t e r m\x9b""0m v2.4 " "\x9b""3mBy T. Mickelsson\x9b""0m\x0D\n" "\x1b#4\x9b""1mV A X t e r m\x9b""0m v2.4 " "\x9b""3mBy T. Mickelsson\x9b""0m\x0D\n" "\n\x1b#6\x9b""1mVMS \x9b""22moriented \x9b""1m\x9b""4m" "VT220 Terminal Emulator""\x9b""22m\x9b""24m\x0D\n\n" "\x9b""4mSpecial keys\x9b""0m\x0D\n\n" "\x9b""1mF1\x9b""0m hold/release screen\x0D\n" "\x9b""1mF2\x9b""0m printer on/off\x0D\n" "\x9b""1mF3\x9b""0m set-up\x0D\n" "\x9b""1mF4\x9b""0m file transfers/host set-up/quit\x0D\n" "\x9b""1mF5\x9b""0m break\x0D\n\n" "Right mouse button toggles the mouse pointer and screen gadget.\x0D\n\n" "When the printer will be activated for the first time, " "file PRINTER.SETUP will\x0D\n" "be sent to printer to modify the default printer settings.\x0D\n\n" "The commands for the host set-up will be read from the " "HOST.SETUP file.\x0D\n\n" "File transfers will work only when the terminal emulator " "is logged into the\x0D\n" "VMS-system. The system must be ready to accept DCL-command from " "the terminal.\x0D\n\n"; struct NewScreen nscr = { 0,0,WIDTH,0,DEPTH, BACKGROUND_PEN,FOREGROUND_PEN,HIRES,CUSTOMSCREEN, NULL,(UBYTE *)"Right mouse button to toggles this title! " "Use F4 and 'Q' keys to quit!",NULL,NULL }; struct NewWindow nwin = { 0,0,WIDTH,0,FOREGROUND_PEN,FOREGROUND_PEN, MOUSEBUTTONS|ACTIVEWINDOW|INACTIVEWINDOW, SMART_REFRESH|BACKDROP|BORDERLESS|ACTIVATE|NOCAREREFRESH|RMBTRAP, NULL,NULL,NULL,NULL,NULL,0,0,0,0,CUSTOMSCREEN }; struct Library *IntuitionBase; struct SimpleSprite sp = { NULL,YSIZE,0,0,-1 }; USHORT rows; char line[80],cdir[64],fdir[64]; void _main(char *argv) { struct GfxBase *gb; struct console console,*con; struct serial serial,*ser; register LONG len; char *cp; BPTR fp; USHORT stat; if (*argv) { if (cp = strchr(argv,' ')) *cp = '\0'; cp = argv; cp = cp + strlen(cp) - 1; while((*cp != ':')&&(*cp != '/')) { if (cp == argv) { cp--; break; } cp--; } cp++; *cp = '\0'; getcd(0,cdir); chdir(argv); getcd(0,fdir); chdir(cdir); } else getcd(0,fdir); strcpy(line,"c:assign VTDIR: \""); strcat(line,fdir); strcat(line,"\""); if (fp = OPEN_FOR_WRITING(NILDEVICE)) { Execute(line,NULL,fp); CLOSEFILE(fp); } con = &console; ser = &serial; con->sp = &sp; con->ser = ser; if ((gb=(struct GfxBase *)OpenLibrary("graphics.library",0)) == NULL) return; rows = gb->NormalDisplayRows / YSIZE; nscr.Height = rows * YSIZE; nwin.Height = rows * YSIZE; CloseLibrary((struct Library *)gb); if ((IntuitionBase = OpenLibrary("intuition.library",0)) != NULL) { if (!(openserial(ser))) { if (fp = OPEN_FOR_WRITING(NILDEVICE)) { Execute("Assign FONTS: VTDIR:fonts",NULL,fp); CLOSEFILE(fp); } stat = openconsole(con); if (fp = OPEN_FOR_WRITING(NILDEVICE)) { Execute("Assign FONTS: sys:fonts",NULL,fp); CLOSEFILE(fp); } if (!stat) { strcpy(con->buf,infotext); interpret(con,strlen(con->buf)); readsetup(con); while (con->gstat & ON) { len = readconsole(con); if (len) writeserial(con,con->buf,len); if (!(con->gstat & HOLD)) { len = readserial(con,1); if (len) { interpret(con,len); if (con->gstat & PRINT) WRITE(con->prt,con->buf,len); } else cursorout(con); } if (con->gstat & SEND_BREAK) { con->gstat &= (MASK - SEND_BREAK); send_break(ser); } else if (con->gstat & TRANSFER) { con->gstat &= (MASK - TRANSFER); transfer(con); } else if (con->gstat & SETUP) { con->gstat &= (MASK - SETUP); setup(con); } } closeconsole(con); } closeserial(ser); } CloseLibrary(IntuitionBase); } } readconsole(register struct console *con) { register struct IOStdReq *rreq; register USHORT len; register char *cp; struct IntuiMessage *mes; ULONG class; USHORT code; len = 0; if (!(con->gstat & LOCKED)) { if (GetMsg(con->rport) != NULL) { cp = con->buf; *cp++ = con->character; len = 1; rreq = con->rreq; rreq->io_Flags |= IOF_QUICK; while (len < (BUFSIZE - SECSIZE)) { BeginIO((struct IORequest *)rreq); if (!(rreq->io_Flags & IOF_QUICK)) return((int)len); *cp++ = con->character; len++; } } } if (mes = (struct IntuiMessage *)GetMsg(con->win->UserPort)) { class = mes->Class; code = mes->Code; ReplyMsg((struct Message *)mes); switch (class) { case MOUSEBUTTONS: switch(code) { case MENUUP: if (con->gstat & GAD) { ShowTitle(con->scr,FALSE); SetPointer(con->win,con->dummy,PYSIZE,PXSIZE,0,0); con->gstat &= (MASK - GAD); } else { ShowTitle(con->scr,TRUE); ClearPointer(con->win); con->gstat |= GAD; } break; default: ; } break; case INACTIVEWINDOW: SetRast(&con->srp,0); break; case ACTIVEWINDOW: initcursor(con); DRAWCURSOR(con->rp,&con->srp,con->row,con->col); break; default: ; } } return((LONG)len); } openconsole(register struct console *con) { allocaudio(con); if ((con->wport = CreatePort("console_write",0)) != NULL) { if ((con->wreq = CreateStdIO(con->wport)) != NULL) { if ((con->rport = CreatePort("console_read",0)) != NULL) { if ((con->rreq = CreateStdIO(con->rport)) != NULL) { if ((con->scr = OpenScreen(&nscr)) != NULL) { ShowTitle(con->scr,FALSE); nwin.Screen = con->scr; if ((con->win = OpenWindow(&nwin)) != NULL) { con->wreq->io_Data = (APTR)con->win; con->wreq->io_Length = sizeof(*con->win); if (!(OpenDevice("console.device",0, (struct IORequest *)con->wreq,0))) { con->wreq->io_Command = CD_SETKEYMAP; con->wreq->io_Length = sizeof(struct KeyMap); con->wreq->io_Data = (APTR)&keymap; DoIO((struct IORequest *)con->wreq); con->wreq->io_Command = CMD_WRITE; con->rreq->io_Command = CMD_READ; con->rreq->io_Data = (APTR)&con->character; con->rreq->io_Length = 1; con->rreq->io_Device = con->wreq->io_Device; con->rreq->io_Unit = con->wreq->io_Unit; if (!(allocmem(con))) { SetPointer(con->win,con->dummy, PYSIZE,PXSIZE,0,0); con->rp = con->win->RPort; if (!(openfonts(con))) { SendIO((struct IORequest *)con->rreq); InitBitMap(&con->sbm,1,4 * XSIZE,YSIZE); InitRastPort(&con->srp); con->srp.BitMap = &con->sbm; initcursor(con); if (GetSprite(con->sp,3) != -1) { SetDrMd(con->rp,JAM2); con->prt = NULL; reset(con); return(0); } closefonts(con); } ClearPointer(con->win); freemem(con); } CloseDevice((struct IORequest *)con->wreq); } CloseWindow(con->win); } CloseScreen(con->scr); } DeleteStdIO(con->rreq); } DeletePort(con->rport); } DeleteStdIO(con->wreq); } DeletePort(con->wport); } return(-1); } initcursor(register struct console *con) { register USHORT *wpt,cnt; wpt = con->dat; *wpt++ = 0; *wpt++ = 0; con->sbm.Planes[0] = (PLANEPTR)wpt; for (cnt = 0; cnt < YSIZE * 2; cnt++) *wpt++ = 0x7800; *wpt++ = 0xFFFF; *wpt = 0xFF7F; con->sp->posctldata = con->dat; return(0); } closeconsole(register struct console *con) { freeaudio(con); if (con->prt) CLOSEFILE(con->prt); FreeSprite(con->sp->num); closefonts(con); if (!(con->gstat & GAD)) ClearPointer(con->win); freemem(con); CloseDevice((struct IORequest *)con->wreq); CloseWindow(con->win); CloseScreen(con->scr); DeleteStdIO(con->rreq); DeletePort(con->rport); DeleteStdIO(con->wreq); DeletePort(con->wport); return(0); } allocmem(register struct console *con) { if ((con->dummy = (UWORD *)AllocMem(DUMMYSIZE,MEMF_CHIP|MEMF_CLEAR))!=NULL) { if ((con->dat = (UWORD *)AllocMem(SPRITESIZE,MEMF_CHIP)) != NULL) { if ((con->conv = AllocMem(CONVSIZE,0)) != NULL) { if ((con->buf = AllocMem(BUFSIZE,0)) != NULL) { if ((con->rows = (UBYTE *)AllocMem(rows + 1,0)) != NULL) return(0); FreeMem(con->conv,CONVSIZE); } FreeMem(con->buf,BUFSIZE); } FreeMem((char *)con->dat,SPRITESIZE); } FreeMem((char *)con->dummy,DUMMYSIZE); } return(-1); } freemem(register struct console *con) { FreeMem((char *)con->rows,rows + 1); FreeMem(con->conv,CONVSIZE); FreeMem(con->buf,BUFSIZE); FreeMem((char *)con->dat,SPRITESIZE); FreeMem((char *)con->dummy,DUMMYSIZE); return(0); } static UBYTE alloc[] = { 15,14,13,11,7,3,5,6,9,10,12,8,4,2,1 }; static UBYTE wave[] = { 0,63,127,63,0,-64,-128,-64 }; beep(struct console *con) { register struct IOAudio *audio = con->audio; register UBYTE *temp; if (audio != NULL) { audio->ioa_Request.io_Unit = con->channels; if (con->sound) { if (GetMsg(audio->ioa_Request.io_Message.mn_ReplyPort) == NULL) return(-1); } BeginIO((struct IORequest *)audio); if (audio->ioa_Request.io_Error) { while (GetMsg(audio->ioa_Request.io_Message.mn_ReplyPort) == NULL); temp = audio->ioa_Data; audio->ioa_Request.io_Command = ADCMD_ALLOCATE; audio->ioa_Request.io_Flags = ADIOF_NOWAIT | IOF_QUICK; audio->ioa_Data = alloc; audio->ioa_Length = sizeof(alloc); BeginIO((struct IORequest *)audio); audio->ioa_Request.io_Command = CMD_WRITE; audio->ioa_Request.io_Flags = ADIOF_PERVOL; audio->ioa_Data = temp; audio->ioa_Length = sizeof(wave); if (audio->ioa_Request.io_Error) con->sound = 0; else { con->channels = audio->ioa_Request.io_Unit; BeginIO((struct IORequest *)audio); con->sound = 1; } } else con->sound = 1; } return(0); } allocaudio(struct console *con) { register struct IOAudio *audio = con->audio; audio = (struct IOAudio*)AllocMem(sizeof(struct IOAudio),MEMF_CLEAR); if (audio != NULL) { audio->ioa_Request.io_Message.mn_ReplyPort = CreatePort("beep",0); if (audio->ioa_Request.io_Message.mn_ReplyPort != NULL) { audio->ioa_Request.io_Message.mn_Node.ln_Pri = BEEPPRIORITY; audio->ioa_Data = alloc; audio->ioa_Length = sizeof(alloc); if (!(OpenDevice(AUDIONAME,0,(struct IORequest *)audio,0))) { audio->ioa_Data = AllocMem(sizeof(wave),MEMF_CHIP); if (audio->ioa_Data != NULL) { memcpy(audio->ioa_Data,wave,sizeof(wave)); audio->ioa_Request.io_Command = CMD_WRITE; audio->ioa_Request.io_Flags = ADIOF_PERVOL; audio->ioa_Length = sizeof(wave); audio->ioa_Period = BEEPPERIOD; audio->ioa_Volume = BEEPVOLUME; audio->ioa_Cycles = BEEPCYCLES; con->audio = audio; con->channels = audio->ioa_Request.io_Unit; con->sound = 0; return(0); } CloseDevice((struct IORequest *)audio); } DeletePort(audio->ioa_Request.io_Message.mn_ReplyPort); } FreeMem((char *)audio,sizeof(struct IOAudio)); } con->audio = NULL; return(-1); } freeaudio(struct console *con) { register struct IOAudio *audio = con->audio; if (audio != NULL) { audio->ioa_Request.io_Unit = con->channels; FreeMem((char *)audio->ioa_Data,sizeof(wave)); CloseDevice((struct IORequest *)audio); DeletePort(audio->ioa_Request.io_Message.mn_ReplyPort); FreeMem((char *)audio,sizeof(struct IOAudio)); } return(0); } readserial(register struct console *con,SHORT linemode) { register struct serial *ser; register struct IOExtSer *rreq; register char *cp,c; register LONG len; ser = con->ser; cp = con->buf; rreq = ser->rreq; if (ser->requested) { if ((GetMsg(ser->rport)) == NULL) return(0); if (rreq->IOSer.io_Error) { ser->requested = 0; return(0); } c = ser->character; if (c == END) { rreq->IOSer.io_Flags &= (0xFF - IOF_QUICK); rreq->IOSer.io_Error = 0; BeginIO((struct IORequest *)rreq); if (rreq->IOSer.io_Error) { GetMsg(ser->rport); ser->requested = 0; } return(0); } *cp++ = c; len = 1; } else len = 0; rreq->IOSer.io_Flags |= IOF_QUICK; rreq->IOSer.io_Error = 0; ser->requested = 1; while (len < BUFSIZE) { BeginIO((struct IORequest *)rreq); if (rreq->IOSer.io_Error) { GetMsg(ser->rport); ser->requested = 0; return(len); } if (!(rreq->IOSer.io_Flags & IOF_QUICK)) return(len); c = ser->character; if (c == END) { rreq->IOSer.io_Flags &= (0xFF - IOF_QUICK); BeginIO((struct IORequest *)rreq); if (rreq->IOSer.io_Error) { GetMsg(ser->rport); ser->requested = 0; } return(len); } *cp++ = c; len++; if (linemode) { if ((c == LF)||(c == FF)) { rreq->IOSer.io_Flags &= (0xFF - IOF_QUICK); BeginIO((struct IORequest *)rreq); if (rreq->IOSer.io_Error) { GetMsg(ser->rport); ser->requested = 0; } return(len); } } } return(len); } writeserial(register struct console *con,char *cp,LONG len) { register struct serial *ser; register struct IOExtSer *wreq; ser = con->ser; len = convert(con,cp,len); wreq = ser->wreq; if (!(con->gstat & LOCKED)) { wreq->IOSer.io_Length = len; wreq->IOSer.io_Data = (APTR)con->conv; DoIO((struct IORequest *)wreq); } return(0); } writeasync(register struct console *con,LONG len) { register struct serial *ser; register struct IOExtSer *wreq; struct IntuiMessage *mes; ULONG class; USHORT code,clicks = 0; ser = con->ser; wreq = ser->wreq; wreq->IOSer.io_Length = len; wreq->IOSer.io_Data = (APTR)con->conv; BeginIO((struct IORequest *)wreq); while ((GetMsg(ser->wport)) == NULL) { readserial(con,0); if (mes = (struct IntuiMessage *)GetMsg(con->win->UserPort)) { class = mes->Class; code = mes->Code; ReplyMsg((struct Message *)mes); if ((class == MOUSEBUTTONS)&&(code == SELECTDOWN)) { clicks++; if (clicks == ABORTASYNC) { AbortIO((struct IORequest *)wreq); GetMsg(ser->wport); return(1); } Delay(ABORTDELAY); } } } return(0); } send_break(register struct serial *ser) { register struct IOExtSer *wreq; UBYTE flags; wreq = ser->wreq; flags = wreq->IOSer.io_Flags; wreq->IOSer.io_Flags &= (0xFF - (IOF_QUICK | SERF_QUEUEDBRK)); wreq->IOSer.io_Command = SDCMD_BREAK; DoIO((struct IORequest *)wreq); wreq->IOSer.io_Command = CMD_WRITE; wreq->IOSer.io_Flags = flags; return(0); } openserial(register struct serial *ser) { struct Preferences prefs; if ((ser->wport = CreatePort("serial_write",0)) != NULL) { if ((ser->wreq = (struct IOExtSer *)CreateExtIO(ser->wport, sizeof(struct IOExtSer))) != NULL) { if ((ser->rport = CreatePort("serial_read",0)) != NULL) { if ((ser->rreq = (struct IOExtSer *)CreateExtIO(ser->rport, sizeof(struct IOExtSer))) != NULL) { if (!(OpenDevice("serial.device",1, (struct IORequest *)ser->wreq,0))) { GetPrefs(&prefs,sizeof(struct Preferences)); ser->rreq->IOSer.io_Device = ser->wreq->IOSer.io_Device; ser->rreq->IOSer.io_Unit = ser->wreq->IOSer.io_Unit; if (prefs.SerParShk & 0xf0) ser->rreq->io_SerFlags = SERF_PARTY_ON; else ser->rreq->io_SerFlags = 0; if ((prefs.SerParShk >> 4) == SPARITY_ODD) ser->rreq->io_SerFlags |= SERF_PARTY_ODD; if ((prefs.SerParShk & 0x0f) != SHSHAKE_XON) ser->rreq->io_SerFlags |= SERF_XDISABLED; switch (prefs.BaudRate) { case BAUD_110: ser->rreq->io_Baud = 110; break; case BAUD_300: ser->rreq->io_Baud = 300; break; case BAUD_1200: ser->rreq->io_Baud = 1200; break; case BAUD_2400: ser->rreq->io_Baud = 2400; break; case BAUD_4800: ser->rreq->io_Baud = 4800; break; case BAUD_9600: ser->rreq->io_Baud = 9600; break; case BAUD_19200: ser->rreq->io_Baud = 19200; break; case BAUD_MIDI: ser->rreq->io_Baud = 32768; break; default: ser->rreq->io_Baud = 2400; } ser->rreq->io_ReadLen = 8 - (prefs.SerRWBits >> 4); ser->rreq->io_WriteLen = 8 - (prefs.SerRWBits & 0x0f); ser->rreq->io_StopBits = (prefs.SerStopBuf >> 4) + 1; ser->rreq->io_CtlChar = 0x11130506; switch (prefs.SerStopBuf & 0x0f) { case SBUF_512: ser->rreq->io_RBufLen = 512; break; case SBUF_1024: ser->rreq->io_RBufLen = 1024; break; case SBUF_2048: ser->rreq->io_RBufLen = 2048; break; case SBUF_4096: ser->rreq->io_RBufLen = 4096; break; case SBUF_8000: ser->rreq->io_RBufLen = 8000; break; case SBUF_16000: ser->rreq->io_RBufLen = 16000; break; default: ser->rreq->io_RBufLen = 1024; } ser->rreq->io_BrkTime = 500000L; ser->rreq->IOSer.io_Command = SDCMD_SETPARAMS; if (!(DoIO((struct IORequest *)ser->rreq))) { ser->rreq->IOSer.io_Command = CMD_READ; ser->rreq->IOSer.io_Data = (APTR)&ser->character; ser->rreq->IOSer.io_Length = 1; ser->rreq->IOSer.io_Error = 0; ser->wreq->IOSer.io_Command = CMD_WRITE; BeginIO((struct IORequest *)ser->rreq); ser->requested = 1; if (ser->rreq->IOSer.io_Error == 0) return(0); } CloseDevice((struct IORequest *)ser->wreq); } DeleteExtIO((struct IORequest *)ser->rreq); } DeletePort(ser->rport); } DeleteExtIO((struct IORequest *)ser->wreq); } DeletePort(ser->wport); } return(-1); } closeserial(register struct serial *ser) { CloseDevice((struct IORequest *)ser->wreq); DeleteExtIO((struct IORequest *)ser->rreq); DeletePort(ser->rport); DeleteExtIO((struct IORequest *)ser->wreq); DeletePort(ser->wport); return(0); }