/*********************************/ /* IBM Block Terminal Emulation */ /* written by B. Nebel, March 86 */ /* Version 1.2 of 5/10/86 */ /*********************************/ /* include files */ /*****************/ #include "define.h" /* common C defintions */ #include "osbind.h" /* binding of TOS */ #include "gemdefs.h" /* GEM defintions */ /* some ASCII codes */ /********************/ #define NUL 0x00 /* ^@ */ #define SOH 0x01 /* ^A */ #define ETX 0x03 /* ^C */ #define BEL 0x07 /* ^G */ #define BS 0x08 /* ^H */ #define HT 0x08 /* ^I */ #define LF 0x0A /* ^J */ #define VT 0x0B /* ^K */ #define FF 0x0C /* ^L */ #define CR 0x0D /* ^M */ #define DC1 0x11 /* ^S */ #define DC3 0x13 /* ^Q */ #define SUB 0x1A /* ^Z */ #define ESC 0x1B /* ^[ */ #define DEL 0x7F /* Some Scan Codes */ /*******************/ #define CLR_HOME_KEY 0x47 #define UP_KEY 0x48 #define LEFT_KEY 0x4B #define RIGHT_KEY 0x4D #define DOWN_KEY 0x50 #define INSERT_KEY 0x52 #define UNDO_KEY 0x61 #define HELP_KEY 0x62 /* global constant parameters */ /******************************/ #define ACCESSORY YES #define MENU_NAME " IBM Terminal" /* name of menu entry */ #define MAX_LL 80 /* line length */ #define MAX_BUF 20 /* ring buffers */ /* external functions */ /**********************/ /* GEMDOS (osbind.h) */ /* Crawio, Cauxin, Cauxout, Cauxis, Malloc, Mfree */ /* XBIOS (osbind.h) */ /* Rsconf */ /* VDI */ extern int v_opnvwk(); extern int v_clsvwk(); extern int v_enter_cur(); extern int v_exit_cur(); extern int v_curright(); extern int v_curleft(); extern int v_curhome(); extern int v_eeos(); extern int v_eeol(); extern int vs_curaddress(); extern int vq_curaddress(); extern int v_curtext(); extern int vq_chcells(); extern int vro_copyfm(); /* AES */ extern int appl_init(); extern int appl_exit(); extern int graf_handle(); extern int graf_mouse(); extern int graf_growbox(); extern int menu_register(); extern int evnt_mesag(); extern int evnt_timer(); extern int wind_create(); extern int wind_open(); extern int wind_close(); extern int wind_delete(); extern int wind_get(); extern int wind_update(); extern int form_alert(); extern int gl_apid; /* Global Variables */ /********************/ int menu_id, vdi_handle, wi_handle; /* some handles */ int gl_hchar, gl_wchar, gl_wbox, gl_hbox; /* sizes given back by VDI */ int xdesk, ydesk, hdesk, wdesk; /* desktop size and loc. */ int last_entry, next_entry; /* ptr to ring buffer */ char ring_buffer [MAX_BUF] [MAX_LL]; /* the ring buffer */ int ring_filled[MAX_BUF]; /* fill counter for ring buf */ int aux_received; /* if <> 0 someth. rec. by aux */ FDB scrn_mfdb; /* mfdbs for saving menu bar */ FDB save_mfdb; int work_in[11]; /* params for vdi_opnvwk */ int work_out[57]; int pxy[8]; /* param for raster copy */ long int buff_loc = NIL; /* save buffer for menu bar */ long buff_size; /* buffer size */ int menbbuf[1000]; /* buffer for menu bar */ /* static allocation because Malloc allocates too much */ int contrl[12]; /* VDI/AES glob. params */ int intin[128]; int ptsin[128]; int intout[128]; int ptsout[128]; /**********************************/ /* Initializations & Terminations */ /**********************************/ open_vdi() /* open virtual work station */ { int i; vdi_handle = graf_handle(&gl_wchar, &gl_hchar, &gl_wbox, &gl_hbox); for (i = 1; i < 10; i++) { work_in[i] = 1; } work_in[10] = 2; v_opnvwk(work_in, &vdi_handle, work_out); wind_get(0,WF_WORKXYWH,&xdesk,&ydesk,&wdesk,&hdesk); } int init_terminal() /* init virtual workstation as a terminal */ { graf_mouse(M_OFF,NIL); if (!(save_menu_bar())) return FALSE; wi_handle = wind_create(0,xdesk,ydesk,wdesk,hdesk); graf_growbox(xdesk,ydesk,gl_wbox,gl_hbox,xdesk,ydesk,wdesk,hdesk); wind_open(wi_handle,xdesk,ydesk,wdesk,hdesk); v_enter_cur(vdi_handle); v_curhome(vdi_handle); v_eeos(vdi_handle); return TRUE; } int save_menu_bar() /* save menu bar in a area to be allocated */ { vq_extnd(vdi_handle, 0, work_out); save_mfdb.fd_w = work_out[0] + 1; save_mfdb.fd_h = ydesk; save_mfdb.fd_wdwidth = save_mfdb.fd_w >> 4; save_mfdb.fd_stand = 0; vq_extnd(vdi_handle, 1, work_out); save_mfdb.fd_nplanes = work_out[4]; buff_size = (save_mfdb.fd_w >> 3) * save_mfdb.fd_h * save_mfdb.fd_nplanes; buff_loc = save_mfdb.fd_addr = /* ((buff_loc == NIL) ? (Malloc(buff_size)) : buff_loc); * I use static allocation because Malloc stole me 50 K! */ &menbbuf[0]; scrn_mfdb.fd_addr = 0; if (buff_loc == NIL) {form_alert(1,"[1][Nicht genug Speicherplatz vorhanden][Abort]"); return FALSE;}; pxy[0] = pxy[4] = 0; pxy[1] = pxy[5] = 0; pxy[2] = pxy[6] = save_mfdb.fd_w - 1; pxy[3] = pxy[7] = ydesk - 1; vro_cpyfm(vdi_handle,3,pxy,&scrn_mfdb,&save_mfdb); return TRUE; } close_vdi() /* close virtual workstation */ v_clsvwk(vdi_handle); exit_terminal() /* exit terminal mode */ { v_exit_cur(vdi_handle); restore_menu_bar(); wind_close(wi_handle); wind_delete(wi_handle); graf_shrinkbox(xdesk,ydesk,gl_wbox,gl_hbox,xdesk,ydesk,wdesk,hdesk); #if !ACCESSORY graf_mouse(M_ON,NIL); #endif } restore_menu_bar() { vro_cpyfm(vdi_handle,3,pxy,&save_mfdb,&scrn_mfdb); /* Mfree(buff_loc); Do not free because it doesn't work right! */ graf_mouse(M_ON,NIL); } /*****************/ /* VDI Functions */ /*****************/ vdi_ch(ch) int ch; Crawio(ch); vdi_line(string) char string[]; { v_curtext(vdi_handle,string); vdi_ch(CR); vdi_ch(LF); } /**********************/ /* Terminal Functions */ /**********************/ help() { v_curhome(vdi_handle); v_eeos(vdi_handle); vdi_line("**********************"); vdi_line("* IBM Block Terminal *"); vdi_line("**********************"); vdi_line(""); vdi_line("BACKSPACE - letztes Zeichen lschen"); vdi_line("DELETE - aktuelles Zeichen lschen"); vdi_line("INSERT - lsche Zeile"); vdi_line("RETURN und ENTER - sende Zeile"); vdi_line("CLR HOME - sende BREAK Sequenz"); vdi_line("Pfeile links/rechts - Cursor in der Zeile bewegen"); vdi_line("Pfeile oben/unten - letzte/nchste Zeile editieren"); vdi_line("HELP - Ausgabe dieser Meldung"); vdi_line("UNDO - zurck zum Desktop"); vdi_line(""); } flush_rs232_buffer() while (Cauxis() != 0) Cauxin(); flush_terminal_buffer() while (Crawio(0xFF) != 0); wait_for_char(scan_code,ch) char *scan_code,*ch; { long result; do {*scan_code = NUL; if ((result = Crawio(0xFF)) != 0) { *ch = result & 0xFF; *scan_code = result >> 16 ; } else {if (Cauxis() != 0) {result = Cauxin(); *ch = result & 0x7F; if (*ch <= '~') { vdi_ch(*ch); aux_received = YES; }; }; }; } while (*scan_code == NUL); } send_break() {char tsr; tsr = (Rsconf(-1,-1,-1,-1,-1,-1) >> 16) & 0xFF; Rsconf(-1,-1,-1,-1,(tsr | 0x08),-1); evnt_timer(750,0); Rsconf(-1,-1,-1,-1,tsr,-1); } ring_bell() vdi_ch(BEL); redisplay(from,to,line) int from, to; char line[]; { int i,r,c; vq_curaddress(vdi_handle,&r,&c); for (i = from; i <= to; i++) vdi_ch(line[i]); v_eeol(vdi_handle); vs_curaddress(vdi_handle,r,c); } move_right(dummy) int dummy; v_curright(vdi_handle); move_left(vcol) int vcol; { int r,c; vq_chcells(vdi_handle,&r,&c); if (c >= vcol) v_curleft(vdi_handle); } shift_right(from, to, line) int from, to; char line[]; { int i; for (i = to ; i >= from ; i--) line[i+1] = line[i]; } shift_left(from, to, line) int from, to; char line[]; { int i; for (i = from; i <= to; i++) line[i] = line[i+1]; } copy_buf_entry(src,dst) char src[]; char dst[]; { int i; for (i = 0; i < MAX_LL; i++) dst[i] = src[i]; } int dec_entry(e) int *e; return ((--(*e) < 0) ? (*e = MAX_BUF - 1) : (*e)); int inc_entry(e) int *e; return ((++(*e) >= MAX_BUF) ? (*e = 0) : (*e)); int get_line(filled, line) int *filled; char line[]; { int pos, scol, srow; char ch, scan_code; aux_received = NO; pos = 0; *filled = 0; vq_curaddress(vdi_handle,&srow,&scol); while (TRUE) { wait_for_char(&scan_code,&ch); if (aux_received) {vq_curaddress(vdi_handle,&srow,&scol); redisplay(0,*filled-1,line); vs_curaddress(vdi_handle,srow,scol+pos); aux_received = NO; }; if (ch != NUL) {if ((ch >= ' ') && (ch <= '~')) {if (*filled >= MAX_LL) ring_bell(); else {shift_right(pos, (*filled)-1, line); line[pos] = ch; redisplay(pos,*filled,line); (*filled)++; pos++; move_right(scol+pos); }; } else switch (ch) {case CR: vdi_ch(CR); return TRUE; case BS: if (pos == 0) ring_bell(); else {move_left(scol+pos); shift_left(--pos,--(*filled),line); redisplay(pos,(*filled)-1,line); }; break; case DEL: if (pos == *filled) ring_bell(); else {shift_left(pos,--(*filled),line); redisplay(pos,(*filled)-1,line); }; break; default: ring_bell(); break; }; } else switch (scan_code) {case UNDO_KEY: return FALSE; case LEFT_KEY: if (pos == 0) ring_bell(); else move_left(scol+pos--); break; case RIGHT_KEY: if (pos == *filled) ring_bell(); else move_right(scol+pos++); break; case UP_KEY: pos = *filled = ring_filled[dec_entry(&last_entry)]; copy_buf_entry(ring_buffer[last_entry],line); vs_curaddress(vdi_handle,srow,scol); redisplay(0,(*filled)-1,line); vs_curaddress(vdi_handle,srow,scol+pos); break; case DOWN_KEY: pos = *filled = ring_filled[inc_entry(&last_entry)]; copy_buf_entry(ring_buffer[last_entry],line); vs_curaddress(vdi_handle,srow,scol); redisplay(0,(*filled)-1,line); vs_curaddress(vdi_handle,srow,scol+pos); break; case HELP_KEY: help(); vq_curaddress(vdi_handle,&srow,&scol); redisplay(0,*filled-1,line); vs_curaddress(vdi_handle,srow,scol+pos); break; case CLR_HOME_KEY: vs_curaddress(vdi_handle,srow,scol); v_eeol(vdi_handle); pos = *filled = 0; send_break(); aux_received = TRUE; break; case INSERT_KEY: vs_curaddress(vdi_handle,srow,scol); v_eeol(vdi_handle); pos = *filled = 0; break; default: ring_bell(); break; }; }; } send_line(filled,line) int filled; char line[]; { int i; for (i = 0; i < filled; i++) Cauxout(line[i]); Cauxout(CR); } terminal() { char this_line[MAX_LL]; int this_fill; vdi_ch(ESC); vdi_ch('w'); help(); flush_rs232_buffer(); flush_terminal_buffer(); while (TRUE) {if (!get_line(&this_fill,this_line)) break; send_line(this_fill,this_line); if (this_fill != 0) {ring_filled[next_entry] = this_fill; copy_buf_entry(this_line,ring_buffer[next_entry]); inc_entry(&next_entry); }; last_entry = next_entry; }; } init_accessory() menu_id = menu_register(gl_apid,MENU_NAME); handle_events() { int mbuf[10]; while (TRUE) {evnt_mesag(mbuf); {if ((mbuf[0] == AC_OPEN) && (mbuf[4] == menu_id)) {wind_update(BEG_UPDATE); open_vdi(); if (init_terminal()) {terminal (); exit_terminal(); }; close_vdi(); wind_update(END_UPDATE); }; }; }; } main() {appl_init(); #if ACCESSORY init_accessory(); handle_events(); #else open_vdi(); if (init_terminal()) {terminal(); exit_terminal();}; close_vdi(); appl_exit(); #endif }