|
DataMuseum.dkPresents historical artifacts from the history of: DKUUG/EUUG Conference tapes |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about DKUUG/EUUG Conference tapes Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - downloadIndex: T m
Length: 41859 (0xa383) Types: TextFile Names: »msxhpx.asm«
└─⟦9ae75bfbd⟧ Bits:30007242 EUUGD3: Starter Kit └─⟦71044c191⟧ »EurOpenD3/misc/kermit.ms-2.32.tar.Z« └─⟦31f2d420d⟧ └─⟦this⟧ »msxhpx.asm«
name msxhpx ; File MSXHPX.ASM ; Edit history: ; Last edit: 4 June 1988 ; 1 July 1988 Version 2.31 ; 1 Jan 1988 version 2.30 ; 25 May 1987 Add keyboard translator, input translation, cleanups. [jrd] ; 1 Oct 86 Version 2.29a ; 30 Sept 1986 Reject DEL char at serial port reception level to avoid ; problems when DEL is used as a filler char (by Emacs). [jrd] ; 28 Sept 1986 Revise procedure Term to permit capturing, printer ready ; testing, debug display. Revised other port procedures slightly too; ; especially to set port into binary mode via ioctl. [jrd] ; 22 Sept 1986 Add modifications from Mike Mellinger: outchr, serhng. ; Introduce COM3 as additional choice. Startup 8 bits, no parity. [jrd] ; 4 Sept 1986 Add Bob Goeke's change to move comms port table to a system ; dependent module (typ msx---) to allow 3+ ports and localized idents. [jrd] ; Date: 15 Oct 85 ; HP Portable Kermit ; for HP110 and HP Portable Plus ; Port 1: Serial, Port 2: internal modem ; Defaults: even parity, 9600 baud: serial, 1200 internal modem ; Internal modem code only works on HP Portable Plus ; 15 Nov 85: ; Added code to shut off serial port and modem when quitting Kermit ; 11 Jan 86; ; change msdefs.h to mssdef.h for kermit 2.28 jrd ; ; Add global entry point vtstat for use by Status in mssset. ; Also trimmed off trailing commas in publics. Joe R. Doupnik 12 March 1986 ; Add global procedures ihosts and ihostr to handle host initialization ; when packets are to be sent or received by us,resp. 24 March 1986 ; Add global procedure dtrlow (without worker serhng) to force DTR & RTS low ; in support of Kermit command Hangup. Says Not Yet Implemented. [jrd] ; Add global procedure Dumpscr, called by Ter in file msster, to dump screen ; to a file. Just does a beep for now. 13 April 1986 [jrd] ; In proc Outchr add override of xon from chkxon sending routine. ; This makes a hand typed Xoff supress the xon flow control character sent ; automatically as the receiver buffer empties. 20 April 1986 [jrd] ; Fix port selector table, comptab, (from original version) to properly ; hold port name AUX. 23 April 1986 [jrd] ; ; Fixed error in resetting the serial port, 25 April 1986 ; page 80,132 PLUS equ 0 public serini, serrst, clrbuf, outchr, coms, vts, vtstat, dodel public ctlu, cmblnk, locate, lclini, prtchr, dobaud, clearl public dodisk, getbaud, beep, pcwait, termtb, shomodem, getmodem public xofsnt, puthlp, putmod, clrmod, poscur public sendbr, sendbl, term, machnam, setktab, setkhlp, showkey public ihosts, ihostr, dtrlow, serhng, dumpscr, comptab public chrout, cstatus, cquit public cquery, trnprs, snull, klogon, klogof, kdos include mssdef.h false equ 0 true equ 1 instat equ 6 print_out equ 05h ; dos function to print to printer prtscr equ 80h ; print screen pressed ; external variables used: ; drives - # of disk drives on system ; flags - global flags as per flginfo structure defined in pcdefs ; trans - global transmission parameters, trinfo struct defined in pcdefs ; portval - pointer to current portinfo structure (currently either port1 ; or port2) ; port1, port2 - portinfo structures for the corresponding ports ; global variables defined in this module: ; xofsnt, xofrcv - tell whether we saw or sent an xoff. datas segment public 'datas' extrn drives:byte,flags:byte, trans:byte extrn portval:word, port1:byte, port2:byte, dmpname:byte extrn port3:byte, kbdflg:byte, rxtable:byte ifdef PLUS machnam db 'HP-PLUS$' else machnam db 'HP-110$' endif erms20 db cr,lf,'?Warning: System has no disk drives$' erms40 db cr,lf,'?Warning: Unrecognized baud rate$' erms41 db cr,lf,'?Warning: Cannot open com port$' erms50 db cr,lf,'Error reading from device$' badbd db cr,lf,'Unimplemented baud rate$' badpar db cr,lf,'Unimplemented parity$' noimp db cr,lf,'Command not implemented.$' hngmsg db cr,lf,' The phone should have hungup.',cr,lf,'$' hnghlp db cr,lf,' The modem control lines DTR and RTS for the current' db ' port are forced low (off)' db cr,lf,' to hangup the phone. Normally, Kermit leaves them' db ' high (on) when it exits.' db cr,lf,'$' msmsg1 db cr,lf,' Communications port is not ready.$' msmsg2 db cr,lf,' Communications port is ready.$' rdbuf db 80 dup (?) ; temp buf shkmsg db 'Not implemented.' shklen equ $-shkmsg baudstr db 'SB' ; string used in setting baud rate baudx db 0,';' par_str db 'P' ; string used to set parity par_x db 4,';' ; 4=no parity (use 0 for even parity) brk_on db 'B1;' ; start sending breaks brk_off db 'B0;' ; stop sending breaks chk_msg db 0BFH,';' ; check serial buffer $m0 db 'M0;' $m1 db 'M1;' $off_m db 'M3;M5;' off_len equ $-$off_m ; ini_msg db 'C2;' ; XON/XOFF db 'LI1;' ; DTR on db 'SS0;' ; 1 Stop Bit Db 'SW0;' ; 8 bits ( use SW1 for 7 Bit Length) setktab db 0 setkhlp db 0 crlf db cr,lf,'$' delstr db BS,BS,' ',BS,'$' clrlin db cr,ESCAPE,'K$' clreol db ESCAPE,'K$' telflg db 0 ; non-zero if we're a terminal xofsnt db 0 ; Say if we sent an XOFF xofrcv db 0 ; Say if we received an XOFF invseq db ESCAPE,'&dB$' ; Reverse video nrmseq db ESCAPE,'&d@$' ; Normal video ivlseq db 80 dup (' '),cr,'$' ; make line inverse video prthnd dw 0 ; Port handle argadr dw ? ; address of arg blk from msster.asm parmsk db ? ; 8/7 bit parity mask, for reception flowoff db ? ; flow-off char, Xoff or null (if no flow) flowon db ? ; flow-on char, Xon or null captrtn dw ? ; routine to call for captured output tempbuf dw 10 dup(?) prttab dw com1,com2,com3 com1 db 'COM1',0 com2 db 'AUX',0 com3 db 'COM3',0 blank db ESCAPE,'H',ESCAPE,'J$' movcur db ESCAPE,'&a' colno db 20 dup(?) ten db 10 tmp db ?,'$' temp dw 0 temp1 dw ? ; Temporary storage temp2 dw ? ; Temporary storage ; Entries for choosing communications port. [19b] comptab db 7 ; 7 entries. Rewritten by [jrd] mkeyw '1',1 mkeyw '2',2 mkeyw '3',2 mkeyw 'AUX',2 ; alias for com2 mkeyw 'COM1',1 mkeyw 'COM2',2 mkeyw 'COM3',3 termtb db tttypes ; entries for Status, not Set mkeyw 'Heath-19',ttheath mkeyw 'none',ttgenrc mkeyw 'Tek4014',tttek mkeyw 'VT102',ttvt100 mkeyw 'VT52',ttvt52 ; variables for serial interupt handler source db bufsiz DUP(?) ; buffer for data from port bufout dw 0 ; buffer removal pointer count dw 0 ; number of chars in int buffer bufin dw 0 ; buffer insertion pointer ourarg termarg <> datas ends code segment public 'code' extrn comnd:near, dopar:near, prserr:near, atoi:near, prompt:near extrn sleep:near extrn msuinit:near, keybd:near ; in msuhpx assume cs:code,ds:datas ; this is called by Kermit initialization. It checks the ; number of disks on the system, sets the drives variable ; appropriately. Returns normally. DODISK PROC NEAR mov ah,gcurdsk ; Current disk value to AL int dos mov dl,al ; Put current disk in DL mov ah,seldsk ; Select current disk int dos ; Get number of drives in AL mov drives,al ret DODISK ENDP ; Clear the input buffer. This throws away all the characters in the ; serial interrupt buffer. This is particularly important when ; talking to servers, since NAKs can accumulate in the buffer. ; Returns normally. CLRBUF PROC NEAR cli mov bufin,offset source mov bufout,offset source mov count,0 sti ret CLRBUF ENDP ; Clear to the end of the current line. Returns normally. CLEARL PROC NEAR push ax ; save regs push dx mov ah,prstr mov dx,offset clreol int dos pop dx pop ax ret CLEARL ENDP ; Put the char in AH to the serial port. This assumes the ; port has been initialized. Should honor xon/xoff. Skip returns on ; success, returns normally if the character cannot be written. outchr: push cx ; save regs or ah,ah ; sending a null? jz outch2 ; z = yes xor cx,cx ; clear counter cmp ah,flowoff ; sending xoff? jne outch1 ; ne = no mov xofsnt,false ; supress xon from chkxon buffer routine outch1: cmp xofrcv,true ; Are we being held? jne outch2 ; No - it's OK to go on loop outch1 ; held, try for a while mov xofrcv,false ; timed out, force it off and fall thru outch2: push dx ; Save register mov al,ah ; Parity routine works on AL call dopar ; Set parity appropriately ; Begin revised output routine mov byte ptr temp,al ; put data there cmp prthnd,0 ; Got a handle yet? jne outch3 ; Yup just go on call opnprt ; Else 'open' the port outch3: push bx mov bx,prthnd ; port handle mov cx,1 ; one byte to write mov dx,offset temp ; place where data will be found mov ah,write2 ; dos 2 write to file/device int dos pop bx ; end of revised routine pop dx pop cx jmp rskp ; This routine blanks the screen. Returns normally. CMBLNK PROC NEAR push ax ; save regs push dx mov ah,prstr mov dx,offset blank int dos pop dx pop ax ret CMBLNK ENDP ; Homes the cursor. Returns normally. LOCATE PROC NEAR mov dx,0 ; Go to top left corner of screen jmp poscur LOCATE ENDP ; Write a line at the bottom of the screen... ; the line is passed in dx, terminated by a $. Returns normally. putmod proc near push dx ; preserve message ifdef PLUS mov dx,1800H ; now address line 24 else mov dx,0F00H ; now address line 15 endif call poscur mov dx,offset invseq ; put into inverse video mov ah,prstr int dos pop dx ; get message back int dos ; print it mov dx,offset nrmseq ; normal video int dos ret putmod endp ; clear the mode line written by putmod. Returns normally. clrmod proc near ifdef PLUS mov dx,1800H else mov dx,0F00H endif call poscur ; Go to bottom row call clearl ; Clear to end of line ret clrmod endp ; Put a help message on the screen. ; Pass the message in ax, terminated by a null. Returns normally. puthlp proc near push dx ; save regs push si push ax ; preserve this mov ah,prstr mov dx,offset crlf int dos pop si ; point to string again puth0: mov ah,prstr mov dx,offset invseq ; put into reverse video int dos mov ah,prstr mov dx,offset ivlseq ; make line inverse video int dos cld puth1: lodsb ; get a byte cmp al,0 ; end of string? je puth2 mov dl,al mov ah,conout int dos ; else write to screen cmp al,lf ; line feed? je puth0 ; yes, clear the next line jmp puth1 puth2: mov ah,prstr mov dx,offset crlf int dos mov dx,offset nrmseq ; normal video int dos pop si pop dx ret puthlp endp ; Set the baud rate for the current port, based on the value ; in the portinfo structure. Returns normally. DOBAUD PROC NEAR push ax ; save regs push bx push dx mov bx,portval mov dx,[bx].baud ; get baud rate from table cmp dx,0 jb bd_bd cmp dx,10 je bd_bd cmp dx,15 ja bd_bd ; cmp dx,10 jb baud_4 cmp dx,11 jne baud_1 mov dl,'A' jmp baud_5 baud_1: cmp dx,12 jne baud_2 mov dx,'C' jmp baud_5 baud_2: cmp dx,13 jne baud_3 mov dx,'E' jmp baud_5 baud_3: cmp dx,14 jne bd_bd mov dx,'F' jmp baud_5 baud_4: add dl,'0' ; make # printable baud_5: mov baudx,dl ; put into baud rate message mov cx,4 mov dx,offset baudstr ; point to message cmp prthnd,0 ; is port open je Baud_R ; No, skip hardware set call w_ioctl ; write to ioctl of serial port pop dx ; [jrd] pop bx pop ax Baud_R: ret ; ...and return ; bd_bd: mov ah,prstr mov dx,offset badbd ; Say it's not implemented int dos mov bx,portval mov [bx].baud,0FFFFH ; So it's not a recognized value pop dx pop bx pop ax ret ; Must be set before starting Kermit DOBAUD ENDP ; Use hardware parity of None so software routines can do the work. [jrd] DOPARITY PROC NEAR push ax ; save regs push bx push cx push dx ;; mov bx,portval ;; mov dl,[bx].parflg ; get parity flag ;; cmp dl,0 ;; jne par_1 ;; mov dx,'0' ; even parity ;; jmp par_3 ;;par_1: cmp dl,2 ;; jne par_2 mov dx,'4' ; no parity ;; jmp par_3 ;;par_2: cmp dl,3 ;; jne bd_par ;; mov dx,'1' ; odd parity par_3: mov par_x,dl ; set up string mov dx,offset par_str ; point to string mov cx,3 ; 3 lettters in string cmp prthnd,0 ; is port open je Par_R ; No, skip hardware set call w_ioctl ; write to ioctl of serial port pop dx ; [jrd] pop cx pop bx pop ax Par_R: ret ; ...and return bd_par: mov bx,portval mov [bx].parflg,0 mov ah,prstr mov dx,offset badpar int dos pop dx pop cx pop bx pop ax ret DOPARITY ENDP ; Get the current baud rate from the serial card and set it ; in the portinfo structure for the current port. Returns normally. ; This is used during initialization. GETBAUD PROC NEAR ret ; Can't do this GETBAUD ENDP ; SHOW MODEM - displays status of modem lines DSR, CD, CTS, in this case ; it just says whether or not the port is ready for i/o. shomodem proc near mov ah,cmcfm ; get a confirm call comnd jmp r ; no confirm nop cmp prthnd,0 ; Got a handle yet? jne shmod0 ; Yup just go on call opnprt ; Else 'open' the port shmod0: mov dx,offset msmsg1 ; say port is not ready mov bx,prthnd mov al,7 ; output status command mov ah,ioctl ; ask DOS to look for us int dos jc shmod1 ; c = call failed, device not ready or al,al jz shmod1 ; not ready mov dx,offset msmsg2 ; say port is ready shmod1: mov ah,prstr int dos jmp rskp shomodem endp getmodem proc near mov al,0 ; no modem status ret getmodem endp ; ; write cx bytes to ioctl of serial port ; W_IOCTL PROC NEAR push ax ; save regs push bx mov ah,ioctl mov al,3 mov bx,prthnd int dos pop bx pop ax ret W_IOCTL ENDP ; ; read cx bytes from ioctl of serial port to tempbuf ; R_IOCTL PROC NEAR push ax ; save regs push bx mov ah,ioctl mov al,2 mov bx,prthnd mov dx,offset tempbuf int dos pop bx pop ax ret R_IOCTL ENDP ; ; check serial port for characters and return number in al ; CHK_BUFF PROC NEAR push cx push dx mov dx,offset chk_msg mov cx,2 call w_ioctl mov cx,1 call r_ioctl mov ax,tempbuf pop dx pop cx ret CHK_BUFF ENDP ; Use for DOS 2.0 and above. Check the port status. If no data, skip ; return. Else, read in a char and return. PRTCHR PROC NEAR push bx push cx push si cmp prthnd,0 ; got a handle jne prtch1 ; ne = yes call opnprt ; open port if not prtch1: cmp count,0 ; any chars in buffer? jne prtch2 ; ...yes, get one call chk_buff ; any chars at port? or al,al jz prtch4 ; no, go to skip return mov ah,0 mov cx,1 ; read one char mov count,cx mov bx,prthnd mov ah,readf2 ; DOS read from file/device mov dx,offset source int dos jc prt3x ; c = failure mov bufout,offset source prtch2: dec count mov si,bufout cld lodsb mov bufout,si prtch3: pop si pop cx pop bx ret ; return success prt3x: mov ah,prstr mov dx,offset erms50 int dos prtch4: pop si pop cx pop bx jmp rskp ; no chars PRTCHR ENDP ; Send a break out the current serial port. Returns normally. SENDBR PROC NEAR push cx push dx mov dx,offset brk_on mov cx,3 call w_ioctl mov dx,offset brk_off mov cx,3 call w_ioctl pop dx pop cx clc ; clear carry to stay in Connect mode ret SENDBR ENDP SENDBL PROC NEAR ; Send a Long Break jmp sendbr ; same as regular here SENDBL ENDP ; IHOSTS - Initialize the host by sending XON, or equivalent, and enter the ; cycle of clear input buffer, wait 1 second, test if buffer empty then exit ; else repeat cycle. Requires that the port be initialized before hand. ; Ihosts is used by the local send-file routine just after initializing ; the serial port. ; 22 March 1986 [jrd] IHOSTS PROC NEAR push ax ; save the registers push bx push cx push dx mov bx,portval ; port indicator mov ax,[bx].flowc ; put Go-ahead flow control char in ah or ah,ah ; don't send null if flow = none jz ihosts1 ; z = null call outchr ; send it (release Host's output queue) nop ; outchr can do skip return nop nop ihosts1:call clrbuf ; clear out interrupt buffer pop dx ; empty buffer. we are done here pop cx pop bx pop ax ret IHOSTS ENDP ; IHOSTR - initialize the remote host for our reception of a file by ; sending the flow-on character (XON typically) to release any held ; data. Called by receive-file code just after initializing the serial ; port. 22 March 1986 [jrd] IHOSTR PROC NEAR push ax ; save regs push bx push cx mov bx,portval ; port indicator mov ax,[bx].flowc ; put Go-ahead flow control char in ah or ah,ah ; don't send null if flow = none jz ihostr1 ; z = null call outchr ; send it (release Host's output queue) nop ; outchr can do skip return nop nop ihostr1:pop cx pop bx pop ax ret IHOSTR ENDP DTRLOW PROC NEAR ; Global proc to Hangup the Phone by making ; DTR and RTS low. mov ah,cmtxt ; allow text to be able to display help mov bx,offset rdbuf ; dummy buffer mov dx,offset hnghlp ; help message call comnd ; get a confirm jmp r call serhng ; drop DTR and RTS mov ah,prstr ; give a nice message mov dx,offset hngmsg int dos jmp rskp DTRLOW ENDP ; Hang up the Phone. Similar to SERRST except it just forces DTR and RTS low ; to terminate the connection. 29 March 1986 [jrd] ; Calling this twice without intervening calls to serini should be harmless. ; Returns normally. ; Adapted from recommendation by Mike Mellinger. [jrd] SERHNG PROC NEAR push ax push bx push cx push dx mov dx,offset com2 mov ah,open2 ; open device AUX mov al,1 ; for writing int dos jc serhn1 ; c = error mov bx,ax ; file handle mov ah,write2 mov dx,offset $off_m ; magic words to turn off DTR mov cx,off_len ; their length int dos ; write them mov ah,close2 ; close the device int dos serhn1: pop dx pop cx pop bx pop ax ret SERHNG ENDP ; Wait for the # of milliseconds in ax, for non-IBM compatibles. ; Thanks to Bernie Eiben for this one. pcwait proc near mov cx,240 ; inner loop counter for 1 millisecond pcwai1: sub cx,1 ; inner loop takes 20 clock cycles jnz pcwai1 dec ax ; outer loop counter jnz pcwait ; wait another millisecond ret pcwait endp ; Position the cursor according to contents of DX: ; DH contains row, DL contains column. Returns normally. POSCUR PROC NEAR push ax ; save regs push dx push di mov ax,ds mov es,ax ; address data segment!! cld mov di,offset colno mov al,dl ; column call nout mov al,'x' stosb mov al,dh ; row call nout mov al,'Y' stosb mov al,'$' stosb mov dx,offset movcur mov ah,prstr int dos ; print the sequence pop di pop dx pop ax ret POSCUR ENDP NOUT PROC NEAR cbw ; extend the word div byte ptr ten ; divide by ten or al,al ; any quotient? jz nout1 ; no, forget this push ax ; save current result call nout ; output high order pop ax ; restore nout1: mov al,ah ; get digit add al,'0' ; make printable stosb ; put in buffer ret ; and return NOUT ENDP ; Delete a character from the terminal. This works by printing ; backspaces and spaces. Returns normally. DODEL PROC NEAR push ax ; save regs push dx mov ah,prstr mov dx,offset delstr ; Erase weird character int dos pop dx pop ax ret DODEL ENDP ; Move the cursor to the left margin, then clear to end of line. ; Returns normally. CTLU PROC NEAR push ax ; save regs push dx mov ah,prstr mov dx,offset clrlin int dos call clearl pop dx pop ax ret CTLU ENDP ; Set the current port. COMS PROC NEAR call serr_x ; force close on serial port mov dx,offset comptab ; table of comms ports mov bx,0 ; use keywords as help mov ah,cmkey ; parse a keyword call comnd jmp r ; failure nop push bx mov ah,cmcfm call comnd ; Get a confirm jmp comx ; Didn't get a confirm nop pop bx mov flags.comflg,bl ; Set the comm port flag cmp flags.comflg,1 ; Using Com 1? jne coms2 ; ne = no mov portval,offset port1 ret coms2: cmp bl,2 ; using com2? jne coms3 ; ne = no mov portval,offset port2 ret coms3: mov portval,offset port3 ret comx: pop bx ret COMS ENDP ; Set heath emulation on/off. VTS PROC NEAR jmp notimp VTS ENDP VTSTAT PROC NEAR ; For Status display [jrd] ret ; no emulator status to display VTSTAT ENDP ; Save the screen to a buffer and then append buffer to a disk file. [jrd] ; Default filename is Kermit.scn; actual file can be a device too. Filename ; is determined by mssset and is passed as pointer dmpname. DUMPSCR PROC NEAR ; Dumps screen contents to a file. Just Beeps here call beep ret DUMPSCR ENDP notimp: mov ah,prstr mov dx,offset noimp int dos jmp prserr ; Initialize variables to values used by the generic MS DOS version. lclini: call msuinit ; init keyboard translator mov flags.vtflg,0 ; Don't do terminal emulation mov prthnd,0 ; no port handle yet. [jrd] ;;; call opnprt ; Get file handle for comm port push bx mov bx,offset port1 mov [bx].baud,B9600 ; port1 -> 9600 baud mov [bx].parflg,2 ; no parity mov bx,offset port2 mov [bx].baud,B1200 ; port2 -> 1200 baud mov [bx].parflg,2 ; no parity pop bx ret ; Get a file handle for the communications port. Use DOS call to get the ; next available handle. If it fails, ask user what value to use (there ; should be a predefined handle for the port, generally 3). The open ; will fail if the system uses names other than "COM1", "COM2", "COM3","AUX". opnprt: mov al,flags.comflg dec al ; flags.comflg = 1 for com1, 2 com2, 3 com3 mov ah,0 mov si,ax shl si,1 ; double index mov dx,prttab[si] mov ah,open2 mov al,2 int dos jnc opnpr1 mov ah,prstr ; It didn't like the string mov dx,offset erms41 int dos mov prthnd,0 ; clear port file handle stc ; carry set for failure ret opnpr1: mov prthnd,ax ; Call succeeded mov ah,ioctl mov al,00h ; get device info xor dx,dx mov bx,prthnd ; port's handle int dos or dl,20h ; set binary mode in device info mov dh,0 mov ah,ioctl mov al,01h ; set device info int dos ret ; carry clear for success showkey: mov ax,offset shkmsg mov cx,shklen ret ; Initialization for using serial port. Returns normally. SERINI PROC NEAR cld ; Do increments in string operations cmp prthnd,0 ; Got Handle already? jne ser_x ; ne = yes, skip open call opnprt ; open handle jc serin2 ; carry set = failure mov cx,3 mov ax,portval cmp ax,offset port1 jnz seri mov dx,offset $m1 jmp serx seri: mov dx,offset $m0 serx: call w_ioctl ser_x: mov dx,offset ini_msg mov cx,15 call w_ioctl call dobaud ; set baud rate call doparity ; set parity push bx mov bx,portval ; get port mov parmsk,0ffh ; parity mask, assume parity is None cmp [bx].parflg,parnon ; is it None? je serin1 ; e = yes mov parmsk,07fh ; no, pass lower 7 bits as data serin1: mov bx,[bx].flowc ; get flow control chars mov flowoff,bl ; xoff or null mov flowon,bh ; xon or null pop bx clc ; carry clear for success serin2: ret SERINI ENDP ; Reset the serial port. This is the opposite of serini. Calling ; this twice without intervening calls to serini should be harmless. ; Returns normally. SERRST PROC NEAR cmp flags.extflg,0 jne serr_x ret serr_x: push bx ; save reg cmp prthnd,0 ; handle there? je serr_1 ; no, don't try to close mov cx,off_len mov dx,offset $off_m call w_ioctl mov bx,prthnd mov ah,close2 int dos ; close handle mov prthnd,0 serr_1: pop bx ret SERRST ENDP ; Produce a short beep. The PC DOS bell is long enough to cause a loss ; of data at the port. Returns normally. BEEP PROC NEAR mov dl,bell mov ah,dconio int dos ret BEEP ENDP ; Dumb terminal emulator. Doesn't work too well above 1200 baud (and ; even at 1200 baud you sometimes lose the first one or two characters ; on a line). Does capture (logging), local echo, debug display, tests ; for printer/logging device not ready. 27 Sept 86 [jrd]. term proc near mov argadr,ax ; save argument ptr mov si,ax ; this is source mov di,offset ourarg ; place to store arguments push es ; save register push ds pop es ; set es to datas segment mov cx,size termarg cld rep movsb ; copy into our arg blk pop es ; restore reg and ourarg.flgs,not (prtscr) ; no screen printing at startup mov ax,ourarg.captr mov captrtn,ax ; buffer capture routine mov parmsk,0ffh ; parity mask, assume parity = None cmp ourarg.parity,parnon ; is parity None? je term1 ; e = yes, keep all 8 bits mov parmsk,07fh ; else keep lower 7 bits term1: call portchr ; get char from port, apply parity mask jnc short term2 ; nc = no char, go on call outtty ; display and capture char term2: call keybd ; call keyboard translator in msu jnc term1 ; nc = no char or have processed it ; carry set = quit Connect mode term4: ret term endp ; put the character in al to the screen, do capture and printing, ; does translation for Set Input command. ; Adapted from msyibm.asm [jrd] outtty proc near test flags.remflg,d8bit ; keep 8 bits for displays? jnz outnp8 ; nz = yes, 8 bits if possible and al,7fh ; remove high bit outnp8: cmp rxtable+256,0 ; is translation off? je outnp7 ; e = yes, off push bx ; Translate incoming char mov bx,offset rxtable ; address of translate table xlatb ; new char is in al pop bx outnp7: push bx mov bx,argadr ; args from msster directly test [bx].flgs,capt ; capturing output? Can be shut off pop bx ; if out dev becomes not ready jz outnoc ; no, forget this part push ax ; save char call captrtn ; give it captured character pop ax ; restore character and keep going outnoc: test ourarg.flgs,prtscr ; should we be printing? jz outnop ; no, keep going push ax mov ah,print_out ; write to system printer device mov dl,al int dos pop ax jnc outnop ; nc = successful print push ax call beep ; else make a noise and call trnprs ; turn off printing pop ax outnop: cmp flags.vtflg,0 ; emulating a terminal? jnz outnop1 ; nz = yup, go do something smart test ourarg.flgs,trnctl ; debug? if so use dos tty mode jz outnp4 ; z = no mov ah,conout cmp al,7fh ; Ascii Del char or greater? jb outnp1 ; b = no je outnp0 ; e = Del char push ax ; save the char mov dl,7eh ; output a tilde for 8th bit int dos pop ax ; restore char and al,7fh ; strip high bit outnp0: cmp al,7fh ; is char now a DEL? jne outnp1 ; ne = no and al,3fH ; strip next highest bit (Del --> '?') jmp outnp2 ; send, preceded by caret outnp1: cmp al,' ' ; control char? jae outnp3 ; ae = no add al,'A'-1 ; make visible outnp2: push ax ; save char mov dl,5eh ; caret int dos ; display it pop ax ; recover the non-printable char outnp3: mov dl,al int dos ret outnp4: cmp al,bell ; bell (Control G)? jne outnp5 ; ne = no jmp beep ; use short beep, avoid char loss outnop1: outnp5: mov ah,conout ; dostty screen mode mov dl,al ; write without intervention int dos ; else let dos display char ret ; and return outtty endp ; send the character in al out to the serial port; handle echoing. ; Can send an 8 bit char while displaying only 7 bits locally. outprt proc near test ourarg.flgs,lclecho ; echoing? jz outpr1 ; z = no, forget it push ax ; save char call outtty ; print it pop ax ; restore outpr1: mov ah,al ; this is where outchr expects it call outchr ; output to the port nop nop nop ; skip returns ret outprt endp ; Get a char from the serial port manager ; returns with carry on if a character is available portchr proc near call prtchr ; character at port? jmp short portc1 ; yes, go handle nop ; skip return is stupid portc0: clc ; no carry -> no character ret ; and return portc1: and al,parmsk ; apply 8/7 bit parity mask or al,al ; catch nulls jz portc0 ; z = null, ignore it cmp al,del ; catch dels je portc0 ; e = del, ignore it stc ; have a character ret ; and return portchr endp ;; keyboard translator action routines, system dependent, called from msugen. ; These are invoked by a jump instruction. Return carry clear for normal ; processing, return carry set to exit Connect mode (kbdflg has transfer char) chrout: call outprt ; put char in al to serial port clc ; stay in Connect mode ret trnprs: push ax ; toggle Copy screen to printer test ourarg.flgs,prtscr ; are we currently printing? jnz trnpr2 ; nz = yes, its on and going off mov ah,ioctl mov al,7 ; get output status of printer push bx mov bx,4 ; file handle for system printer int dos pop bx jc trnpr1 ; c = printer not ready cmp al,0ffh ; Ready status? je trnpr2 ; e = Ready trnpr1: call beep ; Not Ready, complain jmp trnpr3 ; and ignore request trnpr2: xor ourarg.flgs,prtscr ; flip the flag trnpr3: pop ax clc ret klogon proc near ; resume logging (if any) test flags.capflg,logses ; session logging enabled? jz klogn ; z = no, forget it or ourarg.flgs,capt ; turn on capture flag klogn: clc ret klogon endp klogof proc near ; suspend logging (if any) and argadr.flgs,not capt ; stop capturing klogo: clc ret klogof endp snull: mov ah,0 ; send a null call outchr ; send without echo or logging nop nop nop clc ret kdos: mov al,'P' ; Push to DOS jmp short cmdcom cstatus:mov al,'S' ; these commands exit Connect mode jmp short cmdcom cquit: mov al,'C' jmp short cmdcom cquery: mov al,'?' jmp short cmdcom cmdcom: mov kbdflg,al ; pass char to msster.asm via kbdflg stc ; say exit Connect mode ret ; Jumping to this location is like retskp. It assumes the instruction ; after the call is a jmp addr. RSKP PROC NEAR pop bp add bp,3 push bp ret RSKP ENDP ; Jumping here is the same as a ret. R PROC NEAR ret R ENDP code ends end