name msxhp1 ; File MSXHP1.ASM ; System dependent module for HP150. ; Latest modification: 20 April 1986 ; Add global entry point vtstat for use by Status in mssset. ; Add clearing of terminal emulation flag, flags.vtflg, in procedure lclini. ; Joe R. Doupnik 12 March 1986 ; Add register save/restore in poscur and in other procedures as well. ; 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] ; Fix procedure getbaud to report unrecognized baud rate. [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 inverse video mode line from Arvind Kumar @ hplabs marked [ak], 1/86 public serini, serrst, clrbuf, outchr, coms, vts, vtstat, dodel, ctlu public cmblnk, locate, prtchr, dobaud, clearl, lclini public dodisk, getbaud, beep, setkhlp, setktab public machnam, xofsnt, count, term, poscur public clrmod, putmod, puthlp, sendbr, showkey public ihosts, ihostr, dtrlow, dumpscr ; [jrd] include mssdef.h false equ 0 true equ 1 wrdev equ 40H rddev equ 3fH open equ 3dH close equ 3eH rdchan equ 2 e_send_break equ 6 e_ioctl equ 44h ; DOS i/o control function [jrd] datas segment public 'datas' extrn drives:byte, flags:byte, trans:byte extrn portval:word, port1:byte, port2:byte, dmpname:byte ; [jrd] machnam db 'HP-150$' erms20 db cr,lf,'?Warning: System has no disk drives$' ; [21a] erms40 db cr,lf,'?Warning: Unrecognized baud rate$' erms41 db cr,lf,'?Warning: Cannot open com port$' noimp db cr,lf,'Command not implemented.$' hngmsg db cr,lf,' The phone should have hungup.',cr,lf,'$' ; [jrd] 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,'$' ; [jrd] rdbuf db 80 dup (?) ; temp buf [jrd] setktab db 0 setkhlp db 0 shkmsg db 'Not implemented.' shklen equ $-shkmsg crlf db cr,lf,'$' comphlp db cr,lf,'1 (COM1) 2 (COM2)$' ; [19b] delstr db BS,BS,' ',BS,BS,'$' ; Delete string. [21d] clrlin db cr,esc,'K$' xofsnt db 0 ; Say if we sent an XOFF. xofrcv db 0 ; Say if we received an XOFF. invseq db esc,'&dB$' ; Reverse video. nrmseq db esc,'&d@$' ; Normal mode. ivlseq db 80 dup (' '),esc,'A','$' ; [ak] Make a line inverse video tmp db ?,'$' temp dw 0 temp1 dw ? ; Temporary storage. temp2 dw ? ; Temporary storage. ; Entries for choosing communications port. [19b] comptab db 04H db 01H,'1$' dw 01H db 01H,'2$' dw 00H db 04H,'COM1$' dw 01H db 04H,'COM2$' dw 00H ; variables for serial interrupt handler source db bufsiz DUP(?) ; Buffer for data from port. bufout dw 0 ; buffer removal ptr count dw 0 ; Number of chars in int buffer. bufin dw 0 ; buffer insertion ptr telflg db 0 ; Are we acting as a terminal. [16] [17c] clreol db esc,'K$' prttab dw com2,com1 com1 db 'COM1',0 com2 db 'COM2',0 blank db esc,'H',esc,'J$' movcur db esc,'&a' colno db 20 dup (?) ten db 10 prthnd dw 0 tempbuf dw 10 dup(?) ourarg termarg <> datas ends code segment public 'code' extrn comnd:near, dopar:near, prserr:near extrn sleep:near ; [jrd] assume cs:code,ds:datas ; See how many disk drives we have. 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 before sending a packet. [20e] CLRBUF PROC NEAR cli mov ax,offset source mov bufin,ax mov bufout,ax mov count,0 sti clrb1: call prtchr ; get a character jmp clrb1 ; until there aren't any more nop ret CLRBUF ENDP ; Common routine to clear to end-of-line. [19a] CLEARL PROC NEAR push ax ; save regs [jrd] push dx mov dx,offset clreol mov ah,prstr int dos pop dx ; restore regs [jrd] pop ax ret CLEARL ENDP dobaud proc near ; updated by [jrd] to set baud. mov ah,prstr mov dx,offset noimp ; Say it's not implemented. int dos push bx ; save reg. [jrd] mov bx,portval mov [bx].baud,0FFFFH ; So it's not a recognized value. pop bx ret ; Must be set before starting Kermit. ;;;[jrd] jmp notimp dobaud endp ; Send the break signal out data comm. sendbr: mov al,e_send_break jmp dc_ioctl ; Set some data comm ioctl option. AL has function code. dc_ioctl proc near push ax ; save regs [jrd] push bx push cx push dx mov ah,8h mov tempbuf,ax mov dx,offset tempbuf mov ah,e_ioctl mov al,3 mov bx,prthnd mov cx,2 int 21h pop dx ; restore regs [jrd] pop cx pop bx pop ax ret dc_ioctl endp outchr: push bp ; save regs. [jrd] push cx mov bp,portval cmp ds:[bp].floflg,0 ; Are we doing flow control. je outch2 ; No, just continue. xor cx,cx ; clear counter cmp ah,byte ptr [bp].flowc ; sending xoff? [jrd] 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. push bx cmp prthnd,0 ; do we have a port handle? jne outch3 ; yes, go on push ax call opnprt ; open the port pop ax outch3: mov byte ptr temp,ah ; save character mov bx,prthnd mov ah,wrdev mov cx,1 mov dx,offset temp int dos pop bx pop dx pop cx ; [jrd] pop bp jmp rskp opnprt: mov al,flags.comflg mov ah,0 push si ; [jrd] mov si,ax shl si,1 ; double index mov dx,prttab[si] pop si ; [jrd] mov ah,open mov al,2 int dos jnc opnpr1 mov ah,prstr mov dx,offset erms41 int dos ret opnpr1: mov prthnd,ax ret ; This routine blanks the screen. CMBLNK PROC NEAR ; This is stolen from the IBM example. mov ah,prstr mov dx,offset blank int dos ret CMBLNK ENDP LOCATE PROC NEAR mov dx,0 ; Go to top left corner of screen. jmp poscur ; callret... LOCATE ENDP GETBAUD PROC NEAR ret GETBAUD ENDP ; skip returns if no character available at port, ; otherwise returns with char in al, # of chars in buffer in dx. PRTCHR PROC NEAR push bx push cx push si push bp cmp prthnd,0 ; have a handle yet? jne prtch1 ; yes, keep going call opnprt prtch1: cmp count,0 ; no characters? [jrd] jne prtch2 ; no, go fill buffer [jrd] mov bx,prthnd mov al,rdchan mov ah,ioctl mov dx,offset source ; buffer to read into mov cx,bufsiz ; length of buffer int dos mov count,ax ; reset count mov dx,ax ; needed to obey rules [jrd] or ax,ax jz prtch4 ; still no chars mov bufout,offset source ; this is output ptr prtch2: dec count mov dx,count ; return count in dx mov si,bufout lodsb ; get character mov bufout,si ; update ptr mov bp,portval cmp ds:[bp].parflg,PARNON ; no parity? je prtch3 ; then don't strip and al,7fh ; else turn off parity prtch3: pop bp pop si pop cx pop bx ret prtch4: pop bp pop si pop cx pop bx jmp rskp ; no chars... PRTCHR 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 call outchr ; send it (release Host's output queue) nop ; outchr can do skip return nop nop ihosts1:call clrbuf ; clear out interrupt buffer mov ax,1 ; sleep for 1 second call sleep ; procedure sleep is in msscom.asm call prtchr ; check for char at port jmp ihosts1 ; have a char in al, repeat wait/read cycle nop ; prtchr does skip return on empty 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 call outchr ; send it (release Host's output queue) nop ; outchr can do skip return nop nop 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 ; not yet imp. call serhng ; drop DTR and RTS mov ah,prstr ; give a nice message ; not yet imp. mov dx,offset hngmsg mov dx,offset noimp ; for now 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. ; SERHNG is Not Yet Implemented. ; Position the cursor according to contents of DX. POSCUR PROC NEAR push ax ; save regs [jrd] push dx push di push es mov ax,ds mov es,ax ; address data segment!!! cld mov di,offset colno mov al,dl ; column call nout mov al,'c' 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 es ; restore regs [jrd] pop di pop dx pop ax ret POSCUR ENDP NOUT PROC NEAR cbw ; extend to word div byte ptr ten ; divide by 10 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 ret ; put in buffer and return NOUT endp ; Write a line in inverse video at the bottom of the screen... ; the line is passed in dx, terminated by a $. Returns normally. putmod proc near push dx ; preserve message mov dx,24 * 100H ; line 24 call poscur mov dx,offset invseq ; put into inverse video mov ah,prstr int dos pop dx int dos mov dx,offset nrmseq ; normal videw int dos ret ; and return putmod endp ; Clear the mode line written by putmod. Returns normally. clrmod proc near mov dx,24 * 100H call poscur call clearl ret clrmod endp ; Put a help message one the screen in reverse video. Pass ; the message in AX, terminated by a null. Returns normally. ; The message is put wherever the cursor currently is located. puthlp proc near push ax mov ah,prstr ; Leave some room before the message. mov dx,offset crlf int dos pop si ; Put message address here. 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 puth1: lodsb cmp al,0 ; Terminated with a null. je puth2 mov dl,al mov ah,conout int dos cmp al,lf ; Line feed? je puth0 ; Yes, clear the next line. jmp puth1 ; Else, just keep on writing. puth2: mov dx,offset crlf mov ah,prstr int dos mov dx,offset nrmseq ; Normal video. int dos ret puthlp endp ; Perform a delete. DODEL PROC NEAR mov ah,prstr mov dx,offset delstr ; Erase weird character. int dos ret DODEL ENDP ; Perform a Control-U. CTLU PROC NEAR mov ah,prstr mov dx,offset clrlin int dos ret CTLU ENDP COMS PROC NEAR mov dx,offset comptab mov bx,offset comphlp mov ah,cmkey call comnd jmp r 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 coms0 ; Nope. mov ax,offset port1 mov portval,ax ret coms0: mov ax,offset port2 mov portval,ax ret comx: pop bx ret COMS ENDP 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 ; [jrd] ret DUMPSCR ENDP notimp: mov ah,prstr mov dx,offset noimp int dos jmp prserr lclini: mov flags.vtflg,0 ; no terminal emulation. [jrd] mov prthnd,0 ; no port handle yet. [jrd] ret showkey: mov ax,offset shkmsg mov cx,shklen ret ; Common initialization for using serial port. SERINI PROC NEAR call opnprt call clrbuf ; Clear input buffer. [20e] ret ; We're done. [21c] SERINI ENDP SERRST PROC NEAR push bx ; save reg. [jrd] mov bx,prthnd cmp bx,0 ; none there? je serrs1 ; no, don't try to close. mov ah,close int dos ; close handle mov prthnd,0 serrs1: pop bx ; [jrd] ret ; All done. [21c] SERRST ENDP ; Generate a short beep. BEEP PROC NEAR mov dl,bell mov ah,conout int dos ret BEEP ENDP ; 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 term proc near mov si,ax ; this is source mov di,offset ourarg ; place to store arguments mov ax,ds mov es,ax ; address destination segment mov cx,size termarg rep movsb ; copy into our arg blk term1: call prtchr jmp short term2 ; have a char... nop nop jmp short term3 ; no char, go on term2: push ax mov dl,al and dl,7fh ; mask off parity for terminal mov ah,dconio int dos ; write out the character pop ax test ourarg.flgs,capt ; capturing output? jz term3 ; no, forget it call ourarg.captr ; else call the routine term3: mov ah,dconio mov dl,0ffh int dos jz term1 ; no character, go on cmp al,ourarg.escc ; escape char? je term4 ; yes, exit push ax ; save char mov ah,al or ah,80H ; turn on hi bit so DOS doesn't interfere call outchr ; output the character nop nop nop pop ax test ourarg.flgs,lclecho ; echoing? jz term1 ; no, continue loop mov dl,al mov ah,dconio int dos jmp term1 ; else echo and keep going term4: ret term endp code ends end