name msxhp1 ; File MSXHP1.ASM include mssdef.h ; Copyright (C) 1982,1991, Trustees of Columbia University in the ; City of New York. Permission is granted to any individual or ; institution to use, copy, or redistribute this software as long as ; it is not sold for profit and this copyright notice is retained. ; System dependent module for HP150. ; Use with file MSUHP1.ASM (keyboard translator) ; Edit history ; 2 March 1991 version 3.10 ; Nov. 24, 1990. Remove references to prserr to make linker happy. ; Nov. 21, 1990. Dump capture buffer (cptdmp) when exiting connect mode. [jan] ; Sept. 1990. Read 20 characters a time from dcomm. Read keyboard ; once every 16 reads of dc port. Start port at 7 bits so firmware ; flow control works. Disable our own flow control. Now works at 4800 ; baud with no flow control. ; August 1990 update to 3.0. Incorporate tektronix. Add replay. [jan]. ; John Nyenhuis, Purdue University, School of Electrical Engineering ; West Lafayette, Indiana 47907 USA (317)494-3524 nyenhuis@ecn.purdue.edu ; 1 July 1988 Version 2.31 ; 11 Jan 1988 update to 2.30 consistency level. ; 1 Jan 1988 version 2.30 writechar macro saying pushf push dx push ax mov ah,2 mov dl,saying int dos pop ax pop dx popf endm writestring macro saying pushf push ax push dx mov ah,prstr mov dx,offset saying int dos pop dx pop ax popf endm saveregs macro push ax push bx push cx push dx push es push di push si push ds push bp pushf endm restoreregs macro popf pop bp pop ds pop si pop di pop es pop dx pop cx pop bx pop ax endm ;; below 40 publics are the minimum necessary public baudst, ihostr, bdtab, getbaud, chrout, pcwait, putmod public serrst, trnprs, prtchr, poscur, outchr, dtrlow, vts, puthlp public vtstat, coms, cquery, ctlu, shomodem, portval, getmodem public term, dumpscr, cmblnk, cquit, locate, clearl, machnam, lclini public sendbl, comptab, sendbr, clrmod, cstatus, termtb, serhng public clrbuf, beep, serini ;;additional system dependent publics public termtog, kclrscn, kdos, snull, cquit, cquery public toterminal, klogtog, setchtab, vtstbl 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 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 passall equ 0803h ; Port transparency mode [WHM] xofcnt equ 32 ; number of characters to send xoff xoncnt equ 16 ; number of characters to send xon dos201 equ 201h dos211 equ 20bh ; dosnum for 2.11 data segment public 'data' extrn lclexit:word, flags:byte, trans:byte, dmpname:byte extrn kbdflg:byte, rxtable:byte, denyflg:word, repflg:byte extrn diskio:byte ; for replay feature extrn dosnum:word, agiosbuff:byte extrn sloghnd:word ; session log handle from msster extrn prnhand:word machnam db 'HP-150$' 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,'$' 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 (0) ; temp buf setktab db 0 setkhlp db 0 shkmsg db '?Not implemented.' shklen equ $-shkmsg anspflg db 0 ; printing active status crlf db cr,lf,'$' delstr db BS,BS,' ',BS,BS,'$' ; Delete string clrlin db cr,ESCAPE,'K$' xofsnt db 0 ; Say if we sent an XOFF xofrcv db 0 ; Say if we received an XOFF invseq db ESCAPE,'&dJ$' ; Reverse video nrmseq db ESCAPE,'&d@$' ; Normal mode ivlseq db 80 dup (' '),ESCAPE,'A','$' ; [ak] Make a line inverse video keydelay db 0 ; delay for keyboard reads tmp db 0,'$' temp dw 0 temp1 dw 0 temp2 dw 0 eightstatustxt db 'No. Bits: $' eightflg db eightbitnum transparencytxt db 'Port Status: $' transparentflg db transonnum rawtxt db 'Port Mode: $' rawflg db rawonnum tekstatustxt db 'Tek Auto Entry: $' tekbyte db tekonnum ; tek auto entry temp3 dw 0 ; structure for status information table sttab. stent struc sttyp dw 0 ; type (actually routine to call) msg dw 0 ; message to print val2 dw 0 ; needed value: another message, or tbl addr tstcel dw 0 ; address of cell to test, in data segment basval dw 0 ; base value, if non-zero stent ends ; table with datacomm status for the status command vtstbl stent ; tell 7 or 8 bits stent ; tell if transparent stent ; tell if raw or cooked stent ; tell if raw or cooked dw 0 ; end of table ; Entries for choosing communications port comptab db 4 ; four entries mkeyw '1',1 mkeyw '2',2 mkeyw 'COM1',1 mkeyw 'COM2',2 port1 prtinfo <0FFFH,0,defpar,1,0,defhand,floxon,0> port2 prtinfo <0FFFH,0,defpar,1,0,defhand,floxon,0> portval dw port1 ; Default is to use port 1 bdtab db 9 ; baud rate table mkeyw '110',0 mkeyw '150',1 mkeyw '300',2 mkeyw '600',3 mkeyw '1200',4 mkeyw '2400',5 mkeyw '4800',6 mkeyw '9600',7 mkeyw '19200',8 ; mappings for baud settings from hp to our table ourbdtab db 0,0 ; not applicable db 1,0 ; na db 2,0 ; 110 db 3,0 ; na db 4,1 ; 150 db 5,2 ; 300 db 6,3 ; 600 db 7,4 ; 1200 db 8,0 ; na db 9,0 ; na db 10,5 ; 2400 db 11,0 ; na db 12,6 ; 4800 db 13,0 ; na db 14,7 ; 9600 db 15,8 ; 19200 ; mappings for baud setting from our table to hp ourbdtab1 db 0,2 ; 300 db 1,4 ; 150 db 2,5 ; 300 db 3,6 ; 600 db 4,7 ; 1200 db 5,10 ; 2400 db 6,12 ; 4800 db 7,14 ; 9600 db 8,15 ; 19200 setchtab db 1; set file character-set table mkeyw 'CP437',437 sevenbitnum equ 7 eightbitnum equ 8 transonnum equ 9 transoffnum equ 10 rawonnum equ 11 rawoffnum equ 12 tekonnum equ 13 tekoffnum equ 14 termtb db 10 ; entries for Status, not Set mkeyw 'HP150',ttgenrc mkeyw 'Tek4014',tttek mkeyw '7bit',sevenbitnum mkeyw '8bit',eightbitnum mkeyw 'OnTransparency',transonnum mkeyw 'OffTransparency',transoffnum mkeyw 'Raw',rawonnum mkeyw 'Cooked',rawoffnum mkeyw 'EnableTek',tekonnum mkeyw 'DisableTek',tekoffnum ; 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 clreol db ESCAPE,'K$' prttab dw com1,com2 com1 db 'COM1',0 com2 db 'COM2',0 blank db ESCAPE,'H',ESCAPE,'J$' movcur db ESCAPE,'&a' colno db 20 dup (0) ten db 10 prthnd dw 0 argadr dw 0 ; address of arg blk from msster.asm parmsk db 0ffh ; 8/7 bit parity mask, for reception flowoff db 0 ; flow-off char, Xoff or null (if no flow) flowon db 0 ; flow-on char, Xon or null captrtn dw cptchr ; routine to call for captured output logflag db false ; if true, we are logging session ; (we have taken cptchr from msster and placed in ; in msxhp1 to avoid flow control problems) tempbuf dw 10 dup(0) ourarg termarg <> ;;new stuff to scan escape sequences from comm port [jan] stringtab dw tekst1,tekst2 ; strings for matching dw tekst3 numstrings equ 3 ; number of strings to match disptab dw toteknoplay,totekplay ; dispatch table dw leavetek dw ignoreall, ignoreall tekst1 db escape,'[?38h',0 ;1st string to get into tek mode [jan] tekst2 db escape,FF,0 ;2nd string to get into tek mode [jan] tekst3 db escape,'[?38l',0 ; string to exit tekmode stringchekbuff db 16 dup (0) stringchekcnt dw 0 ; characters already in buffer matchsofar dw false ; no match yet match dw 0 playem db false ; don't play back switch characters ; end of data for string scannine prtrdy db true ; if false, we get out of connect mode capbuf db cptsiz dup (0) ; session logging buffer capbp dw capbuf caplft dw cptsiz capterr db escape,'Error in writing log file ','$' alpha_disp db escape,'&s0P',escape,'&s0Q','$' ; alpha active tek_disp db escape,'&s1P',escape,'&s0Q',escape,'*t1D','$' ; tek active alpha_on db escape,'*dE','$' ; turn on alpha display alpha_off db escape,'*dF','$' ; turn off alpha display tek_on db escape,'*dC','$' ; turn on tek display tek_off db escape,'*dD','$' ; turn off tek display alpha_clear db escape,'H',escape,'J', '$' ; clear alpha tek_clear db escape,'*dA',escape,'*dL',escape,'*d0,380O','$'; clear tek to_term_msg db 'Entering Firmware terminal ' db 'Press SHIFT STOP to return to Kermit','$' ;;;; Data for reading data comm configuration in firmware ;******************************************* ; e_cnp_rom_segment equ 0000h e_cnp_entry equ 045ch e_dhp_entry equ 0425h e_dhp_driver equ 042ah e_long_call equ 09ah ; e_port1_read equ 2 e_port2_read equ 4 e_port1_save equ 2 e_port2_save equ 11 e_port1 equ 1 ; values for the two physcial ports. e_port2 equ 2 e_true equ 1 e_false equ 0 ; ;************** LOCAL DECLARATIONS ************** ; ; CONFIGURATION_DATA_AREA struc predef_values db ? barrel_index db ? dc_port db ? dc_bool1 db ? dc_bool2 db ? dc_baud_rate db ? dc_parity db ? dc_clock db ? dc_asterisk db ? dc_recv_pace db ? dev_token dw ? CONFIGURATION_DATA_AREA ends dc_status_struc struc ; status for datacomm eightbit db 0 ; true if 8 bit, false if 7 bit transparent db 0 ; true if transparent, false if not transparent raw db 0 ; true if raw, false if cooked dc_status_struc ends ; scratch space. ; err_flag db 0 readid dw 0 saveid dw 0 work_config CONFIGURATION_DATA_AREA <> dc_status dc_status_struc ; ;************************************ ; ; Macros for absolute long calls. ; ;************************************ ; call_cnp_entry macro db e_long_call dw e_cnp_entry dw e_cnp_rom_segment endm call_dhp_entry macro db e_long_call dw e_dhp_entry dw e_cnp_rom_segment endm call_dhp_driver macro db e_long_call dw e_dhp_driver dw e_cnp_rom_segment endm baud_port equ 0ch ; port address of baud rate controller ; ; table to print out value of a nibble on the screen asciitab db '0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F' ; porta_baud db 0 ; stored baud codes portb_baud db 0 start_porta_baud db 0 start_portb_baud db 0 data ends code segment public 'code' extrn comnd:near, dopar:near, atoi:near, prompt:near extrn sleep:near,statc:near, srchkw:near extrn msuinit:near, keybd:near ; in msuhp1.asm extrn keybdopen:near, keybdclose:near ; in msuhp1.asm extrn getkey:near ; in msuhp1.asm extrn clearlabels:near, labelsoftkeys:near ; in msuhp1.asm extrn displaylogoffkey:near, displaylogonkey:near ; in msuhp1 extrn pntchr:near, pntflsh:near assume cs:code, ds:data, es:nothing ; Clear the input buffer before sending a packet. CLRBUF PROC NEAR cmp repflg,0 ; doing replay? je clrb0 ; e => no replay ret ; don't clear if replaying clrb0: push ax ; need to save for CROSHAIR in msggri cli mov ax,offset source mov bufin,ax mov bufout,ax mov count,0 sti clrb1: call prtchr ; get a character jnc clrb1 ; until there aren't any more nop pop ax ret CLRBUF ENDP ; Common routine to clear to end-of-line CLEARL PROC NEAR push ax push dx mov dx,offset clreol mov ah,prstr int dos pop dx pop ax ret CLEARL endp ; Set the baud rate for the current port, based on the value ; in the portinfo structure. Returns carry clear. BAUDST PROC NEAR mov dx,offset bdtab ; baud rate table, ascii xor bx,bx ; help is the table itself mov ah,cmkey ; get keyword call comnd jc baudst1 ; c = failure push bx ; save result mov ah,cmeol ; get confirmation call comnd pop bx jc baudst1 ; c = failure mov si,portval mov ax,[si].baud ; remember original value mov [si].baud,bx ; set the baud rate call dobaud ; use common code clc baudst1:ret BAUDST ENDP ; on entrance bx has baud rate from bdtab dobaud proc near ; updated by [jan] to set baud mov ax,portval cmp ax,offset port1 ; using port 1? jne dobaud1 ; ne => not using port 1 mov al,1 ; port 1 set mov ah,bl ; baud code call set_baud ; set the baud rate ret dobaud1:mov al,2 ; set port 2 baud mov ah,bl ; ah has baud code call set_baud ret dobaud endp ; Send the break signal out data comm sendbl: ; long break (same as regular h sendbr: mov al,e_send_break ; regular break call dc_ioctl clc ; clear carry bit (stay in Connect) ret ; Set some data comm ioctl option. AL has function code dc_ioctl proc near push ax ; save regs 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 dos pop dx ; restore regs pop cx pop bx pop ax ret dc_ioctl endp shomodem proc near mov ah,cmeol ; get a confirm call comnd jnc shomod00 ; nc => success ret ; get out if failure shomod00: 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 clc ret shomodem endp getmodem proc near mov al,0 ret getmodem 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 proc near push cx 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 ; restore registers pop dx pop cx clc ret outchr endp ; 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" or "COM2". opnprt proc near mov al,flags.comflg dec al ; flags.comflg is 1 for com1, 2 for com2 mov ah,0 push si mov si,ax shl si,1 ; double index mov dx,prttab[si] pop si mov ah,open2 mov al,2 int dos jnc opnpr2 mov ah,prstr ; it didn't like the string mov dx,offset erms41 int dos ret opnpr2: mov prthnd,ax ; Call succeeded call set_port_param ; set appropriate parameters call serini ; set appropriate parameters ret opnprt endp ; This routine blanks the screen. CMBLNK PROC NEAR ; This is stolen from the IBM example push ax push dx mov ah,prstr mov dx,offset blank int dos pop dx pop ax ret CMBLNK ENDP LOCATE PROC NEAR mov dx,0 ; Go to top left corner of screen jmp poscur ; Go and move the cursor LOCATE ENDP ; To get the baud, it is likely we would need to ; directly access the UART. Not implemented. GETBAUD PROC NEAR ret GETBAUD ENDP ; Carry set if no character available at the port. If carry clear, ; returns with char in al, # of chars in buffer in dx. PRTCHR PROC NEAR cmp repflg,0 ; doing replay? je prtch0 ; e=> not doing replay jmp getrepchr ; get replay character if in replay prtch0: push bx push cx push si cmp prthnd,0 ; have a handle yet? jne prtch1 ; yes, keep going call opnprt prtch1: cmp count,0 ; no characters? jne prtch2 ; no, go fill buffer mov bx,prthnd mov al,rdchan mov ah,ioctl mov dx,offset source ; buffer to read into mov cx,20 ; read 20 characters at a time ; More characters cause problems for ; early firmware versions int dos jc prtch4 ; c = error mov count,ax ; reset count mov keydelay, -1 ; read keyboard next go around mov dx,ax ; needed to obey rules 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 cld lodsb ; get character mov bufout,si ; update ptr prtch3: pop si pop cx pop bx clc ; clc if there is a character ret ; exit success prtch4: pop si pop cx pop bx stc ; set carry if no characters ret 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 or ah,ah ; don't send null if flow = none jz ihosts1 ; z = null call outchr ; send it (release Host's output queue) 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) ihostr1:pop cx pop bx pop ax ret IHOSTR ENDP DTRLOW PROC NEAR ; Global proc to Hangup the Phone by making mov ah,cmline ; 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 jnc dtrlow1 ; nc => success ret ; get out if failure dtrlow1:call serhng ; drop DTR and RTS writestring hngmsg ; tell user of success clc ; success ret 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. Implemented by [jan]. SERHNG PROC NEAR mov al,5 ; modem disconnect code call dc_ioctl clc ; stay in connect mode ret SERHNG ENDP ; Position the cursor according to contents of DX POSCUR PROC NEAR push ax ; save regs 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 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 ; save some regs push si push dx 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 cld 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 ; e = 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 pop si pop dx pop ax ret puthlp endp ; Perform a delete. DODEL PROC NEAR push ax push dx mov ah,prstr mov dx,offset delstr ; Erase character int dos pop dx pop ax ret DODEL ENDP ; Perform a Control-U. CTLU PROC NEAR push ax push dx mov ah,prstr mov dx,offset clrlin int dos pop dx pop ax ret CTLU ENDP COMS PROC NEAR mov dx,offset comptab ; comms port table mov bx,0 ; use keywords as help mov ah,cmkey ; parse keyword call comnd jnc coms1 ; nc => success ret ; get out if failure coms1: push bx mov ah,cmeol call comnd ; Get a confirm jc comx ; didn't get a confirm call serrst ; close existing port before opening pop bx ; the new one mov flags.comflg,bl ; Set the comm port flag cmp flags.comflg,1 ; Using Com 1? jne coms2 ; ne = no mov portval,offset port1 call serini ; initialize new port ret coms2: mov portval,offset port2 ; use Com2 call serini ; initialize port ret comx: pop bx ret COMS ENDP VTS PROC NEAR ; Set Term code mov dx, offset termtb mov bx,0 mov ah,cmkey call comnd jnc vts1 ; nc => success ret ; return if failure vts1: push bx mov ah,cmeol call comnd jnc vts2 ; nc=> success pop bx ret ; return if failure vts2: pop bx ; bl has number from termtb mov di,offset dc_status cmp bl,eightbitnum ; doing 8 bits? jne vts3 mov [di].eightbit,true call set_port_param ; set port parameters clc ret vts3: cmp bl,sevenbitnum ; doing 7 bits? jne vts4 ; ne => not 7 bits mov [di].eightbit,false call set_port_param ; set port parameters clc ret vts4: cmp bl,transonnum ; transparency on? jne vts5 mov [di].transparent,true call set_port_param ; set port parameters clc ret vts5: cmp bl,transoffnum ; transparency off? jne vts6 mov [di].transparent,false call set_port_param ; set port parameters clc ret vts6: cmp bl,rawonnum ; make port raw? jne vts7 mov [di].raw,true call set_port_param ; set port parameters clc ret vts7: cmp bl,rawoffnum ; cook the port? jne vts7a mov [di].raw,false call set_port_param ; set port parameters clc ret vts7a: cmp bl,tekonnum ; enable tek? jne vts7b ; ne => don't enable and denyflg,not tekxflg ; clear tekx bit mov tekbyte,bl ; for status display clc ret vts7b: cmp bl,tekoffnum ; disable tek jne vts8 ; ne => don't disable or denyflg,tekxflg ; set tek deny bit mov tekbyte,bl ; for status display clc ret vts8: cmp bl,ttgenrc ; hp150 emulation selected? jne vts9 mov flags.vtflg,bl ; set emulator type clc ret vts9: cmp bl,tttek ; tek emulation selected? jne vts10 mov flags.vtflg,bl vts10: clc ret ; success VTS ENDP VTSTAT PROC NEAR ; For Status display mov bx,offset vtstbl ; table of things to show jmp statc ; common status code 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 lclini proc near saveregs call read_baud ; use firmware to read baud rates mov lclexit,offset lclose ; routine to call when closing mov prtrdy,true ; port is ready mov flags.vtflg,0 ; no terminal emulation. [jrd] mov prthnd,0 ; no port handle yet. [jrd] call msuinit ; initialize keyboard module msugen call serini ; initialize port restoreregs ret lclini endp ; Wait for the # of milliseconds in ax, for non-IBM compatibles. ; Thanks to Bernie Eiben for this one. pcwait proc near mov cx, 180 ; hp150 has effective clock of only 3.6 MHz!!! 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 ; Initialization for using serial port. Returns normally. ; Attempts to put port device in binary mode. [jrd] SERINI PROC NEAR cld ; Do increments in string operations cmp prthnd,0 ; Got a handle yet? jne serin0 push bx call opnprt ; Else 'open' the port pop bx serin0: push bx mov bx,portval ; get port [jrd] 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 ret SERINI ENDP SERRST PROC NEAR push bx ; save reg push di mov bx,prthnd cmp bx,0 ; none there? je serrs6 ; no, don't try to close ; return the port to the orignal status mov bx, prthnd ; handle call cookedon ; cook the port first mov al, e_port1 ; assume port 1 mov bx, offset port1 cmp portval, bx ; are we using port 1? je serrs2 mov al, e_port2 ; using port 2 serrs2: call get_config_values ; read configuration di points to work_config mov al, 1 ; assume 7 bit mode test [di].dc_bool2, 2 ; if bit2 set => 7 bit jnz serrs3 ; nx => yes 7 bit mov al,2 ; 2 for 8 bit serrs3: call dc_ioctl ; update the number of bits mov al, 4 ; disable data comm transparency call dc_ioctl mov bx, prthnd ; port handle in bx for close mov ah,close int dos ; close handle mov prthnd,0 ; the port is now closed serrs6: pop di pop bx ret ; All done SERRST ENDP ; Generate a short beep. BEEP PROC NEAR mov dl,bell mov ah,conout 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 ; make es point to datas segment mov cx,size termarg cld rep movsb ; copy into our arg blk pop es ; recover reg mov ax,ourarg.captr ;;; mov captrtn,ax ; buffer capture routine call pntflsh ; flush printer buffer mov keydelay,0 ; initizize keyboard counter [jan] mov parmsk,0ffh ; parity mask, assume parity = None call keybdopen ; turn on keycode mode call labelsoftkeys call displaylogkey ; decide whehter to display logging softkey cmp flags.vtflg,tttek ; in tektronix emulation? jne term0 ; ne=> doing alpha call tekini ; initialize emulator term0: mov parmsk,0ffh ; 8 bit parity by default cmp ourarg.parity,parnon ; is parity None? je term1 ; e = yes, keep all 8 bits mov parmsk,07fh ; else keep lower 7 bits term1: cmp prtrdy,false ; ready to read port? jne term2 ; ne = yes mov kbdflg,'C' ; so we exit connect mode mov prtrdy,true ; get ready for next connect jmp term5 ; get out term2: call portchr ; get char from port, mask parity jnc short term4 ; nc = no char, go on call stringchek ; check the string for escape sequence jnc short term4 ; nc => no key to show term3: call outtty ; display and capture char term4: inc keydelay ; increment counter mov ah,keydelay ; move into ah and ah,15 ; clear high bits and read keyboard jne term1 ; once each 16 reads of serial port call keybd ; call keyboard translator in msu jnc term1 ; nc = no char or have processed it term5: ; carry set = quit Connect mode call pntflsh ; flush printer buffer call clearlabels ; blank softkey labels call keybdclose ; turn off keycode mode writestring alpha_disp ; make sure we are in alpha upon exit writestring alpha_on ; turn on alpha writestring tek_off ; turn off tek call test_baud_change ; check for baud change call cptdmp ; empty the capture buffer 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: cmp logflag,true ; are we logging? jne outnoc ; ne => no, forget logging push ax ; save char call captrtn ; give it captured character pop ax ; restore character and keep going outnoc: test anspflg,prtscr ; should we be printing? jz outnop ; no, keep going call pntchr ; queue char for printer 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 dl,al ; write without intervention mov ah,6 ; direct console i/o 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 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? jnc portc1 ; nc = yes there is a character portc0: clc ; no carry -> no character ret ; and return portc1: and al,parmsk ; apply 8/7 bit parity mask 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 proc near cmp repflg,0 ; in replay mode? je chrout1 ; e=> not doing replay jmp repchrout ; display the replay character chrout1:call outprt ; put char in al to serial port clc ; stay in Connect mode ret chrout endp trnprs: push ax ; toggle Copy screen to printer test anspflg,prtscr ; should we be 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,prnhand ; 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 short trnpr3 ; and ignore request trnpr2: xor anspflg,prtscr ; toggle print flag trnpr3: pop ax clc ret displaylogkey proc near ; display logging softkey? test flags.capflg, logses ; session logging enables? jz displaylogkey3 ; z= no, forget it cmp logflag, true ; are we logging? jne displaylogkey1 ; ne => not logging call displaylogoffkey ; off key if capturing jmp displaylogkey2 ; make a good exit displaylogkey1: call displaylogonkey ; show log on function key displaylogkey2: clc ret displaylogkey3: mov logflag, false ; not logging clc ret displaylogkey endp klogtog proc near ; toggle session logging key test flags.capflg, logses ; session logging enables? jz klogtogn ; z= no, forget it cmp logflag, true ; are we capturing? jne klogtog1 ; ne => not logging mov logflag, false ; turn off loggin push bx mov bx, argadr and [bx].flgs, not capt ; tell kermit we are stopping capture and ourarg.flgs, not capt ; turn off local capture flag pop bx ; restore the register call displaylogkey ; turn on appropriate log key call cptdmp ; dump the capture buffer to file jmp klogtog2 klogtog1: mov logflag, true ; turn on logging push bx mov bx, argadr or [bx].flgs, capt ; tell kermit we are resuming capture or ourarg.flgs, capt ; turn on local capture flag pop bx ; restore the register call displaylogkey ; turn on log off key klogtog2: clc ret klogtogn: mov logflag, false ; not logging so turn off flag clc ret klogtog endp snull: mov ah,0 ; send a null call outchr ; send without echo or logging 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 ;; end of action routines ; set comm port parameters based on dc_status structure set_port_param proc near push di cmp prthnd,0 ; got a handle yet jne set_port_param1 ; ne = yes call opnprt jmp set_port_param5 ; opnprt calls this so don't repeat set_port_param1: mov di,offset dc_status cmp [di].eightbit,true ; doing 8 bit? je set_port_param2 ; e=> yes, doing 8 7 bit mov eightflg,sevenbitnum ; so status knows we have seven bits mov al,1 ; dc_ioctl code for 7 bit call dc_ioctl jmp set_port_param2a ; check transparent set_port_param2: mov eightflg,eightbitnum ; so status knows we have eight bits mov al,2 ; code for 8 bit call dc_ioctl set_port_param2a: cmp [di].transparent,true ; in transparency mode? je set_port_param3 ; e=> yes mov transparentflg,transoffnum ; so status knows transparency off mov al,4 ; code to disable transparency call dc_ioctl jmp set_port_param3a ; check raw/cooked situation set_port_param3: mov transparentflg,transonnum ; so status knows transparency on mov al,3 ; code to enable transparency call dc_ioctl set_port_param3a: cmp [di].raw,true ; raw mode set? je set_port_param4 ; e => raw on mov rawflg,rawoffnum ; so status knows we're cooked mov bx,prthnd ; cooked on needs port handle call cookedon jmp set_port_param5 ; done set_port_param4: mov rawflg,rawonnum ; tell status port is raw mov bx,prthnd ; port handle for raw on call rawon set_port_param5: pop di clc ret set_port_param endp ;check string to see if we need to do something special stringchek proc near cmp stringchekcnt,0 ; nobody in yet? jne stringchek1 ; ne => already have characters cmp al,escape ; is this escape? je stringchek1 ; it is escape, so go and process cmp al,escape+80h ; in case parity is odd je stringchek1 ; process escape stc ; display the character ret ; return quickly if nothing to do stringchek1: ; here is escape already in saveregs and al,07fh ;strip high bit mov bx,stringchekcnt mov stringchekbuff[bx],al ;put character in buffer inc stringchekcnt ;one more character in buffer call stringtest ; does the string in stringchekbuff match? cmp match,0 ; 0 means no match je stringchek2 mov si,match ; here means we have a match shl si,1 ; multiply by 2 dec si dec si ; 1=0, 2=1 etc call disptab[si] ; call appropriate function call stringbuffplay ; play back the buffer clc ; don't display jmp stringchek3 ; return and don't display character stringchek2: clc ; don not display cmp matchsofar,true ; do we have a match so far je stringchek3 ; e=true , get out mov playem,true call stringbuffplay ; clean out the buffer clc ; don't display character stringchek3: restoreregs ret stringchek endp ;test to see if input string is a match to toggle terminal [jan] ; stringtab gives addresses of 0 terminated strings ; teststring in stringchekbuff ; numstrings is the number to checked ; matchsofar will have be true if there is a possilbe match ; match will be non-zero 1, 2, 3 indicating number of match if a match ; if no match yet, match will be 0 ; severaal registers get destroyed stringtest proc near mov matchsofar,false ; assume no match mov match,0 ; no match xor si,si ; pointer to string tab dec si dec si ; step back 1 item mov cx,0 ; cx points to number of string strtst1: inc cx ; strings number cmp cx,numstrings ; done parsing table? ja strtst5 ; we're done, get out of here mov di,offset stringchekbuff inc si inc si ; point to next item mov bx,stringtab[si] ; offset of string strtst2: mov al,[di] ; stringchekbuff in al mov ah,[bx] ; string element to test in ah cmp al,0 ; end of stringchekbuff jne strtst2a ; ne=> not at end of buffer mov matchsofar,true ; we have a match so far jmp strtst5 ; return to caller strtst2a: cmp ah,0 ; at end of string? je strtst1 ; failure, go to next string cmp ah,al ; match? jne strtst1 ; no match, on to next string ; here if match mov ah,[bx+1] ; next byte from string cmp ah,0 ; are we done with string? je strtst3 ; e => yes, a match inc bx ; next element in string inc di ; next character in stringchekbuff jmp strtst2 ; check next item in string strtst3: ; here if we have a match mov match,cx mov matchsofar,true strtst5:ret stringtest endp ;play back characters in string buffer ..called by stringchek stringbuffplay proc near xor bx,bx mov cx,stringchekcnt stringbuffplay1: mov al,stringchekbuff[bx] cmp playem,true ; playback characters? jne stringbuffplay2 ; ne = no don't play back push bx ; save index push cx ; save count call outtty ; print the character pop cx ; restore count pop bx ; restore index stringbuffplay2: mov stringchekbuff[bx],0 ; set to 0 inc bx ; point to next character loop stringbuffplay1 ; repeat until buffer is empty mov stringchekcnt,0 ; now no characters in buffer ret stringbuffplay endp ignoretek proc near ; ignore this escape sequence in tek mode mov playem,false cmp flags.vtflg,tttek ; are in in tek emulation je ignoretek1 ; e=yes do not play back mov playem,true ignoretek1:ret ignoretek endp ignoreall proc near ; always ignore this escape sequence mov playem,false call beep ; let user know of illegal sequence ret ignoreall endp totekplay proc near ; turn on tektronix mov playem,true ; play back characters jmp totek totekplay endp toteknoplay proc near mov playem,false jmp totek toteknoplay endp totek proc near ; turn on tektronix test denyflg,tekxflg ; tek auto entry enabled? jz totek1 mov playem,true ; play back characters ret totek1: cmp flags.vtflg,tttek ; already doing tek je totek2 call termtog ; toggle to tektronix totek2: ret totek endp leavetek proc near ; turn off tektronix mov playem,false ; don't play back characters test denyflg,tekxflg ; tek auto entry/exit enabled? jz leavetek1 mov playem,true ; play back characters ret leavetek1: cmp flags.vtflg,tttek ; already doing tek jne leavetek2 ; ne => doing alpha so ignore call termtog ; toggle to alpha leavetek2:ret leavetek endp getrepchr proc near ; get replay character for file mov ah,readf2 ; read from replay file mov bx,diskio.handle mov cx,1 ; read 1 character mov dx,offset rdbuf ; to this buffer int dos jc getrepchr1 ; c => failure cmp ax,cx ; read the byte? jne getrepchr1 mov al,rdbuf ; al has character clc ; character available in al ret getrepchr1: call beep ; announce file is done call beep call waitkey ; wait for a key to be pressed mov prtrdy,false ; so we exit connect mode stc ret ; no character available getrepchr endp repchrout proc near ; process key in al while replaying and al,7fh ; strip parity repchrout1: cmp al,'C'-40h ; Control C?(to exit playback mode) je repchrout3 ; e=> yes, return failure cmp al,XOFF ; user wants to stop? jne repchrout2 ; ne => ok to continue call waitkey ; wait and get a key jmp repchrout1 ; now process this key repchrout2: clc ; return success ret repchrout3: mov prtrdy,false ; exit terminal stc ; exit connect mode ret repchrout endp termtog proc near ; toggle terminal type [jan] cmp flags.vtflg,tttek ; doing tek emulation ? jne termtog1 ; ne means doing tek writestring tek_off ; turn off tek writestring alpha_disp ; turn on alpha writestring alpha_on ; and turn on the alpha mov flags.vtflg,ttgenrc ; turn on alpha display clc ret termtog1:mov flags.vtflg,tttek ; turn on tek display writestring alpha_off ; turn off alpha writestring tek_disp writestring tek_on ; and turn on the tek clc ; do not exit Connect mode ret ; stay in connect mode termtog endp kclrscn proc near ; clear the screen cmp flags.vtflg,tttek ; doing tek emulation je kclrscn1 ; e=> yes writestring alpha_clear ; clear the alpha clc ; stay in connect mode ret ; return to caller kclrscn1:writestring tek_clear ; clear the tektronix clc ; stay in connect mode ret kclrscn endp waitkey proc near ; wait for a key to be pressed waitkey0:call getkey ; get a key; carry set => no key; code in ax jc waitkey0 ; repeat until its pressed ret waitkey endp tekini proc near ; initialize tek emulator writestring alpha_off writestring tek_disp ; enable tektronix writestring tek_on ; turn on tek ret tekini endp toterminal proc near ; go to firmware terminal mode cmp dosnum,dos211 ; dos 2.11 or above? jae toterminal1 ; ae=> ok to go to terminal mov ah,2 mov dl,7 int dos ; ring the bell clc ; stay in connect mode ret toterminal1: call clearlabels ; blank softkey labels call keybdclose ; get out of keycode writestring to_term_msg mov ax,1750 call pcwait ; 1 3/4 second time to read message mov bx,offset agiosbuff mov word ptr [bx],26 ; function code to get into terminal mov ax,4403h ; io control write mov bx,1 ; console handle mov cx,2 ; 2 bytes in buffer mov dx,offset agiosbuff int dos ; now in terminal mode call labelsoftkeys ; turn keys on when we return call keybdopen ; back to keycode mode clc ; stay in connect mode ret ; back to terminal toterminal endp cookedon proc near ; cook handle in bx push ax push dx ; save registers push bx ; save handle mov ax,4400h ; get device information int dos xor dh,dh ; clear high byte and dl,0dfh ; clear raw bit without changing other bits mov ax,4401h ; put device information pop bx ; restore handle int dos ; turn off raw mode pop dx ; restore registers pop ax clc ; always returns success ret cookedon endp rawon proc near push ax push dx ; save registers push bx ; save handle mov ax,4400h ; get device information int dos xor dh,dh ; clear high byte or dl,20h ; set raw bit mov ax,4401h ; put device information pop bx ; restore handle int dos ; turn on raw mode pop dx pop ax ; restore registers clc ; always returns success ret rawon endp ;;;cptchr and cptdmp taken from msster to fix the problem ; of com buffer overflow with logging the session cptchr proc near ; session capture routine, char in al push di mov di,capbp ; buffer pointer mov byte ptr [di],al inc capbp pop di dec caplft ; decrement chars remaining jg cptch1 ; more room, forget this part call cptdmp ; dump the info cptch1: ret cptchr endp cptdmp proc near ; empty the capture buffer push ax push bx push cx push dx mov bx,sloghnd ; get file handle cmp bx,0 ; is file open? jle cptdm1 ; le = no, skip it push bx ; save handle mov bx,portval ; doing flow control? cmp [bx].floflg,0 ; e = no je cptdmp01 cmp xofsnt,true ; have we sent xoff? je cptdmp01 ; don't send it again mov ah,flowoff ; get the xoff or ah,ah ; null (no flow control?) jz cptdmp01 call outchr ; send xoff to port mov xofsnt,true ; remember we've sent it cptdmp01:pop bx ; restore handle mov cx,cptsiz ; original buffer size sub cx,caplft ; minus number remaining jl cptdm2 ; means error jcxz cptdm1 ; z = nothing to do mov dx,offset capbuf ; the capture routine buffer mov ah,write2 ; write with filehandle int dos ; write out the block jc cptdm2 ; carry set means error mov capbp,offset capbuf mov caplft,cptsiz ; init buffer ptr & chrs left jmp short cptdm1 cptdm2: and flags.capflg,not logses ; so please stop capturing ; and targ.flgs,not capt ; so please stop capturing and ourarg.flgs, not capt ; so please stop capturing mov dx,offset capterr ; tell user the bad news mov ah,prstr int dos cptdm1: cmp xofsnt, true ; xoff sent jne cptdm02 mov ah,flowon ; get the xon or ah,ah ; null? jz cptdm02 call outchr ; send xon mov xofsnt,false ; remember we've sent it cptdm02:pop dx pop cx pop bx pop ax ret cptdmp endp test_baud_change proc near ; check if firmware baud changed mov al,e_port1 call get_config_values mov al,[di].dc_baud_rate cmp al,start_porta_baud ; baud rate changed by firmware (via user) je test_baud_change1 ; e = not changed call read_bauda ; redo port a baud test_baud_change1: mov al,e_port2 ; check if port 2 changed call get_config_values mov al,[di].dc_baud_rate cmp al,start_portb_baud je test_baud_change2 ; e = not changed call read_baudb ; read port b baud test_baud_change2: ret test_baud_change endp read_baud proc near call read_bauda ; read port 1 baud call read_baudb ; read port 2 baud ret read_baud endp read_bauda proc near ; read baud on port 1 and update port info mov al,e_port1 call get_config_values ; get port 1 configuration mov si,offset port1 mov di,offset work_config mov bl,[di].dc_baud_rate ; baud rate into bl mov start_porta_baud,bl ; remember startup baud mov portb_baud,bl ; remember startup baud mov di,offset ourbdtab ; translate hp baud into kermit code shl bl,1 ; multiply by 2 for 2 bytes per entry xor bh,bh mov bl,[di+bx+1] mov [si].baud,bx ; write baud in port 1 info ret read_bauda endp ; Read the port 2 status read_baudb proc near mov al,e_port2 call get_config_values ; get port 2 configuration mov si,offset port2 mov di,offset work_config mov bl,[di].dc_baud_rate ; baud rate into bl mov start_portb_baud,bl ; remember startup baud mov portb_baud,bl ; current baud on port b mov di,offset ourbdtab ; translate hp baud into kermit code shl bl,1 ; multiply by 2 since 2 bytes per entry xor bh,bh mov bl,[di+bx+1] mov [si].baud,bx ; write baud in port 2 info ret read_baudb endp ;;; read data comm configuration. taken off dc.asm from compuserve ;******************************************* ; ; Firmware Programming Notes: ; ; 1) The firmware has a modular structure and generally consists ; of a bunch of processing modules which all have a separate ; logical segment and a limited number of entry points ; (generally only one). ; 2) The desired processing is accessed by passing the required ; parameters and the proper function code on entry to a ; module. ; 3) A call to a procedure outside the logical module is always ; a long call and inter segment (logical segment). ; 4) Parameters for a call to a procedure outside the logical ; module are pushed on the stack. This includes the function ; code. The procedure called has the responsibility of ; cleaning up the stack. ; 5) The procedure called should always return status in AX. ; Registers BX, CX, and DX may also contain outputs. ; 6) The caller should always assume registers AX, BX, CX, and ; DX have been modified. The caller should always assume ; registers SI, DI, SP, BP, DS, ES, and SS are the same on ; return. ; 7) Calls to external procedures are made through jump tables ; at the beginning of each rom. Thus the application is ; insulated from re-releases of the HP150 firmware. ; ;******************************************* page; ;*************** GRYPHON DECLARATIONS ************ ; To simplify external linking to absolute firmware jump locations, ; we include the long calls as constants. Note that we still have ; some measure of ROM independence because we entry the routines ; through fixed jump tables at the start of the RAM. ; ;------------------------------------------- ; ; COMMENTS: ; 1) The bytes PREDEF_VALUES and BARREL_INDEX are used by ; configuration processing during normal operation where a ; configuration form is brought onto the screen. Their ; values can be set and then ignored. ; 2) The bytes DC_PORT through DC_RECV_PACE are the actual ; datacomm configuration values. ; 3) The word DC_DEVICE_TOKEN is used to access the datacomm ; device. ; ;------------------------------------------- ;******************************************* ; ; The data format for the datacomm configuration values are as ; follows: ; ; 1) DC_PORT= 2 (port 1) ; 11 (port 2) ; ; 2) DC_BOOL1 (a graphical representation follows) ; 3) DC_BOOL2 ; ; HP Point-to-Point Boolean Bit Positions ; ; 7 6 5 4 3 2 1 0 ; +-------+-------+-------+-------+-------+-------+-------+-------+ ; | 1 Stop| CS(CB)| SRR | RR(CF)| SRR | SR(CH)| Chk | ENQ | ; | Bit | Xmit | Invert| Recv | Xmit | | Parity| ACK | ; +-------+-------+-------+-------+-------+-------+-------+-------+ ; | TR(CD)| DM(CC)| | | | | 7 Data| Xmit | ; | | Xmit | | | | | Bits | Pace | ; +-------+-------+-------+-------+-------+-------+-------+-------+ ; ; DC_BOOL1: ; ; Bit 0: 0 = No 1 = Yes ; Bit 1: 0 = No 1 = Yes ; Bit 2: 0 = Lo 1 = Hi ; Bit 3: 0 = No 1 = Yes ; Bit 4: 0 = No 1 = Yes ; Bit 5: 0 = No 1 = Yes ; Bit 6: 0 = No 1 = Yes ; Bit 7: 0 = 2 Stop Bits 1 = 1 Stop Bit ; ; DC_BOOL2: ; ; Bit 0: 0 = None 1 = Xon/Xoff ; Bit 1: 0 = 8 Data Bits 1 = 7 Data Bits ; Bit 6: 0 = No 1 = Yes ; Bit 7: 0 = Lo 1 = Hi ; ; 4) DC_BAUD_RATE = 02H (110 Baud) ; 04H (150 Baud) ; 05H (300 Baud) ; 06H (600 Baud) ; 07H (1200 Baud) ; 0AH (2400 Baud) ; 0CH (4800 Baud) ; 0EH (9600 Baud) ; 0FH (19200 Baud) ; ; 5) DC_PARITY = 0 (Zeros) ; 1 (Ones) ; 2 (Even) ; 3 (Odd) ; 4 (None) ; ; 6) DC_CLOCK = 0 (INT CLOCK) ; 1 (EXT X1 CLOCK) ; 2 (EXT X16 CLOCK) ; ; 7) DC_ASTERISK = 0 (No Asterisk) ; 1 (DM Asterisk) ; 2 (RR Asterisk) ; 3 (Line Asterisk) ; 4 (CS Asterisk) ; ; 8) DC_RECV_PACE = 0 (No Recv Pace) ; 1 (Xon/Xoff Recv Pace) ; 2 (TR(CD) Recv Pace) ; ;******************************************* ; ; ;------------------------------------------- ; ; PROCEDURE NAME: GET_CONFIG_VALUES ; ; FUNCTION: ; 1) Specify a block of configuration parameters to be obtained ; by config processing. The parameters define how datacomm ; is configured. ; 2) Config processing will get the data out of NVRAM. The ; values reflect the current configuration of the 150. ; 3) The data is written into the data area supplied by the ; caller and is in the format used by the datacomm driver. ; ; INPUTS: ; 1) DS - segment of CONFIGURATION_DATA_AREA ; 2) DI - offset of CONFIGURATION_DATA_AREA ; ; OUTPUTS: ; The configuration data area will have all the necessary ; values needed to specify the datacomm configuration. These ; can be modified so when they are passed to the datacomm ; driver, the new configuration will take effect. ; ; REGISTERS MODIFIED: ax, bx, cx, dx ; ;------------------------------------------- GET_CONFIG_VALUES proc near mov readid,e_port1_read mov saveid,e_port1_save cmp al,e_port1 je init90 mov readid,e_port2_read mov saveid,e_port2_save init90: mov di,offset work_config ;---------------------------------------- ; Initialize the variables of the config data area required ; by config processing. ;---------------------------------------- mov [di].PREDEF_VALUES,3 mov [di].BARREL_INDEX,6 mov ax,readid mov [di].DC_PORT,al ;---------------------------------------- ; Get the datacomm configuration values. ;---------------------------------------- mov ah,al ; Port X config type in AH mov al,4 ; full duplex, hardwired form. push ax mov ax,0201h ; 01 -> Personality ID push ax ; C02 -> Config values are required. push ds ; segment of CONFIGURATION_DATA_AREA push di ; pointer to start of data area lea ax,[di].DC_PORT ; pointer to start of config values push ax mov ax,3 ; function code for CNP_GET_DEV_CONFIG push ax CALL_CNP_ENTRY mov ax,saveid mov [di].dc_port,al ret GET_CONFIG_VALUES endp ; Set baud port (1 or 2) in al, Kermit baud code from bdtab in ah. ; First translate Kermit baud into HP baud set_baud proc near mov dx,ax ; save baud and port mov di,offset ourbdtab1 mov bl,ah ; put baud code in bl xor bh,bh ; bh=0 for indexing shl bl,1 ; x2 since two bytes per baud entry mov al,[di+bx+1] ; al now has hp baud code cmp dl,1 ; is it port 1? je set_baud1 ; e = yes mov portb_baud,al ; save it mov cl,4 shl al,cl ; port b in left nibble or al,porta_baud ; port a baud in right nibble out baud_port,al ; write the port a and port b baud clc ; success ret set_baud1: ; set port 1 baud mov porta_baud,al ; save the baud mov dl,portb_baud mov cl,4 shl dl,cl or al,dl ; port a in right nibble , port b in left nibble out 0ch,al ; write the port a and port b baud clc ; success ret set_baud endp lclose proc near ; this gets called when kermit quits mov al,e_port1 ; reset baud to match firmware values call get_config_values mov al,[di].dc_baud_rate ; port a baud rate push ax ; save this baud mov al,e_port2 call get_config_values mov bl,[di].dc_baud_rate ; port 2 baud rate mov cl,4 shl bl,cl ; port b baud in left nibble pop ax ; al has port a baud or al,bl ; both bauds in al out baud_port,al ; write the baud rate ret lclose endp code ends end