NAME msx55x ; File MSX55X.ASM ; Kermit system dependent module for Sanyo MBC-55x with video board ; Edit History ; Edit MSXIBM.ASM version 2.29 to make Sanyo version 8 July 1986 [rwb] ; Remove module VTS since mssset now selects terminal emulation type. ; Add Topview support for some screen handling functions and call smarter ; screen routines in module msyibm. ; - Bob Babcock ; ; Revise Putmod to not advance cursor to last column to avoid unwanted ; cursor wraparound on some machines (Compaq). ; Add DOS keyboard reading if running under IBM PC Netbios (pcnet != 0). ; Move all terminal Set and Status routines to this system dependent file. ; Add Global entry point vtstat to invoke local Status display. ; Remove Autowrap (H-19) as a separate item; a terminals now use Wrap. ; Add Set Term Color for terminal emulation; as a default the system uses ; colors in existence when Kermit is started. [jrd] ; Add extra code to SERINI & SERRST to assert 8250 Uart signals OUT1 and OUT2. ; Normally OUT2 is used to enable recoginition of IRQ3/4 and OUT1 is unused. ; Add code at end of SERRST to clear modem's delta line status bits and ; to reassert DTR, RTS, and OUT1/2. ; Add control of screen refresh as Set Term Color 0 for regular IBM CGA, ; waits for retrace before updating screen, and Set Color 10 for other systems ; not needing to wait. Default is to wait (no snow). ; 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 (and worker serhng) to drop DTR and RTS and ; thus hangup the phone. 29 March 1986 [jrd] ; Revise Set Term Tab ... to use codes of set/clear/not-modified in tmptab ; buffer and hence set/clear individual tabs cleanly. 1 April 1986 ; 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] ; Add save reg si in proc puthlp to help avoid lost cursor. ; Add test for IBM PC jr and if machine is a PC jr then set port 2 as the ; default. 23 April 1986 [jrd] ; Revise Puthlp procedure to use manual cursor movement while writing help ; text. Hope is to avoid screen problems on Compaq's. 1 May 1986 [jrd] ; Revise Poscur to not do Topview notification. Should cure video controller ; problems on early IBM/Compaq PC's. 5 May 1986 [jrd] ; ; [2.28 jrd/2] ; Modified procedure serini to flush input char before allowing interrupts, ; to stop interrupts from occurring during the procedure body, to stop ; interrupts from occurring due to TX holding buffer becoming empty, and to ; speed our exit from the procedure before an interrupt can occur. ; Modified procedure serrst to do quicker exit before interrupts occur. ; Modified procedure serint to remove unnecessary start-interrupts in proc ; body (it's an interrupt routine folks) and send 8259 end-of-interrupt ; code just before exiting procedure (less exposure time). [jrd] ; Joe R. Doupnik 22 Dec 1985. ; Make keywords mixed case for reading ease. 26 Dec 85 [jrd] ; ; Make break be 275 ms, DT 5:51pm Thursday, 6 December 1984 public serini, serrst, clrbuf, outchr, coms, vts, vtstat public dodel, ctlu, cmblnk, locate, prtchr, dobaud, clearl public dodisk, getbaud, beep public count, xofsnt, puthlp, putmod, clrmod, poscur public sendbr, machnam, setktab, setkhlp, lclini, showkey public ihosts, ihostr, dtrlow ; [jrd] include mssdef.h false equ 0 true equ 1 mntrgh equ bufsiz*3/4 ; High point = 3/4 of buffer full. ; constants used by serial port handler MCONF EQU 11H ; Machine configuration. KEYB EQU 16H BIOS EQU 10H ; 8251A serial communications device BUF8251 EQU 028h ; I/O address of 8251 in/out buffer CMD8251 EQU 02Ah ; I/O address of 8251A command buffer STS8251 EQU 02Ah ; I/O address of 8251A status buffer VEC8251 EQU 03E8h ; 8251A interrupt vector location INT8251 EQU 0FBh ; 8259A interrupt enable mask (int 2) ; 8251A Command instruction formats TxEN EQU 1 ; transmit enable DTR EQU 2 ; data terminal ready RxEN EQU 4 ; receiver enable SBRK EQU 8 ; send break ER EQU 10h ; error reset RTS EQU 20h ; request to send IR EQU 40h ; internal reset ; 8251A Status read formats TxRDY EQU 1 ; transmitter ready RxRDY EQU 2 ; receiver ready TxEMPTY EQU 4 ; transmit buffer empty PE EQU 8 ; parity error OE EQU 10h ; overrun error FE EQU 20h ; framing error BRKDET EQU 40h ; break detect DSR EQU 80h ; data set ready ; 8253 timer device CKA8253 EQU 20h ; I/O address of counter #0 CKB8253 EQU 22h ; I/O address of counter #1 CKC8253 EQU 24h ; I/O address of counter #2 CKD8253 EQU 26h ; I/O address of counter #3 ; 8259A interrupt controller CMA8259 EQU 0 ; I/O address of command buff 1 CMB8259 EQU 2 ; I/O address of command buff 2 ; 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 (only port1) [rwb] ; port1 - portinfo structures for the port ; global variables defined in this module: ; xofsnt, xofrcv - tell whether we saw or sent an xoff. ; setktab - keyword table for redefining keys (should contain a 0 if ; not implemented) ; setkhlp - help for setktab. datas segment public 'datas' extrn drives:byte,flags:byte, trans:byte extrn portval:word, port1:byte, port2:byte extrn pcnet:byte, refresh:byte extrn vtemu:byte ; [jrd] ; structure for status information table sttab. stent struc sttyp dw ? ; type (actually routine to call) msg dw ? ; message to print val2 dw ? ; needed value: another message, or tbl addr tstcel dw ? ; address of cell to test, in data segment basval dw 0 ; base value, if non-zero stent ends setktab db 12 mkeyw 'BackSpace',0eh mkeyw 'F1',3bh mkeyw 'F2',3ch mkeyw 'F3',3dh mkeyw 'F4',3eh mkeyw 'F5',3fh mkeyw 'F6',40h mkeyw 'F7',41h mkeyw 'F8',42h mkeyw 'F9',43h mkeyw 'F10',44h mkeyw 'scan',-1 setkhlp db cr,lf,'Keyname: "BackSpace", F1, ... F10, or "scan" follwed by ' db 'decimal scan code$' 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] erms20 db cr,lf,'?Warning: System has no disk drives$' ; [21a] erms40 db cr,lf,'?Warning: Unrecognized baud rate$' badbd db cr,lf,'Unimplemented baud rate$' prterr db '?Unrecognized value$' ; [jrd] machnam db 'Sanyo 55x with video board$' crlf db cr,lf,'$' delstr db BS,BS,' ',BS,BS,'$' ; Delete string. [21d] clrlin db cr,'$' ; Clear line (just the cr part). onmsg db 'on$' ; [jrd] offmsg db 'off$' savsci dw ? ; Save for serial port interrupt vector. [14] savscs dw ? ; Ditto. [14] savbr1 dw ? ; "Break" interrupt vector. [25] savbr2 dw ? ; Ditto. [25] portin db 0 ; Has comm port been initialized. [21c] xofsnt db 0 ; Say if we sent an XOFF. xofrcv db 0 ; Say if we received an XOFF. tmp db ?,'$' temp dw 0 temp1 dw ? ; Temporary storage. temp2 dw ? ; Temporary storage. rdbuf db 80 dup (?) ; temporary storage. [jrd] ; begin Terminal emulator data set termtb db tttypes ; entries for Status, not Set mkeyw 'Heath-19',ttheath mkeyw 'none',ttgenrc mkeyw 'VT102',ttvt100 mkeyw 'VT52',ttvt52 ; [jrd] vttbl db 13 ; fourteen entries. mkeyw 'Character-set',chaval mkeyw 'Color',200H ; screen fore/back colors; 200H=marker mkeyw 'Cursor-style',curval mkeyw 'Heath-19',ttheath+100H ; note 100H flag for decoding here mkeyw 'Keyclick',keyval mkeyw 'Margin-bell',marval mkeyw 'None',ttgenrc+100H mkeyw 'Newline',newval mkeyw 'Screen-background',scrval mkeyw 'Tabstops',tabval mkeyw 'VT102',ttvt100+100H mkeyw 'VT52',ttvt52+100H ; [jrd] mkeyw 'Wrap',wraval scrtab db 02H ; screen attributes mkeyw 'normal',00H mkeyw 'reverse',01H curtab db 02H ; cursor attributes mkeyw 'block',00H mkeyw 'underline',01H chatab db 02H ; character set (pound sign choice) mkeyw 'UK-ascii',01H mkeyw 'US-ascii',00H ; US ASCII is default (0). tabtab db 02H ; label says it all! mkeyw 'at',0FFH ; For setting tab stops. mkeyw 'Clear',00H ; For clearing tab stops. alltab db 02H ; more tab command decoding mkeyw 'all',00H mkeyw 'at',01H vtable dw ontab, curtab, chatab, ontab, ontab, ontab, scrtab, 0 vtsflg equ this byte ; define small digits xxxval newval equ $-vtsflg ; and mask for bit in byte db vsnewline curval equ $-vtsflg db vscursor chaval equ $-vtsflg db vsshift3 keyval equ $-vtsflg db vskeyclick wraval equ $-vtsflg db vswrap marval equ $-vtsflg db vsmarginbell scrval equ $-vtsflg db vsscreen numflgs equ $-vtsflg tabval equ $-vtsflg db 0 vtrtns dw numflgs dup (flgset), tabset ; dispatch table for vtsflg clrset db ? ; Temp for SET Term Tabstops xxx tmptabs db 80D dup (?) ; Temporary for unconfirmed tabs. vthlp db ' one of the following:',cr,lf db ' terminal types of: None, Heath-19, VT52, or VT102',cr,lf db ' Newline-mode Cursor-style Character-set (US UK)',cr,lf db ' Keyclick Margin-bell Screen-background',cr,lf db ' Tabstops Wrap (long lines) Color (fore & background)' db '$' wrpst db 'Autowrap (Heath-19): $' clrhlp db ' one of the following:' db cr,lf,' AT #s (to set tabs at column #s)' db cr,lf,' Clear AT #s or Clear ALL (to clear tabstops)' db cr,lf,' Ex: Set Term Tab at 10, 20, 34 sets tabs' db cr,lf,' Ex: Set Term Tab Clear at 9, 17, 65 clears tabs$' allhlp db ' one of the following:' db cr,lf,' AT #s (to clear at specific columns)' db cr,lf,' ALL (to clear all tabstops)$' tbshlp db ' column number of tab stop to set, 1-79$' tbchlp db ' column number of tab stop to clear, 1-79$' tbserr db cr,lf,'?Column number is not in range 1-79$' colhlp db cr,lf,' Set Term Color value, value, value, ...' db ' commas are optional.' db cr,lf,' 0 selects normal white on black and' db ' no-snow mode on an IBM CGA (default).' db cr,lf,' 1 for high intensity foreground.' db cr,lf,' 10 for fast screen updating.' db cr,lf,' Foreground color (30-37) = 30 + colors' db cr,lf,' Background color (40-47) = 40 + colors' db cr,lf,' where colors are 1 = red, 2 = green, 4 = blue.' db cr,lf,' Ex: 0, 1, 34, 47 IBM CGA(0), bright(1) blue(34)' db ' chars on a white(47) field.' db cr,lf,' Attributes are applied in order of appearance.$' colerr db cr,lf,'?Value not in range of 0, 1, 10, 30-37, or 40-47$' vtwrap db 'Term wrap-lines: $' ; 1st item has two spaces from STAT0 vtbell db 'Term margin-bell: $' ; this is also on same line as wrap. vtnewln db ' Term newline: $' vtcur db ' Term cursor-style: $' vtcset db ' Term character-set: $' vtclik db ' Term key-click: $' vtscrn db ' Term screen-background: $' colst1 db ' Term color foreground:3$' colst2 db ' background:4$' ; terminal emulator vtstbl stent ; VT100 line wrap stent ; VT100 margin bell stent ; VT100 cursor type stent ; VT100 newline stent ; VT100 screen stent ; VT100 character set stent ; VT100 keyclick stent ; VT100 colors stent ; VT100 tab status - needs one whole line dw 0 ; end of table ; end of Terminal data set ontab db 02H ; Two entries. db 03H,'off$' ; Should be alphabetized. [19a] dw 00H db 02H,'on$' dw 01H comptab db 04H db 01H,'1$' dw 01H db 01H,'2$' dw 00H db 04H,'COM1$' dw 01H db 04H,'COM2$' dw 00H ; this table is indexed by the baud rate definitions given in ; pcdefs. Unsupported baud rates should contain FF. ; Baud rates above 4800 may be sufficiently inaccurate to cause problems. [rwb] ; The 8251 must be run in 16x mode for reliable reception, which leads [rwb] ; to small divisors and large errors. The baud rate divisor is [rwb] ; calculated by 1,789,773 / (16 * baud rate). [rwb] ; Odd baud rates have not been tested [rwb] bddat label word dw 2458 ; 45.5 baud dw 2337 ; 50 baud dw 1491 ; 75 baud dw 1017 ; 110 baud dw 832 ; 134.5 baud dw 746 ; 150 baud dw 373 ; 300 baud dw 186 ; 600 baud ; actual baud rates in parentheses dw 93 ; 1200 baud (1202.8) dw 62 ; 1800 baud (1804.2) dw 56 ; 2000 baud (1997.5) dw 47 ; 2400 baud (2380.0) dw 23 ; 4800 baud (4863.5) dw 12 ; 9600 baud (9321.7) dw 6 ; 19200 baud (18643.5) dw 0FFh ; 38400 baud -- not supported, exceeds ; chip spec of 19.2K max ; variables for serial interrupt handler source db bufsiz DUP(?) ; Buffer for data from port. srcpnt dw 0 ; Pointer in buffer (DI). count dw 0 ; Number of chars in int buffer. savesi dw 0 ; Save SI register here. telflg db 0 ; Are we acting as a terminal. mst dw 0 ; Modem status address. mdat dw 0 ; Modem data address. mdeoi db 0 ; End-of-Interrupt value. rbtrn db 7fH ; rubout shkbuf db 300 dup (?) ; room for definition shkmsg db ' Scan code: ' shkmln equ $-shkmsg shkms1 db cr,lf,' Definition: ' shkm1ln equ $-shkms1 datas ends code segment public 'code' extrn comnd:near, dopar:near, defkey:near, gss:near, lclyini:near extrn sleep:near, atsclr:near, scrseg:near,scrloc:near, scrsync:near extrn atoi:near, strlen:near, prtscr:near, scroff:near, scron:near extrn vtsound:near ; [rwb] assume cs:code,ds:datas ; local initialization lclini proc near mov ax,0eH ; scan code for arrow key mov si,offset rbtrn ; translate to rubout mov cx,1 ; one char translation call defkey call model ; get model of IBM machine. [jrd] mov ax,8 ; set default 1200 baud [rwb] mov bp,portval ; [rwb] mov ds:[bp].baud,ax ; [rwb] call dobaud ; programm default baud rate [rwb] call lclyini ; let other modules initialize too... ret lclini endp ; 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 int mconf ; Get equipment configuration. mov ah,al ; Store AL value for a bit. and al,01H ; First, look at bit 0. jz dodsk0 ; No disk drives -- forget it. mov al,ah ; Get back original value. mov cl,6 ; Shift over bits 6 and 7. shr al,cl ; To positions 0 and 1. inc al ; Want 1 thru 4 (not 0 thru 3). mov drives,al ; Remember how many. ret dodsk0: mov ah,prstr ; Print a warning message. mov dx,offset erms20 ; I'm not sure if things will int dos ; work with only a cassette. mov drives,0 ; Say there aren't any drives. ret DODISK ENDP model proc near ; no model info, just return ret model endp ; show the definition of a key. The terminal argument block (which contains ; the address and length of the definition tables) is passed in ax. ; Returns a string to print in AX, length of same in CX. ; Revised to also run under IBM PC Netbios (lose some scan codes by doing ; DOS keyboard reads rather than Bios. Non-Network reads use Bios). [jrd] ; Returns normally. showkey proc near push es push ax ; save the ptr mov bx,ds mov es,bx ; address data segment cld showk1: cmp pcnet,0 ; running under Netbios? (0 = no) je showk3 ; e = no. xor bx,bx ; say shift state is none mov dl,0ffh ; Network. keyboard input, via DOS mov ah,conin ; get a char into al int dos xor ah,ah ; assume no scan code cmp al,0 ; special char? jne showk4 ; ne = no mov ah,conin ; get second byte, pseudo-scan-code int dos xor ah,ah ; clear effective shift state jmp showk4 ; and carry on regardless. showk3: xor ah,ah ; Non-Netbios. Bios keyboard input. int keyb ; read a char push ax ; save the character call gss ; get shift state pop bx mov ah,al ; shift state to ah mov al,bh ; scan code to al showk4: push ax ; remember scan code mov di,offset shkbuf mov si,offset shkmsg mov cx,shkmln rep movsb ; copy in initial message call nout ; write out scan code mov si,offset shkms1 mov cx,shkm1ln ; second message rep movsb pop ax ; get scan code back pop bx ; and terminal arg block mov cx,[bx].klen ; and length jcxz showk2 ; no table, not defined push di ; remember output ptr mov di,[bx].ktab ; get key table repne scasw ; search for a definition for this mov si,di ; remember result ptr pop di ; get output ptr back jne showk2 ; not defined, forget it sub si,[bx].ktab ; compute offset from beginning sub si,2 ; minus 2 for pre-increment add si,[bx].krpl ; get index into replacement table mov si,[si] ; pick up replacement mov cl,[si] ; get length mov ch,0 inc si rep movsb ; copy into buffer showk2: mov ax,offset shkbuf ; this is buffer mov cx,di sub cx,ax ; length pop es ret ; and return showkey 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 ax,offset source mov srcpnt,ax mov savesi,ax mov count,0 sti ret CLRBUF ENDP ; Clear to the end of the current line. Returns normally. ; Upgraded for Topview compatibility. [jrd] CLEARL PROC NEAR push ax push bx push dx mov ah,3 ; Clear to end of line. mov bh,0 int bios ; Get current cursor position into dx mov ax,dx ; Topview compatible clear line mov bh,ah ; same row mov bl,79 ; last column call atsclr ; clear from ax to bx, screen coord pop dx pop bx 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: mov bp,portval cmp ds:[bp].floflg,0 ; Are we doing flow control. je outch2 ; No, just continue. mov cl,trans.rtime ; receive timeout interval mov ch,0 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. mov al,1 ; else sleep for a second call sleep loop outch1 ; and try it again mov xofrcv,false ; timed out, force it off and fall thru. outch2: sub cx,cx mov al,ah ; Parity routine works on AL. call dopar ; Set parity appropriately. mov ah,al ; Don't overwrite character with status. outch3: in al,STS8251 ; get status [rwb] test al,TxEMPTY ; Transmitter ready? [rwb] jnz outch4 ; Yes loop outch3 jmp outch5 ; Timeout outch4: mov al,(TxEN+DTR+RxEN+ER+RTS) ; enable transmit [rwb] out CMD8251,al ; [rwb] push ax ; waste some time [rwb] pop ax ; [rwb] mov al,ah ; Now send it out [rwb] out BUF8251,al ; [rwb] push ax ; waste some time [rwb] pop ax ; [rwb] mov al,(DTR+RxEN+ER+RTS) ; back to receive-only mode [rwb] out CMD8251,al ; [rwb] jmp rskp outch5: ret ; This routine blanks the screen. Returns normally. ; Upgraded to Topview compatiblity. [jrd] CMBLNK PROC NEAR push ax push bx xor ax,ax ; from screen loc 0,0 mov bx,184fH ; to 24,79 call atsclr ; do Topview compatible clear, in msyibm pop bx pop ax ret CMBLNK ENDP ; Locate: 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 in inverse video at the bottom of the screen... ; the line is passed in dx, terminated by a $. Returns normally. putmod proc near push ax ; save regs. [jrd] push bx push cx push dx ; preserve message mov cx,1800h mov dx,184fh mov ax,600h ; scroll to clear the line mov bh,70h ; inverse video int bios mov dx,1800h ; now address line 24 call poscur pop si ; get message back mov cx,1 ; only one char at a time xor bh,bh ; page 0 putmo1: lodsb ; get a byte cmp al,'$' ; end of string? je putmo2 push si ; save si push ax ; and the char call poscur inc dl ; increment for next write pop ax ; recover char mov ah,9 ; try this mov bx,0070h ; inverse video, page 0 int bios pop si ; recover pointer jmp putmo1 putmo2: pop cx ; [jrd] pop bx pop ax ret putmod endp ; clear the mode line written by putmod. Returns normally. clrmod proc near push ax ; save regs. [jrd] push bx push cx push dx mov cx,1800h mov dx,184fh mov ax,600h mov bh,7h int bios pop dx ; [jrd] pop cx pop bx pop ax ret clrmod endp ; put a help message on the screen. This one uses reverse video... ; pass the message in ax, terminated by a null. Returns normally. puthlp proc near push bx ; save regs. [jrd] push cx push dx push si push ax ; preserve this cld mov si,ax ; point to it mov dh,1 ; init counter puthl1: lodsb ; get a byte cmp al,lf ; linefeed? jne puthl2 ; no, keep going inc dh ; count it jmp puthl1 ; and keep looping puthl2: cmp al,0 ; end of string? jne puthl1 ; no, keep going mov ax,600h ; scroll to clear window xor cx,cx ; from top left mov dl,4fh ; to bottom right of needed piece mov bh,70h ; inverse video int bios call locate ; home cursor mov bx,0070h ; bh = page 0, bl = inverse video mov cx,1 ; one char at a time cld ; scan direction is forward [jrd] pop si ; point to string again puthl3: lodsb ; get a byte cmp al,0 ; end of string? je puthl4 ; yes, stop push si ; save around bios call [jrd] cmp al,' ' ; printable? jb puth21 ; b = no mov ah,9 ; write char at current cursor position [jrd] int bios ; do the Bios int 10h call inc dl ; point to next column jmp puth23 ; move cursor there puth21: cmp al,cr ; carriage return? jne puth22 ; ne = no xor dl,dl ; set to column zero jmp puth23 puth22: cmp al,lf ; line feed? jne puth23 inc dh ; go to next line puth23: mov ah,2 ; set cursor position to dx int bios pop si ; restore pointer [jrd] jmp puthl3 ; and keep going puthl4: mov dx,24 * 100H ; go to last line call poscur ; position cursor pop si ; [jrd] pop dx pop cx pop bx 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 some regs. [jrd] push bx ; [jrd] push dx ; [jrd] push bp ; [jrd] mov bp,portval mov temp1,ax ; Don't overwrite previous rate. [25] mov ax,ds:[bp].baud ; Check if new rate is valid. [25] mov tmp,2 mul tmp ; Get index into baud table. mov bx,offset bddat ; Start of table. add bx,ax mov ax,[bx] ; The data to output to port. cmp ax,0FFH ; Unimplemented baud rate. jne dobd0 mov ax,temp1 ; Get back orginal value. mov ds:[bp].baud,ax ; Leave baud rate as is. mov ah,prstr mov dx,offset badbd ; Give an error message. int dos jmp dobd1 ; [jrd] dobd0: mov temp1,ax ; Remember value to output. [25] out CKC8253,al ; [rwb] mov al,ah out CKC8253,al dobd1: pop bp ; restore regs [jrd] pop dx ; [jrd] pop bx ; [jrd] pop ax ; [jrd] ret DOBAUD ENDP ; Get the current baud rate from the serial card and set it ; in the portinfo structure for the current port. Returns normally. ; This function is possible with the Sanyo hardware, so just return. [rwb] 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 call chkxon ; see if we need to xon cmp count,0 jnz prtch2 jmp rskp ; No data - check console. prtch2: mov si,savesi lodsb ; get a byte cmp si,offset source + bufsiz ; bigger than buffer? jb prtch1 ; no, keep going mov si,offset source ; yes, wrap around prtch1: dec count mov savesi,si mov dx,count ; return # of chars in buffer ret PRTCHR ENDP ; local routine to see if we have to transmit an xon chkxon proc near push bx mov bx,portval cmp [bx].floflg,0 ; doing flow control? je chkxo1 ; no, skip all this cmp xofsnt,false ; have we sent an xoff? je chkxo1 ; no, forget it cmp count,mntrgh ; below trigger? jae chkxo1 ; no, forget it mov ax,[bx].flowc ; ah gets xon call outchr ; send it nop nop nop ; in case it skips mov xofsnt,false ; remember we've sent the xon. chkxo1: pop bx ; restore register ret ; and return chkxon 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 ; Send a break out the current serial port. Returns normally. ; Sanyo mods [rwb] SENDBR PROC NEAR push cx push ax xor cx,cx mov al,(TxEN+DTR+RxEN+RTS) out CMD8251,al mov al,(TxEN+DTR+RxEN+SBRK+RTS) out CMD8251,al push ax mov ax,275 ; # of ms to wait call pcwait ; hold break for desired interval pop ax mov al,(TxEN+DTR+RxEN+RTS) out CMD8251,al mov al,(DTR+RxEN+ER+RTS) out CMD8251,al pop ax pop cx ret ; And return. SENDBR ENDP ; Wait for the # of milliseconds in ax ; 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 push bx mov ah,2 ; Position cursor. mov bh,0 ; page 0 int bios pop bx pop ax ret POSCUR ENDP ; Delete a character from the terminal. This works by printing ; backspaces and spaces. Returns normally. DODEL PROC NEAR mov ah,prstr mov dx,offset delstr ; Erase weird character. int dos ret DODEL ENDP ; Move the cursor to the left margin, then clear to end of line. ; Returns normally. CTLU PROC NEAR mov ah,prstr mov dx,offset clrlin int dos call clearl ret CTLU ENDP ; set the current port (only port 1 available on Sanyo) COMS PROC NEAR push ax mov ax,offset port1 mov portval,ax pop ax ret COMS ENDP ; begin Terminal set & status code ; SET Term parameters, especially for use with VT100 emulator. [jrd] ; Taken from work done originally by James Harvey IUPUI. ; VTS is called only by mssset to set terminal type and characteristics. VTS proc near ; SET TERM whatever mov ah,cmkey ; Parse another keyword. mov bx,offset vthlp ; Use this help mov dx,offset vttbl ; Use this table call comnd jmp r ; Vsetup always returns +1. cmp bx,100H ; marker for terminal type? jb vsetu1 ; b = no. cmp bx,200h ; marker for set term color? je vsetu2 ; e = yes push bx ; yes mov ah,cmcfm call comnd ; Get a confirm. jmp vsetu0 ; Didn't get a confirm. nop pop bx mov flags.vtflg,bl ; Set the terminal emulation type ret ; in standard global byte. vsetu0: pop bx ret vsetu1: sal bx,1 ; Make bx a word index. call vtrtns[bx] ; Dispatch. jmp r ; Vsetup always returns +1. jmp r ; Vsetup always returns +1. ; Set Term Color foreground, background vsetu2: mov ah,cmtxt ; get number(s) after set term color mov dx,offset colhlp ; use this help mov bx,offset rdbuf ; temp buffer mov byte ptr [bx],0 ; clear the buffer call comnd jmp r cmp ah,0 ; anything given? jne vsetu2a ; ne = yes. jmp r ; else give not confirmed msg vsetu2a:mov ah,cmcfm ; Parse confirm mov bx,0 ; Use default help. call comnd jmp r ; not confirmed, complain. mov si,offset rdbuf ; si = place where atoi wants text vsetu2c:mov dx,si call strlen ; current length of text jcxz vsetu2x ; nothing left mov ah,cl ; put length where Atoi wants it call atoi ; convert text to numeric in ax jmp colbad ; no value available cmp ax,0 ; reset all? regular IBM CGA refresh je vsetu2j ; e = yes cmp ax,1 ; high intensity? je vsetu2k ; e = yes cmp ax,10 ; fast refresh? je vsetu2l ; e = yes cmp ax,30 ; check range jb colbad ; b = too small. complain cmp ax,37 jna vsetu2b ; 30-37 is foreground color cmp ax,40 jb colbad cmp ax,47 ; Compare as unsigned. jna vsetu2b ; 40-47 is background jmp colbad ; else error vsetu2x:jmp rskp ; and return normally. vsetu2b:push bx mov bx,vtemu.att_ptr ; Get address of attributes byte cmp al,40 ; background (40-47)? jnb vsetu2f ; nb = yes sub al,30 ; remove foreground bias and byte ptr [bx],not 07H ; clear foreground bits test al,1 ; ANSI red? jz vsetu2d ; z = no or byte ptr [bx],4 ; set IBM foreground red vsetu2d:test al,2 ; ANSI & IBM green? jz vsetu2e ; z = no or byte ptr [bx],2 ; set green foreground vsetu2e:test al,4 ; ANSI Blue? jz vsetu2i ; z = no or byte ptr [bx],1 ; set IBM blue jmp vsetu2i ; done with foreground settings vsetu2f:sub al,40 ; remove background bias and byte ptr [bx],not 70H ; clear background attributes test al,1 ; ANSI red? jz vsetu2g ; z = no or byte ptr [bx],40h ; set IBM background red vsetu2g:test al,2 ; ANSI & IBM green? jz vsetu2h ; z = no or byte ptr [bx],20h ; set green background vsetu2h:test al,4 ; ANSI Blue? jz vsetu2i ; z = no or byte ptr [bx],10h ; set IBM blue vsetu2i:pop bx jmp vsetu2c ; get any next value vsetu2j:mov refresh,0 ; Regular (slow) screen refresh mov bx,vtemu.att_ptr ; Get address of attributes byte mov byte ptr [bx],07h ; clear all, set white on black. jmp vsetu2c ; get next value vsetu2k:mov bx,vtemu.att_ptr ; Get address of attributes byte or byte ptr [bx],08h ; set high intensity jmp vsetu2c ; get next value vsetu2l:mov refresh,1 ; Fast screen refresh jmp vsetu2c colbad: mov ah,prstr ; Not in range - complain and exit. mov dx,offset colerr int dos jmp rskp ; SET Term flags. These are the (near) equivalent of VT100 Setup mode values. flgset: push bx ; Save bx for a second. mov ah,cmkey ; Another keyword. mov dx,vtable[bx] ; The table to use. mov bx,0 ; Use default help. call comnd jmp flgse3 push bx ; Save switch value. mov ah,cmcfm ; Confirm it. call comnd jmp flgse2 pop dx ; Restore switch value. pop bx ; And index. sar bx,1 ; Make it a byte index. mov al,vtsflg[bx] ; Get the flag. cmp dx,0 ; Set or clear? je flgse1 ; Go clear it. or vtemu.vtflgst,al ; Set the flag. jmp rskp ; Give good return. flgse1: not al ; Complement and vtemu.vtflgst,al ; Clear the indicated flag. jmp rskp ; Give good return. flgse2: pop bx ; error exits flgse3: pop bx ret ; SET Term Tabstops Clear ALL ; SET Term Tabstops Clear AT n1, n2, ..., nx ; SET Term Tabstops At n1, n2, ..., nx tabset: cld ; Make sure this is clear. mov di,offset tmptabs ; clear our temp work area here. mov cx,80 ; 80 columns mov al,0 ; set "not touched" indicator rep stosb ; in all tmptabs slots mov ah,cmkey ; Parse keyword. mov bx,offset clrhlp ; Use this help text. mov dx,offset tabtab ; This table. call comnd jmp r mov clrset,2 ; code for set a tab cmp bl,0 ; Was it set or clear? jne tabse1 ; SET - go parse column number(s). mov clrset,1 ; code for clear at/all tab(s) mov ah,cmkey ; CLEAR - parse ALL or AT mov bx,offset allhlp ; Use this help text. mov dx,offset alltab ; Parse ALL or AT. call comnd jmp r cmp bx,0 ; ALL? jne tabse1 ; ne = AT, clear at specific places. mov al,1 ; ALL, means clear all tab stops. mov cx,80D mov di,offset tmptabs rep stosb mov ah,cmcfm ; Confirm it. call comnd jmp r jmp tabcpy ; update active & coldstart tabs tabse1: mov dx,offset tbshlp ; Tell them we want a column number. cmp clrset,1 ; Clearing? jne tabse2 ; ne = Set. we guessed right on help. mov dx,offset tbchlp ; Yes - use this help instead. tabse2: mov ah,cmtxt ; get text w/o white space mov bx,offset rdbuf ; temp buffer call comnd jmp r cmp ah,0 ; anything given? jne tabse4 ; ne = yes. jmp r ; else give not confirmed msg tabse4: mov ah,cmcfm ; Parse confirm mov bx,0 ; Use default help. call comnd jmp r ; not confirmed, complain. mov si,offset rdbuf ; si = place where atoi wants text tabse5: mov dx,si call strlen ; current length of text mov ah,cl ; put length where Atoi wants it jcxz tabcpy ; nothing left call atoi ; convert text to numeric in ax nop nop nop mov bx,ax ; for subscripting in code below dec bx ; Put column in range 0-79 cmp bx,0 ; check range (1-80 --> 0-79) jl tbsbad ; l = too small. complain cmp bx,79 ; Compare as unsigned. jna tabse3 tbsbad: mov ah,prstr ; Not in range - complain and exit. mov dx,offset tbserr int dos jmp rskp tabse3: mov al,clrset ; Get value for setting or clearing. mov tmptabs[bx],al ; store in tabs temp work array jmp tabse5 ; look for more tabcpy: mov cx,80 ; update 80 tab stops mov si,vtemu.vttbst ; in terminal emulator's active buffer mov di,vtemu.vttbs ; and in the cold-start buffer. mov bx,0 ; subscript tabcpy1:mov al,byte ptr tmptabs [bx] ; get a table entry into al or al,al ; what is the code? jz tabcpy3 ; z = do not touch cmp al,2 ; set a tab? je tabcpy2 ; e = set the tab mov byte ptr [bx+si],0 ; clear the tab mov byte ptr [bx+di],0 ; clear the tab jmp tabcpy3 tabcpy2:mov byte ptr [bx+si],0ffh ; set the tab mov byte ptr [bx+di],0ffh ; set the tab tabcpy3:inc bx ; inc subscript loop tabcpy1 jmp rskp ; Give good return. VTS endp ; end of Set Term things. ; Terminal Status display, called within STAT0: in MSSSET.[jrd] VTSTAT proc near ;enter with di within sttbuf, save bx, di push bx push di mov bx,ds mov es,bx cld mov bx,offset vtstbl ; table of things to show xor cx,cx vtsta1: cmp word ptr [bx],0 ; end of table? je vtstax ; e = yes push bx call [bx].sttyp ; call appropriate routine pop bx ; cx incremented by output count cmp cx,37 ; place for second display jbe vtsta2 ; le = only half full mov dx,offset crlf ; over half full. send cr/lf mov ah,prstr int dos xor cx,cx ; say line is empty now jmp vtsta4 vtsta2: push cx mov cx,37 ; where we want to be next time pop ax sub cx,ax ; compute number of filler spaces jcxz vtsta4 ; nothing to do mov ah,conout mov dl,' ' vtsta3: int dos ; fill with spaces loop vtsta3 ; do cx times mov cx,37 ; current column number vtsta4:add bx,size stent ; look at next entry jmp vtsta1 ; and do it vtstax: pop di pop bx add di,40 ; say we used a lot of buffer space ret ; return to STAT0: in MSSSET. ; foreground/background color status colstat proc near mov dx,offset colst1 mov ah,prstr int dos ; print first part of msg xor ax,ax mov bx,vtemu.att_ptr ; pointer to attributes byte test byte ptr [bx],1 ; IBM blue foregound? jz colsta1 ; z = no or al,4 ; set blue bit colsta1:test byte ptr [bx],2 ; IBM green foreground? jz colsta2 or al,2 colsta2:test byte ptr [bx],4 ; IBM red foreground? jz colsta3 or al,1 colsta3:add al,'0' ; add ascii bias mov dl,al ; move to DOS place mov ah,conout int dos ; print the last digit mov dx,offset colst2 ; now do background mov ah,prstr int dos ; print second part of msg xor ax,ax test byte ptr [bx],10h ; IBM blue background? jz colsta4 ; z = no or al,4 ; set blue bit colsta4:test byte ptr [bx],20h ; IBM green background? jz colsta5 or al,2 ; set green bit colsta5:test byte ptr [bx],40h ; IBM red background? jz colsta6 or al,1 ; set red bit colsta6:add al,'0' ; add ascii bias mov dl,al ; move to DOS place mov ah,conout int dos add cx,45 ; about the # columns we used ret colstat endp ; Tabs Status display tabstat proc near ; display tabs ruler for Status push dx jcxz tabsta0 ; empty line, as it should be xor cx,cx ; used line, empty it mov dx,offset crlf ; cr, lf mov ah,prstr int dos tabsta0:mov si,vtemu.vttbst ; active tabs address, not shadow mov cx,79 ; loop 79 times dec si ; dec for inc below xor ax,ax ; tens counter tabsta1:mov dl,'.' ; default position symbol inc si ; start with position 1 inc al cmp al,10 ; time to roll over? jb tabsta2 ; b = not yet mov al,0 ; modulo 10 inc ah mov dl,ah ; display a tens-digit add dl,'0' tabsta2:cmp byte ptr [si],0 ; is tab set? je tabsta3 ; e = no mov dl,'T' ; yes, display a 'T' tabsta3:push ax mov ah,conout ; console output int dos pop ax loop tabsta1 ; loop til done (cx has count) pop dx mov cx,79 ; say line is full ret tabstat endp ; handler routines for status. All are called with bx/ stat ptr. onoff proc near call stmsg ; print the message mov si,[bx].basval ; get base value cmp si,0 ; any there? je onoff1 ; e = no mov si,[si] ; yes, use as base address onoff1: add si,[bx].tstcel ; add offset of test cell mov al,[si] mov dx,offset onmsg ; add cx,2 ; assume two byte on message or al,al ; test value jnz onoff2 ; nz = on mov dx,offset offmsg inc cx ; three byte message onoff2: mov ah,prstr ; display the message int dos ret onoff endp ; search a keyword table for a bit value, print that value. [jrd] srchkb proc near call stmsg ; first print message call stbval ; get bit set or reset mov ah,0 ; al has 0/1, high order is 0 mov bx,[bx].val2 ; this is table address jmp prttab ; and look in table. srchkb endp ; get address of test value in stent. Returns address in si. [jrd] stbval proc near mov si,[bx].basval ; get address of test value cmp si,0 ; any there? je stbva1 ; no, quit with no match mov al,byte ptr [si]; get byte value mov ah,0 test al,vtemu.vtflgst ; bit test value against emulator flags byte jz stbva1 ; z = they don't match mov al,1 ; match ret stbva1: mov al,0 ; no match ret ; and return it stbval endp ; get address of test value in stent. Returns address in si stval proc near mov si,[bx].basval ; get base value cmp si,0 ; any there? je stva1 ; no, keep going mov si,[si] ; yes, use as base address stva1: add si,[bx].tstcel ; add offset of test cell ret ; and return it stval endp ; copy the message to the screen stmsg proc near mov si,[bx].msg ; get message address stms1: lodsb ; get a byte cmp al,'$' ; end of message? je stms2 ; e = yes mov dl,al ; display the character mov ah,conout int dos inc cx ; count output chars jmp stms1 stms2: ret stmsg endp ; Print value from table. BX/address of table, AL/value of variable. prttab: push cx ; save column count mov cl,[bx] ; Number of entries in our table. inc bx ; Point to the data. prtt0: mov dl,[bx] ; Length of keyword. inc bx ; Point to keyword. mov dh,0 inc dx ; Account for "$" in table. mov si,dx ; Put to index register. cmp ax,[bx+si] ; Is this the one? je prtt1 add bx,dx ; Go to end of keyword. add bx,2 ; Point to next keyword. dec cl ; Any more keywords to check? jnz prtt0 ; Yes, go to it. mov bx,offset prterr prtt1: mov si,bx pop cx ; recover column count jmp stms1 ; copy in message ret ; and return VTSTAT endp ; end of Terminal set & status code ; Initialization for using serial port. This routine performs ; any initialization necessary for using the serial port, including ; setting up interrupt routines, setting buffer pointers, etc. ; Doing this twice in a row should be harmless (this version checks ; a flag and returns if initialization has already been done). ; SERRST below should restore any interrupt vectors that this changes. ; ; Revised slightly by Joe R. Doupnik 22 Dec 1985 to prevent interrupts ; being enabled until we're done, to stop interrupts from occurring when ; TX holding buffer becomes empty (a useless interrupt for us), and to ; shorten the time between enabling interrupts and our exit. [jrd] ; Returns normally. SERINI PROC NEAR cmp portin,0 ; Did we initialize port already? [21c] jne serin0 ; Yes, so just leave. [21c] cli ; Disable interrupts cld ; Do increments in string operations push es ; moved here by [jrd] xor ax,ax ; Address low memory mov es,ax mov bx,VEC8251 ; Save serial card interrupt vector. [19b] mov ax,es:[bx] mov savsci,ax mov ax,offset serint ; And point it to my routine mov es:[bx],ax add bx,2 ; Save CS register too. [19b] mov ax,es:[bx] mov savscs,ax mov es:[bx],cs mov portin,1 ; Remember port has been initialize. mov ax,offset source ; Clear input buffer, but don't touch [jrd] mov srcpnt,ax ; interrupts (CLRBUF turns them on!). [jrd] mov savesi,ax ; [jrd] mov count,0 ; end of clearing input buffer. [jrd] pop es ; moved here by [jrd] mov al,IR ; 8251 reset command [rwb] out CMD8251,al ; [rwb] push ax ; waste some time [rwb] pop ax ; (may not be necessary) [rwb] mov al,04Eh ; 8-bit, no parity, 1 stop, 16x clock [rwb] out CMD8251,al ; [rwb] push ax ; waste time again [rwb] pop ax ; [rwb] mov al,(DTR+RxEN+ER+RTS) ; enable receive [rwb] out CMD8251,al ; [rwb] in al,CMB8259 ; get interrupt mask [rwb] and al,INT8251 ; enable RS-232 interrupt [rwb] out CMB8259,al ; [rwb] sti ; Allow interrupts (AFTER next instr). [jrd] serin0: ret ; We're done. [jrd] SERINI ENDP ; Reset the serial port. This is the opposite of serini. Calling ; this twice without intervening calls to serini should be harmless. ; Moved push/pop es code to do quicker exit before interrupts enabled. [jrd] ; Returns normally. SERRST PROC NEAR cmp portin,0 ; Reset already? je srst1 ; Yes, just leave. cli ; Disable interrupts xor bx,bx ; Address low memory push es ; preserve this. Moved here by [jrd] mov es,bx mov bx,VEC8251 ; Restore the serial card int vector mov ax,savsci mov es:[bx],ax add bx,2 ; Restore CS too. mov ax,savscs mov es:[bx],ax ; leave receive and transmit enabled (that's how DOS sets them initially) [rwb] mov al,IR ; 8251 reset command [rwb] out CMD8251,al ; [rwb] push ax ; waste some time [rwb] pop ax ; (may not be necessary) [rwb] mov al,04Eh ; 8-bit, no parity, 1 stop, 16x clock [rwb] out CMD8251,al ; [rwb] push ax ; waste time again [rwb] pop ax ; [rwb] mov al,(DTR+RxEN+TxEN+ER+RTS) ; enable transmit and receive [rwb] out CMD8251,al ; [rwb] pop es ; Moved here by [jrd] srst3: mov portin,0 ; Reset flag. sti ; Enable interrupts after next instruct. [jrd] srst1: ret ; All done. SERRST ENDP ; serial port interrupt routine. This is not accessible outside this ; module, handles serial port receiver interrupts. SERINT PROC NEAR push ax ; [jrd] push ds ; do ds and ax first [jrd] push bx push dx push es push di push bp push cx cld mov ax,seg datas mov ds,ax ; address data segment mov es,ax mov di,srcpnt ; Registers for storing data. in al,STS8251 ; [rwb] test al,RxRDY ; Data available? [rwb] jz retint ; Nope. in al,BUF8251 ; [rwb] cmp telflg,0 ; File transfer or terminal mode? [17c] jz srint0 and al,7FH ; Terminal mode (7 bits only). srint0: or al,al jz retint ; Ignore nulls. mov ah,al and ah,7fH ; strip parity temporarily cmp ah,7FH ; Ignore rubouts, too. jz retint mov bp,portval cmp ds:[bp].floflg,0 ; Doing flow control? je srint2 ; Nope. mov bx,ds:[bp].flowc ; Flow control char (BH = XON, BL = XOFF). cmp al,bl ; Is it an XOFF? jne srint1 ; Nope, go on. mov xofrcv,true ; Set the flag. jmp retint srint1: cmp al,bh ; Get an XON? jne srint2 ; No, go on. mov xofrcv,false ; Clear our flag. jmp retint srint2: stosb cmp di,offset source + bufsiz jb srint3 ; not past end... mov di,offset source ; wrap buffer around srint3: inc count cmp ds:[bp].floflg,0 ; Doing flow control? je retint ; No, just leave. cmp xofsnt,true ; Have we sent an XOFF? je retint ; Yes. cmp count,mntrgh ; Past the high trigger point? jbe retint ; No, we're within our limit. mov ah,bl ; Get the XOFF. call outchr ; Send it. nop nop nop ; ignore failure. mov xofsnt,true ; Remember we sent it. retint: mov srcpnt,di pop cx ; timing is important here. [jrd] pop bp ; each pop takes 10 machine cycles. [jrd] pop di pop es pop dx pop bx pop ds ; just let end of interrupt be generated by IRET, sending a specific [rwb] ; command to the interrupt controller does not seem to be necessary [rwb] pop ax ; [jrd] intret: iret SERINT ENDP DTRLOW PROC NEAR ; Global proc to Hangup the Phone by making ; DTR and RTS low. [jrd] 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. serhng proc near ; clear modem's delta status bits and lower DTR & RTS cli ; Disable interrupts mov al,IR ; 8251 reset command [rwb] out CMD8251,al ; [rwb] push ax ; waste some time [rwb] pop ax ; (may not be necessary) [rwb] mov al,04Eh ; 8-bit, no parity, 1 stop, 16x clock [rwb] out CMD8251,al ; [rwb] push ax ; waste time again [rwb] pop ax ; [rwb] mov al,(RxEN+ER) ; DTR and RTS low [rwb] out CMD8251,al ; [rwb] sti ; Enable interrupts after next instruct. [jrd] ret serhng endp ; Produce a short beep. The PC DOS bell is long enough to cause a loss ; of data at the port. Returns normally. ; May also be true with Sanyo, depends on exactly what DOS is used [rwb] BEEP PROC NEAR push bx ; [rwb] push di ; [rwb] mov bx,3 ; [rwb] mov di,8 ; [rwb] call vtsound ; in msz55x [rwb] pop di ; [rwb] pop bx ; [rwb] ret BEEP ENDP ; put the number in ax into the buffer pointed to by di. Di is updated nout proc near mov dx,0 ; high order is always 0. mov bx,10 div bx ; divide to get digit push dx ; save remainder digit or ax,ax ; test quotient jz nout1 ; zero, no more of number call nout ; else call for rest of number nout1: pop ax ; get digit back add al,'0' ; make printable stosb ; drop it off ret ; and return nout 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 code ends end