|
DataMuseum.dkPresents historical artifacts from the history of: DKUUG/EUUG Conference tapes |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about DKUUG/EUUG Conference tapes Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - downloadIndex: T m
Length: 86841 (0x15339) Types: TextFile Names: »msxp98.asm«
└─⟦9ae75bfbd⟧ Bits:30007242 EUUGD3: Starter Kit └─⟦71044c191⟧ »EurOpenD3/misc/kermit.ms-2.32.tar.Z« └─⟦31f2d420d⟧ └─⟦this⟧ »msxp98.asm«
name msxp98 ; File MSXP98.ASM ; NEC PC-9801 MS DOS Kermit module. ; ; Last edit: 16 Jul 1988 ; 16 Jul 1988 Keyboard kanji translation comes into chrout to work with ; SET KEY command. ; 14 Jul 1988 V2.31 ; old global variable PCNET is now local variable ; local termination pointer NETDONE is renamed LCLEXIT ; GETMODEM is added as a dummy routine (from MSXGEN.ASM) ; Ungermann-Bass port name is UB-NETCI ; 25 Jun 1988 Ungermann-Bass PC-NIU N98 support in NETCI mode ; 15 Jun 1988 V1.00 ; 06 Jun 1988 show modem is installed ; 23 May 1988 added KEYCLICK, AUTOTEK features ; 19 May 1988 become v2.27(A) level (TEK4014, VT100) ; 18 May 1988 Keyboard routine for VT100 is installed. ; 16 May 1988 Works with v2.27(A) VT100 output routine. ; 15 May 1988 Fixed bug in SERINI. ; 14 May 1988 Works with dumb terminal emulator ! ; 12 May 1988 start coding based on MSXGEN.ASM by H.Fujii public serini, serrst, clrbuf, outchr, coms, vts, vtstat, dodel public ctlu, cmblnk, locate, lclini, prtchr, dobaud, clearl public dodisk, getbaud, beep, trnprs, pcwait, termtb public count, xofsnt, puthlp, putmod, clrmod, poscur public sendbr, sendbl, term, machnam, setktab, setkhlp, showkey public ihosts, ihostr, dtrlow, serhng, dumpscr, comptab public chrout, cstatus, cquit, cquery, chang ; kbd action verbs public snull, kdos, klogof, klogon public shomodem, getmodem, mdmhand public pf1, pf2, pf3, pf4 public kp0, kp1, kp2, kp3, kp4, kp5, kp6, kp7, kp8, kp9 public kpmins, kpcoma, kpentr, kpdot public uparrw, dnarrw, lfarrw, rtarrw public keyinchg public s2jis, jis2s, is_kanji1 public curkey_mode, keypad_mode public kanji_rmode, kanji_smode public keyin_dos, vt100_flags include mssdef.h BIOS equ 18h AUTOWRAP_BIT equ 1 AUTOTEK_BIT equ 2 KEYCLICK_BIT equ 4 CURSOR_BIT equ 8 BLINK_BIT equ 16 LOOPTEST_BIT equ 128 CHR_GS equ 1Dh CHR_CAN equ 18h 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 ; ; Ungermann-Bass PC-NIU N98 command interpreter interface ; CALL AH -- Function number ; AL -- Port number relative to 0 ; CX -- may be a counter ; ES:BX -- may be a buffer address NETCI_PORT equ 0 ; NETCI port number NETCI_INT equ 06Bh ; Software interrupt vector# for NETCI NETCI_OPEN equ 2 ; NETCI open function NETCI_CLOSE equ 3 ; NETCI close function NETCI_READ equ 1 ; NETCI read function NETCI_WRITE equ 0 ; NETCI write function NETCI_CNTL equ 6 ; NETCI control function NETCI_STATUS equ 7 ; NETCI status function NETCI_RBRK equ 8 ; NETCI read break function ; Buffer size for Network transfer NETBUFLEN equ 256 ; port assignments for 8251 serial controllers ; ;== PORT 1 == mndata equ 30h mnst1a equ 32h mncmda equ 32h mnmska equ 35h ; mask set mnrdsa equ 33h ; read signal ;== PORT 2 == mndatb equ 0B1h mnst1b equ 0B3h mncmdb equ 0B3h mnmskb equ 0B0h mnrdsb equ 0B0h ; read signal ;== PORT 3 == mndatc equ 0B9h mnst1c equ 0BBh mncmdc equ 0BBh mnmskc equ 0B2h ; mask set mnrdsc equ 0B2h ; read signal ; Status bits from austt txrdy equ 01h rxrdy equ 02h ; Command values for mncmd ccmd equ 37H ; RTS & DTR high, RX & TX enabled, reset ERR cbrk equ 08H ; break enabled cmode equ 40H ; enable mode reset mmode equ 4EH ; 16x rate, 8 data, no parity, 1 stop ; Mask values for mnmsk txmsk equ 04H ; disables transmit ready interrupt rxmsk equ 01H ; disables receive ready interrupt tbemsk equ 02H ; disables transmit buffer empty interrupt ; port assignments for 8253 timers ; Standard interface tmdata equ 75H ; data port tmcmda equ 77H ; command port (Was 27H Ian 10/27/84) ; values for tmcmd which select timer channel and mode tmsela equ 0B6H ; Channel 2, mode 3 (standard port) ; Timer information for current port selection tmrinfo struc tmdat dw 0 ; data port tmcmd dw 0 ; command port tmsel db 0 ; byte which selects channel and mode tmrinfo ends ; Modem information for current port selection ; port assignments for 8259 interrupt controllers ; Standard interface intcmda equ 00H ; Command port (master controller) intmska equ 02H ; Mask port ictmsk equ 01H ; Timer interrupt mask (to master) icsmska equ 10H ; Standard serial interrupt mask (to master) icsvcta equ 0CH ;Interrupt vector for standard interface icEOI equ 20H ; generic end of interrupt for intcmd kbfifosiz equ 64 ; size of fifo buffer in IO.SYS ; miscellaneous constants ctrlP equ 10H ; ^P. ctrl_q equ 11H ; ^Q ctrl_s equ 13H ; ^S printkey equ 00FFH ; Scan code of unshifted PRINT key. brkstp equ 0096H ; Scan code of unshifted break/stop key. mntrgh equ bufsiz*3/4 ; High XON/XOFF trigger = 3/4 of buffer full. ; external variables used: ; drives - # of disk drives on system ; flags - global flags as per flginfo structure defined in pcdefs ; trans - global transmission parameters, trinfo struct defined in pcdefs ; portval - pointer to current portinfo structure (currently either port1 ; or port2) ; port1, port2 - portinfo structures for the corresponding ports ; global variables defined in this module: ; xofsnt, xofrcv - tell whether we saw or sent an xoff. datas segment public 'datas' extrn drives:byte, flags:byte, trans:byte, ttyact:byte extrn filtst:byte ;* in mssker extrn portval:word, port1:byte, port2:byte, port3:byte, port4:byte extrn lclexit:word extrn comand:byte, dmpname:byte ; [jrd] extrn kbdflg:byte, rxtable:byte ;- common variables ----- curkey_mode db 0 keypad_mode db 0 kanji_smode db 0 ; Kanji 1st/2nd byte indicator kanji_rmode db 0 kanji_scode db 0 kanji_rcode db 0 keyin_dos db 0 vt100_flags db 0 ;------------------------ pcnet db 0 ; 2.30 global --> 2.31 local kanjis1 db 0 ; storage for Kanji 1st byte kanjir1 db 0 kanjio1 db 0 ; storage for DEC Kanji code kanjio2 db 0 param_dst dw ? mdstreg db ? ; modem status register machnam db 'NEC PC-9801 (KEK v1.10)$' erms20 db cr,lf,'?Warning: System has no disk drives$' erms40 db cr,lf,'?Warning: Unrecognized baud rate$' erms41 db cr,lf,'?Warning: Cannot open com port$' erms50 db cr,lf,'Error reading from device$' hnd1 db cr,lf,'Enter a file handle. Check your DOS manual if you are ' db cr,lf,'not certain what value to supply (generally 3).$' hnd2 db cr,lf,'Handle: $' hnderr db cr,lf,'Warning: Handle not known.' deverr db cr,lf,'Any routine using the communications port will' db cr,lf,'probably not work.$' hndhlp db cr,lf,'A one to four digit file handle $' dev1 db cr,lf,'Device: $' devhlp db cr,lf,'Name for your systems auxiliary port $' badbd db cr,lf,'Unimplemented baud rate$' 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,' Modem is not ready: DSR is off$' msmsg2 db cr,lf,' Modem is ready: DSR is on$' msmsg3 db cr,lf,' no Carrier Detect: CD is off$' msmsg4 db cr,lf,' Carrier Detect: CD is on$' msmsg5 db cr,lf,' no Clear To Send: CTS is off$' msmsg6 db cr,lf,' Clear To Send: CTS is on$' rdbuf db 80 dup (?) ; temp buf [jrd] tmpbuf db 80 DUP (?) test_hndl dw ? test_fnam db 'KERMIT.TST',0 shkmsg db 'Not implemented.' shklen equ $-shkmsg setktab db 0 setkhlp db 0 crlf db cr,lf,'$' delstr db BS,BS,' ',BS,BS,'$' ; Delete string delscr db ESCAPE,'[2J$' ; Delete screen scn_color dw 0507h save_cur db ESCAPE,'[s$' ; save cursor restore_cur db ESCAPE,'[u$' ; resoter cursor home_cur db ESCAPE,'[H$' ; home cursor ; If delete code moves cursor then BS over code, BS over bad char, space ; over both to erase from screen, BS twice to restore cursor position. clrlin db cr,'$' ; Clear line (just the cr part). clreol db ESCAPE,'[K$' ; Clear to end of line. telflg db 0 ; non-zero if we're a terminal. argadr dw ? ; address of arg blk from msster.asm parmsk db ? ; 8/7 bit parity mask, for reception flowoff db ? ; flow-off char, Xoff or null (if no flow) flowon db ? ; flow-on char, Xon or null captrtn dw ? ; routine to call for captured output xofsnt db 0 ; Say if we sent an XOFF. xofrcv db 0 ; Say if we received an XOFF. prthnd dw 0 ; Port handle. temp dw 0 temp1 dw ? ; Temporary storage. temp2 dw ? ; Temporary storage. prtstr db 20 dup(?) ; Name of auxiliary device ; Entries for choosing communications port comptab db 7 ; Number of options mkeyw '1',1 mkeyw '2',2 mkeyw '3',3 mkeyw 'COM1',1 mkeyw 'COM2',2 mkeyw 'COM3',3 mkeyw 'UB-NETCI','N' mkeyw ' ',0 ; port is not present, for Status ourarg termarg <> modem mdminfo <mndata,mnst1a,mncmda,0,0,0,0> timer tmrinfo <tmdata,tmcmda,tmsela> ;++ The following structure must be initialized as in MSSKER ; portn prtinfo <0FFFFh,0,defpar,1,0,defhand,floxon> termtb db tttypes ; entries for Status, not Set mkeyw 'Heath-19',ttheath mkeyw 'none',ttgenrc mkeyw 'Tek4014',tttek mkeyw 'VT102',ttvt100 mkeyw 'VT52',ttvt52 vthlp db ' one of the following:',cr,lf db ' terminal types of: None, VT102, or Tek4014',cr,lf db ' Keyclick (on/off) ' db ' Keyinput (CON/direct) ',cr,lf db ' Color (white,yellow...)' db ' Highlight (cyan,green...)',cr,lf db ' AutoTek (on/off) ', db ' Kanji-code (DECcode,ShiftJIS,none)',cr,lf db '$' ; <<< DO NOT forget to update the number of items at 'vttbl' when you add ; new item to the following list >>> vttbl db 13 mkeyw 'AutoTek',AUTOTEK_BIT+200H mkeyw 'Blink',BLINK_BIT+200H mkeyw 'Color',300H mkeyw 'Cursor',CURSOR_BIT+200H mkeyw 'Highlight',301H mkeyw 'Kanji-Code',400H mkeyw 'Keyclick',KEYCLICK_BIT+200H mkeyw 'Keyinput',500H mkeyw 'LoopTest',LOOPTEST_BIT+200H mkeyw 'None',ttgenrc+100H ; note 100H flag for decoding here mkeyw 'Tek4014',tttek+100H mkeyw 'VT102',ttvt100+100H mkeyw 'Wrap',AUTOWRAP_BIT+200H ; <<< DO NOT forget to update the number of items at 'vttbl' when you add ; new item to the above list >>> ontab db 2 mkeyw 'off',0 mkeyw 'on',1 colortab db 8 mkeyw 'black',0 mkeyw 'blue',1 mkeyw 'cyan',5 mkeyw 'green',4 mkeyw 'magenta',3 mkeyw 'red',2 mkeyw 'white',7 mkeyw 'yellow',6 kanjitab db 3 mkeyw 'DEC-code',2 mkeyw 'None',0 mkeyw 'Shift-JIS',4 keyintab db 2 mkeyw 'CON ',1 mkeyw 'direct',0 ; this table is indexed by the baud rate definitions given in ; pcdefs. Unsupported baud rates should contain FF. ; Baudrate clock count table for 5/10 MHz CPU even bddat5 label word ; AHS 29-MAY-86 dw 00D30H ; 45.5 baud dw 00C00H ; 50 baud dw 00800H ; 75 baud dw 00574H ; 110 baud dw 00476H ; 134.5 baud dw 00400H ; 150 baud dw 00200H ; 300 baud dw 00100H ; 600 baud dw 00080H ; 1200 baud dw 00055H ; 1800 baud dw 0004DH ; 2000 baud dw 00040H ; 2400 baud dw 00020H ; 4800 baud dw 00010H ; 9600 baud dw 00008H ; 19200 baud dw 00004H ; 38400 baud (not tested - may not work) dw 0FFFFH dw 0FFFFH dw 0FFFFH ; Baud rate clock count table for 8 MHz CPU bddat8 label word ; AHS 29-MAY-86 dw 0FFFFH ; 45.5 baud dw 0FFFFH ; 50 baud dw 00680H ; 75 baud dw 0FFFFH ; 110 baud dw 0FFFFH ; 134.5 baud dw 00340H ; 150 baud dw 001A0H ; 300 baud dw 000D0H ; 600 baud dw 00068H ; 1200 baud dw 0004EH ; 1800 baud dw 0FFFFH ; 2000 baud dw 00034H ; 2400 baud dw 0001AH ; 4800 baud dw 0000DH ; 9600 baud dw 0FFFFH ; 19200 baud dw 0FFFFH ; 38400 baud (not tested - may not work) dw 0FFFFH dw 0FFFFH dw 0FFFFH baudlen equ ($-bddat8)/2 ; number of entries above unkbaud db ' Unk ' ; must be 5 characters baudname db ' 45.5' db ' 50 ' db ' 75 ' db ' 110 ' db '134.5' db ' 150 ' db ' 300 ' db ' 600 ' db ' 1200' db ' 1800' db ' 2000' db ' 2400' db ' 4800' db ' 9600' db '19200' db '38400' db '57.6K' db '115 K' BAUDNSIZ equ 18 parityname db 'even' ; must be 4 characters db 'mark' db 'none' db 'odd ' db 'spc ' lclename db 'loc' remename db 'rem' axsave dw ? portinia dw 0 dmphand dw ? ; file handle for dump file oldsera_ofs dw ? oldsera_sgm dw ? oldmska db ? oldmsdat db ? ; variables for serial interrupt handler even source db bufsiz DUP (?) ; Buffer for data from port. db 2 DUP (?) ; guard for source. srcpnt dw 0 ; Pointer in buffer (DI). count dw 0 ; Number of chars in int buffer. rcvpnt dw 0 ; Save SI register here. mdmhand db 0 ; modem status register, current ; buffer for network xmtbuf db NETBUFLEN DUP (0) ; Buffer for Network xfer. db 2 DUP (0) ; guard xmtpnt dw 0 xmtcnt dw 0 ; Function key definition tables ker_keydef db 0FEh,'f 01 ',0FFh,062h, 8 dup (0) ; f 1 db 0FEh,'f 02 ',0FFh,063h, 8 dup (0) ; f 2 db 0FEh,'f 03 ',0FFh,064h, 8 dup (0) ; f 3 db 0FEh,'f 04 ',0FFh,065h, 8 dup (0) ; f 4 db 0FEh,'f 05 ',0FFh,066h, 8 dup (0) ; f 5 db 0FEh,'f 06 ',0FFh,067h, 8 dup (0) ; f 6 db 0FEh,'f 07 ',0FFh,068h, 8 dup (0) ; f 7 db 0FEh,'f 08 ',0FFh,069h, 8 dup (0) ; f 8 db 0FEh,'f 09 ',0FFh,06Ah, 8 dup (0) ; f 9 db 0FEh,'f 10 ',0FFh,06Bh, 8 dup (0) ; f10 db 0FEh,'F 01 ',0FFh,082h, 8 dup (0) ; shift f 1 db 0FEh,'F 02 ',0FFh,083h, 8 dup (0) ; shift f 2 db 0FEh,'F 03 ',0FFh,084h, 8 dup (0) ; shift f 3 db 0FEh,'F 04 ',0FFh,085h, 8 dup (0) ; shift f 4 db 0FEh,'F 05 ',0FFh,086h, 8 dup (0) ; shift f 5 db 0FEh,'F 06 ',0FFh,087h, 8 dup (0) ; shift f 6 db 0FEh,'F 07 ',0FFh,088h, 8 dup (0) ; shift f 7 db 0FEh,'F 08 ',0FFh,089h, 8 dup (0) ; shift f 8 db 0FEh,'F 09 ',0FFh,08Ah, 8 dup (0) ; shift f 9 db 0FEh,'F 10 ',0FFh,08Bh, 8 dup (0) ; shift f10 db 0FFh,036h, 4 dup (0) ; ROLL UP db 0FFh,037h, 4 dup (0) ; ROLL DOWN db 0FFh,038h, 4 dup (0) ; INS db 0FFh,039h, 4 dup (0) ; DEL db 0FFh,03Ah, 4 dup (0) ; up arrow db 0FFh,03Bh, 4 dup (0) ; left arrow db 0FFh,03Ch, 4 dup (0) ; right arrow db 0FFh,03Dh, 4 dup (0) ; down arrow db 0FFh,03Eh, 4 dup (0) ; HOME CLR db 0FFh,03Fh, 4 dup (0) ; HELP db 0FFh,0AEh, 4 dup (0) ; shift HOME CLR KEYDEF_SIZE = $ - ker_keydef + 2 DOS_keydef db KEYDEF_SIZE dup (?) ; even dw 80 DUP (?) ; local stack for interrupt processing mnstk dw ? mnsp dw ? ; remote stack info mnsseg dw ? baud_set db ? scrn_page db 0 ; mode line buffer mode_len db 0 db 'Esc-chr: ' mode_esc db '^]' db ' help: ' mode_hlp db '^]' db '? port:' mode_prt db '1' db ' speed:' mode_spd db ' ' db ' parity:' mode_pty db 'none' db ' echo:' mode_ech db 'rem' db ' ' mode_typ db 'VT102 ' db ' ' mode_prn db ' ' MODE_LINE_LENG = $ - mode_len - 1 onmsg db 'off' db 'on ' colmsg db 'black ' db 'blue ' db 'red ' db 'magenta' db 'green ' db 'cyan ' db 'yellow ' db 'white ' knjmsg db 'none ' db 'none ' db 'DEC-code ' db 'DEC-code ' db 'shift-JIS' db 'shift-JIS' keyinmsg db 'direct' db 'CON ' vstmsg db '<Terminal status>',cr,lf db ' Keyclick: ' vstmsg_key db ' ' db ' Keyinput: ' vstmsg_keyin db ' ' db ' Color: ' vstmsg_col db ' ' db ' Highlight: ' vstmsg_high db ' ' db cr,lf,' Kanji-send : ' vstmsg_sknj db ' ' db ' Kanji-receive : ' vstmsg_rknj db ' ' db cr,lf,' AutoTek: ' vstmsg_autot db ' ' db ' Wrap: ' vstmsg_autow db ' ' db '$' datas ends code segment public 'code' extrn comnd:near, dopar:near, prserr:near, atoi:near, prompt:near extrn isfile:near ;* in mssker extrn sleep:near, msuinit:near, keybd:near extrn vt100:near, vt100_ini:near extrn vt100_save:near, vt100_restore:near, vt100_modlin:near extrn vt100_dump:near, vt100_color:near extrn tek4014:near, tek4014_ini:near extrn tek4014_save:near, tek4014_restore:near, tek4014_modlin:near assume cs:code,ds:datas ;----------------- ; Utility Package ;----------------- NOUT PROC NEAR ; Copy numeric value from AX to ASCII buffer indicated by DI. ; DI is updated. mov dx,0 mov bx,10 div bx push dx ; save remainder digit or ax,ax ; anything left? jz nout1 ; no, start output phase call nout nout1: pop ax ; retrieve a digit add al,'0' ; make it ASCII stosb ; put it in buffer ret NOUT ENDP ;------------------- is_kanji1 proc near ; ; Check if al is Kanji 1st byte (stc) or not (clc) ; cmp al,81h jb is_kanji1_no cmp al,0FCh ja is_kanji1_no cmp al,9fh jbe is_kanji1_yes cmp al,0E0h jae is_kanji1_yes is_kanji1_no: clc ret is_kanji1_yes: stc ret is_kanji1 endp ;------------------- jis2s proc near ; ; Convert JIS Kanji code in AX to shift-JIS Kanji code ; ah 2nd byte ; al 1st byte ; test al,1 jz jis2s1 add ah,1Fh jmp jis2s2 jis2s1: add ah,7Dh jis2s2: cmp ah,7Fh jb jis2s3 add ah,1 jis2s3: sub al,21h shr al,1 add al,81h cmp al,9Fh jbe jis2s4 add al,40h jis2s4: ret jis2s endp ;------------------- s2jis proc near ; ; Convert Shift JIS Kanji code in AX to JIS Kanji code ; ah 2nd byte ; al 1st byte ; cmp al,9Fh ja s2jis1 sub al,71h jmp s2jis2 s2jis1: sub al,0B1h s2jis2: shl al,1 inc al cmp ah,7Fh jbe s2jis3 dec ah s2jis3: cmp ah,9Eh jb s2jis4 sub ah,7Dh inc al jmp s2jis5 s2jis4: sub ah,1Fh s2jis5: ret s2jis endp set_keydef proc near ; Save MS-DOS key definition table and set new key definition table. ; This is done by calling NEC-PC98 extended bios. push ax push cx push dx mov dx,offset DOS_keydef mov ax,0 mov cl,0Ch int 0DCh mov dx,offset ker_keydef mov ax,0 mov cl,0Dh int 0DCh pop dx pop cx pop ax ret set_keydef endp reset_keydef proc near ; Restore MS-DOS key definition table push ax push cx push dx mov dx,offset DOS_keydef mov ax,0 mov cl,0Dh int 0DCh pop dx pop cx pop ax ret reset_keydef endp SCRN_CHK PROC NEAR ; Check the display screen. If it is not DOS page, save the current page ; and return to DOS page. cmp scrn_page,1 ; VT100 page ? jne scrn_chk1 ; ne = no. call vt100_save jmp scrn_chkx scrn_chk1: cmp scrn_page,2 ; TEK page ? jne scrn_chk2 ; ne = no. call tek4014_save jmp scrn_chkx scrn_chk2: jmp scrn_chk_ex scrn_chkx: push ax push dx mov ah,prstr mov dx,offset restore_cur int dos pop dx pop ax scrn_chk_ex: mov scrn_page,0 ; force to DOS page ret SCRN_CHK ENDP SET_MODLIN PROC NEAR ; set the mode line buffer ; push es mov ax,ds mov es,ax ; mov al,' ' mov ah,trans.escchr cmp ah,020h jge set_modlin1 mov al,'^' or ah,040h set_modlin1: mov word ptr mode_esc,ax mov word ptr mode_hlp,ax ; mov al,ourarg.baudb mov si,offset unkbaud ; Assume unknown baud. mov cx,5 ; length of baud space cmp al,BAUDNSIZ ; too big? jnb set_modlin2 ; yes, use default mul cl xor ah,ah add ax,offset baudname mov si,ax set_modlin2: mov di,offset mode_spd rep movsb ; mov al,ourarg.prt cmp al,'N' je set_modlin3 add al,'0' ; convert to character set_modlin3: mov mode_prt,al ; mov al,ourarg.parity xor ah,ah mov cx,4 imul cl add ax,offset parityname mov si,ax mov di,offset mode_pty rep movsb ; mov si,offset lclename test ourarg.flgs,lclecho jnz set_modlin4 mov si,offset remename set_modlin4: mov cx,3 mov di,offset mode_ech rep movsb ; pop es ret SET_MODLIN ENDP ENT_VT PROC NEAR cmp scrn_page,1 ; VT screen ? je ent_vt1 ; e = yes. terminal screen. keep going push ax push dx mov ah,prstr mov dx,offset save_cur int dos mov ah,prstr mov dx,offset home_cur int dos pop dx pop ax call vt100_restore mov scrn_page,1 ent_vt1: mov dx,offset mode_len call vt100_modlin ret ENT_VT ENDP ENT_TK PROC NEAR cmp scrn_page,2 ; TEK screen ? je ent_tk1 push ax push dx mov ah,prstr mov dx,offset save_cur int dos mov ah,prstr mov dx,offset home_cur int dos pop dx pop ax call tek4014_restore mov scrn_page,2 ent_tk1: mov dx,offset mode_len call tek4014_modlin ret ENT_TK 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 mov ah,gcurdsk ; Current disk value to AL. int dos mov dl,al ; Put current disk in DL. mov ah,seldsk ; Select current disk. int dos ; Get number of drives in AL. mov drives,al ret DODISK ENDP ; Clear the input buffer. This throws away all the characters in the ; serial interrupt buffer. This is particularly important when ; talking to servers, since NAKs can accumulate in the buffer. CLRBUF PROC NEAR cli mov srcpnt,offset source ; receive circular buffer mov count,0 sti call prtchr ; empty any intermediate buffers nop ; got a char, clear again nop nop cli push ax mov ax,offset source ; reset pointers mov rcvpnt,ax mov srcpnt,ax mov count,0 pop ax sti ret CLRBUF ENDP ; Clear to the end of the current line. Returns normally. CLEARL PROC NEAR push ax push dx call scrn_chk mov ah,prstr mov dx,offset clreol int dos pop dx pop ax ret CLEARL ENDP shomodem proc near mov ah,cmcfm ; get a confirm call comnd jmp r ; no confirm nop call serini ; activate port to get status call serrst ; turn off port again ; mov dx,mnst1a ; read status in al,dx and al,80h ; set only DR bit mov mdstreg,al mov dx,mnrdsa ; read signal in al,dx and al,60h ; set CS and CD only or mdstreg,al ; mov ah,prstr mov dx,offset msmsg1 ; modem ready msg test mdstreg,80h ; is DSR asserted? jz shomd1 ; z = no mov dx,offset msmsg2 ; say not asserted shomd1: int dos mov dx,offset msmsg3 ; CD asserted msg test mdstreg,20h ; CD asserted? jz shomd2 ; z = no mov dx,offset msmsg4 ; say not asserted shomd2: int dos mov dx,offset msmsg5 ; CTS asserted msg test mdstreg,40h ; CTS asserted? jz shomd3 ; z = no mov dx,offset msmsg6 ; say not asserted shomd3: int dos jmp rskp 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 ; save regs cmp flowoff,0 ; Are we doing flow control. je outch2 xor cx,cx 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. xor cx,cx mov al,ah ; Parity routine works on AL. call dopar ; Set parity appropriately. ; Begin revised output routine mov ah,al mov temp,ax ; put data there cmp ourarg.prt,'N' ; Network port ? jne outch6 ; ne = No. pop dx pop cx jmp outchn outch6: mov dx,modem.mdstat outch3: in al,dx test al,txrdy jnz outch4 loop outch3 jmp outch5 outch4: mov al,ah mov dx,modem.mddat out dx,al outch5: pop dx pop cx jmp rskp ; outchn: push bx mov bx,offset xmtbuf ; set xfer address add bx,xmtcnt ; count of chars in buffer mov [bx],ah ; put char in buffer pop bx inc xmtcnt ; count of items in this buffer cmp xmtcnt,NETBUFLEN ; is buffer full now? jae outchn1 ; ae = buffer is full, send it now. cmp ah,trans.seol ; end of packet? je outchn1 ; e = yes, send buffer. cmp ah,flowon ; flow control? je outchn1 ; e = yes, always expedite cmp ah,flowoff ; ditto for flow off je outchn1 cmp ttyact,0 ; are we in Connect mode? je outchn2 ; e = no, wait for more before sending outchn1: call send ; network send routine jc outchn3 ; c = error outchn2: jmp rskp ; good exit outchn3: ret ; bad exit OUTCHR ENDP SEND PROC NEAR push ax push bx push cx push es ; push ds pop es ; ES = DS mov bx,offset xmtbuf ; xfer start address mov ah,NETCI_WRITE ; set function mov al,NETCI_PORT ; set port ; send0: mov cx,xmtcnt ; packet length jcxz send1 int NETCI_INT ; send packet cmp cx,xmtcnt ; all done ? jae send1 ; e = yes. pop ax mov bx,offset xmtbuf add bx,cx ; update xfer address sub xmtcnt,cx jmp send0 ; send1: mov xmtcnt,0 pop es pop cx pop bx pop ax clc ret SEND ENDP ; This routine blanks the screen. Returns normally. CMBLNK PROC NEAR push ax ; save some registers push dx call scrn_chk mov ah,prstr mov dx,offset delscr ; delete screen. int dos pop dx pop ax ret CMBLNK ENDP ; Homes the cursor. Returns normally. LOCATE PROC NEAR call scrn_chk mov dx,0 ; Go to top left corner of screen. jmp poscur LOCATE ENDP ; Write a line at the bottom of the screen... ; the line is passed in dx, terminated by a $. Returns normally. putmod proc near call scrn_chk push dx ; preserve message mov dx,1800h ; now address line 24 call poscur pop dx ; get message back mov ah,prstr int dos ; write it out ret ; and return putmod endp ; clear the mode line written by putmod. Returns normally. clrmod proc near call scrn_chk mov dx,1800h call poscur ; Go to bottom row. call clearl ; Clear to end of line. ret clrmod endp ; Put a help message on the screen. ; Pass the message in ax, terminated by a null. Returns normally. puthlp proc near push dx ; save regs push si push ax ; preserve this call scrn_chk call cmblnk call locate mov ah,prstr mov dx,offset crlf int dos pop si ; point to string again cld puthl3: lodsb ; get a byte cmp al,0 ; end of string? je puthl4 ; yes, stop mov dl,al mov ah,dconio int dos ; else write to screen jmp puthl3 ; and keep going puthl4: mov ah,prstr mov dx,offset crlf int dos pop si pop dx ret puthlp endp ; Set the baud rate for the current port, based on the value ; in the portinfo structure. Returns normally. DOBAUD PROC NEAR push ax push bx push dx ; mov axsave,ax mov bx,portval mov ax,[bx].baud shl ax,1 ; ; determine CPU clock ; push ax in al,042h test al,0C0h jz c5mhz test al,020h jz c5mhz c8mhz: mov bx,offset bddat8 jmp dobd0 c5mhz: mov bx,offset bddat5 dobd0: pop ax add bx,ax cmp word ptr [bx],0FFFFh jne dobd1 mov ah,prstr mov dx,offset badbd int dos jmp dobd_ex dobd1: mov dx,timer.tmcmd mov al,timer.tmsel out dx,al mov ax,[bx] mov dx,timer.tmdat out dx,al mov al,ah out dx,al dobd_ex: pop dx pop bx pop ax ret ; Must be set before starting Kermit. 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 is used during initialization. GETBAUD PROC NEAR cmp flags.comflg,'N' ; Network ? je gbaud1 ; e = yes. do nothing here. push bx cmp baud_set,1 ; Did we already set baud rate? je gbaud0 ; yes, so just leave mov bx,portval mov [bx].baud,B9600 mov baud_set,1 gbaud0: pop bx gbaud1: ret GETBAUD ENDP ; Set the mode for the current port. This is part of the serial ; initialization routine. DOMODE PROC NEAR push ax push cx push dx ; mov dx,modem.mdcom ;send 3 zeros to command port to reset chip mov al,0 out dx,al mov al,0 out dx,al mov al,0 out dx,al mov al,cmode ;enable mode setting out dx,al mov cx,100 ;allow chip time to reset mode1: loop mode1 mov al,mmode ;mode: 16x rate, 8 data, no parity, 1 stop out dx,al mov cx,100 mode2: loop mode2 mov al,ccmd ;RTS & DTR high, RX & TX enabled, reset errors out dx,al ; pop dx pop cx pop ax ret DOMODE ENDP ; Use for DOS 2.0 and above. Check the port status. If no data, skip ; return. Else, read in a char and return. ; Note added by [jrd]: The test for char-at-input-port is int 21h function ; 44h (ioctl) sub function 6 (get input status). On many systems an FFH will ; be reported (meaning Ready) even though no char is available; the Ready ; indication is misleading. In such cases the system will wait for a char ; and will appear to be hung. A preferrable method is to use the ROM Bios ; call int 14H function 3 (get port status) and if the lsb of the returned ; 8 bits in AH is 1 then a char is availble at the port; this assumes that ; the machine emulates this ROM Bios operation. ; Lastly, if the current code is used and the system hangs then reboot ; and say ECHO Hello >COM1 before running Kermit; this should make MSDOS ; truely aware of the port's actual status. Dark grey magic. Good luck! [jrd] PRTCHR PROC NEAR prtch0: call chkxon cmp ourarg.prt,'N' jne prtch3 jmp prtchn prtch3: cmp count,0 jnz prtch2 jmp rskp ; No data -check console prtch2: pushf cli ; disable interrupts while manipulating pointers mov si,rcvpnt 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 rcvpnt,si mov dx,count popf ret prtchn: cmp count,0 ; Data in buffer? je prtchn0 ; e = No. Get them from port. jmp prtchn2 prtchn0: push ax push bx push cx push es mov ax,offset source mov rcvpnt,ax mov srcpnt,ax ; mov ah,NETCI_READ mov al,NETCI_PORT mov bx,offset source mov cx,bufsiz push ds pop es int NETCI_INT mov count,cx add srcpnt,cx pop es pop cx pop bx pop ax cmp count,0 jnz prtchn2 jmp rskp prtchn2: pushf cli ; disable interrupts while manipulating pointers mov si,rcvpnt lodsb ; get a byte dec count mov rcvpnt,si ; ; I'm not sure the floowings are necesary or not. ; The handshake should be done at network level. ; ; check the data ; ;@@ push bx ;@@ or al,al ;@@ jz prtchn5 ; Ignore nulls. ;@@ mov ah,al ; copy the character in AH ;@@ and ah,parmsk ; apply parity mask ;@@ mov bx,portval ;@@ cmp [bx].floflg,0 ; Doing flow control? ;@@ je prtchn4 ; Nope. ;@@ mov bx,[bx].flowc ; Flow control character (BH=XON, BL=XOFF). ;@@ cmp ah,bl ; Is it an XOFF? ;@@ jne prtchn3 ; Nope, go on. ;@@ mov xofrcv,true ; Set the flag. ;@@ jmp short prtchn5 prtchn3: ;@@ cmp ah,bh ; Get an XON? ;@@ jne prtchn4 ; No, go on. ;@@ mov xofrcv,false ; Clear our flag. ;@@ jmp short prtchn5 ; prtchn4: ;@@ pop bx mov dx,count popf ret prtchn5: ;@@ pop bx ;@@ popf ;@@ jmp prtchn 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 or ah,ah ; don't send null if flow = none jz ihosts1 ; z = null call outchr ; send it (release Host's output queue) nop ; outchr can do skip return nop nop ihosts1:call clrbuf ; clear out interrupt buffer mov ax,1 ; sleep for 1 second ; NOTE: for systems with a time-of-day clock uncomment the line below ; (call sleep) to provide an interval for the host to respond. ;;; 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 or ah,ah ; don't send null if flow = null jz ihostr1 ; z = null call outchr ; send it (release Host's output queue) nop ; outchr can do skip return nop nop ihostr1:pop cx pop bx pop ax ret IHOSTR ENDP DTRLOW PROC NEAR ; Global proc to Hangup the Phone by making ; DTR and RTS low. mov ah,cmtxt ; allow text to be able to display help mov bx,offset rdbuf ; dummy buffer mov dx,offset hnghlp ; help message call comnd ; get a confirm jmp r ; not yet imp. call serhng ; drop DTR and RTS mov ah,prstr ; give a nice message ; not yet imp. mov dx,offset hngmsg mov dx,offset noimp ; for now int dos jmp rskp DTRLOW ENDP ; Hang up the Phone. Similar to SERRST except it just forces DTR and RTS low ; to terminate the connection. 29 March 1986 [jrd] ; Calling this twice without intervening calls to serini should be harmless. ; Returns normally. ; SERHNG is Not Yet Implemented. SERHNG PROC NEAR ret SERHNG ENDP ; Wait for the # of milliseconds in ax, for non-IBM compatibles. ; Based on 4.77 Mhz 8088 processor speeds. ; 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 ; Send a break out the current serial port. Returns normally. SENDBR PROC NEAR ; Normal Break mov dx,modem.mdcom ; set command port mov al,cbrk+ccmd ; add break to normal command out dx,al sub cx,cx ; counter 0 = 65536 sndbr1: loop sndbr1 ; wait a while mov al,ccmd ; restore normal command out dx,al ret SENDBR ENDP SENDBL PROC NEAR ; Long Break mov dx,modem.mdcom ; set command port mov al,cbrk+ccmd ; add break to normal command out dx,al push dx ; save I/O address call pcwait mov al,ccmd pop dx ; restore I/O address out dx,al ; restore normal command ret SENDBL ENDP ; Position the cursor according to contents of DX: ; DH contains row, DL contains column. Returns normally. POSCUR PROC NEAR push di mov di,offset tmpbuf mov byte ptr [di],ESCAPE mov byte ptr [di+1],'[' add di,2 mov al,dh xor ah,ah inc ax push dx call nout mov byte ptr [di],';' inc di pop dx mov al,dl xor ah,ah inc ax call nout mov byte ptr [di],'H' mov byte ptr [di+1],'$' mov dx,offset tmpbuf mov ah,prstr int dos pop di 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 ; Called only when Kermit exits. Program pointer passed to mssker by ; proc chknet in word 'lclexit'. ; This is used as a local end routine. NETCLOSE PROC NEAR cmp pcnet,0 ; already closed ? je netclo1 ; e = yes push ax mov ah,NETCI_CLOSE mov al,NETCI_PORT int NETCI_INT mov pcnet,0 pop ax netclo1: call reset_keydef ; reset key definition table ret NETCLOSE ENDP ; Open NETCI port chknet proc near cmp pcnet,0 ; netport is closed ? jne chknetx push ax push bx push cx push es ; push cs pop es mov temp,0 mov bx,offset temp mov cx,0 mov ah,NETCI_OPEN mov al,NETCI_PORT int NETCI_INT mov lclexit,offset netclose call clrbuf mov xmtcnt,0 mov pcnet,2 ; pop es pop cx pop bx pop ax chknetx: clc ret chknet endp ; ; Set the current port. ; COMS PROC NEAR mov dx,offset comptab ; the table to examine mov bx,0 ; use keywords as help mov ah,cmkey ; parse keyword from comptab call comnd jmp r ; no match cmp bl,'N' ; Network ? jne coms1 ; ne = no jmp comsn ; Yes, setup for networks coms1: mov temp,bx mov ah,cmcfm call comnd ; Get a confirm. jmp r ; Didn't get a confirm. mov bx,temp ; get port number/letter mov flags.comflg,bl ; remember port number xor bh,bh ; clear high byte mov bl,flags.comflg ; get COMx number (1-3) push bx pop bx mov ax,offset port1 mov portval,ax call inita clc ret comsn: mov temp,bx mov ah,cmcfm call comnd ; Get a confirm jmp r ; Didn't get a confirm nop call serrst ; reset serial port call chknet ; start network usage cmp pcnet,0 ; is network alive (non-zero)? jne comsn4 ; ne = yes stc ret ; return failure comsn4: mov portval,offset portn ; set netowrk port data mov flags.comflg,'N' ; set the comm port flag. clc ; return sucess ret COMS ENDP ; Set heath emulation on/off. VTS PROC NEAR 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 bh,1h ; marker for terminal type? jne vsetup_n1 ; ne = no jmp vsetup_1 vsetup_n1: cmp bh,2h ; marker for set term something on/off? jne vsetup_n2 ; ne = no jmp vsetup_2 vsetup_n2: cmp bh,3h ; marker for color jne vsetup_n3 ; ne = no jmp vsetup_3 vsetup_n3: cmp bh,4h ; marker for kanji jne vsetup_n4 ; ne = no jmp vsetup_4 vsetup_n4: cmp bh,5 jne vsetup_n5 jmp vsetup_5 vsetup_n5: jmp vsetup_ex ; vsetup_1: push bx mov ah,cmcfm call comnd jmp vsetup_ex2 nop pop bx mov flags.vtflg,bl ; Set the terminal emulation type ret vsetup_2: xor bh,bh mov param_dst,bx mov ah,cmkey mov bx,0 mov dx,offset ontab call comnd jmp r ; bad keyword push bx mov ah,cmcfm ; get a confirm call comnd jmp vsetup_ex2 ; did not get a confirm nop mov ax,param_dst pop bx cmp bl,0 jne vsetup_2_1 not al and vt100_flags,al jmp vsetup_2_2 vsetup_2_1: or vt100_flags,al vsetup_2_2: jmp rskp vsetup_3: mov dx,offset scn_color xor bh,bh add dx,bx mov param_dst,dx mov ah,cmkey mov bx,0 mov dx,offset colortab call comnd jmp r ; bad keyword push bx mov ah,cmcfm ; get a confirm call comnd jmp vsetup_ex2 ; did not get a confirm nop pop dx ; get old bx value to dx mov bx,param_dst mov byte ptr [bx],dl mov ax,scn_color call vt100_color jmp rskp vsetup_4: mov ah,cmkey mov bx,0 mov dx,offset kanjitab call comnd jmp r ; bad keyword push bx mov ah,cmcfm ; get a confirm call comnd jmp vsetup_ex2 ; did not get a confirm nop pop bx ; get old bx value to dx mov kanji_scode,bl mov kanji_rcode,bl jmp rskp vsetup_5: mov ah,cmkey mov bx,0 mov dx,offset keyintab call comnd jmp r push bx mov ah,cmcfm call comnd jmp vsetup_ex2 nop pop bx mov keyin_dos,bl jmp rskp vsetup_ex: jmp rskp vsetup_ex2: pop bx ret VTS ENDP VTSTAT PROC NEAR ; For Status display [jrd] push ax push bx push cx push dx push si push di push es ; push ds pop es cld mov si,offset onmsg mov cx,3 test vt100_flags,KEYCLICK_BIT jz vtstat1 add si,cx vtstat1: mov di,offset vstmsg_key rep movsb mov si,offset onmsg mov cx,3 test vt100_flags,AUTOTEK_BIT jz vtstat2 add si,cx vtstat2: mov di,offset vstmsg_autot rep movsb mov si,offset onmsg mov cx,3 test vt100_flags,AUTOWRAP_BIT jz vtstat3 add si,cx vtstat3: mov di,offset vstmsg_autow rep movsb mov si,offset colmsg mov ax,scn_color mov ah,0 mov cx,7 imul cl add si,ax mov di,offset vstmsg_col rep movsb mov si,offset colmsg mov ax,scn_color xchg ah,al mov ah,0 mov cx,7 imul cl add si,ax mov di,offset vstmsg_high rep movsb mov si,offset knjmsg mov ah,0 mov al,kanji_scode mov cx,9 imul cl add si,ax mov di,offset vstmsg_sknj rep movsb mov si,offset knjmsg mov ah,0 mov al,kanji_rcode mov cx,9 imul cl add si,ax mov di,offset vstmsg_rknj rep movsb mov si,offset keyinmsg mov cx,6 cmp keyin_dos,0 je vtstat9 add si,cx vtstat9: mov di,offset vstmsg_keyin rep movsb mov ah,prstr mov dx,offset vstmsg int dos ; pop es pop di pop si pop dx pop cx pop bx pop ax ret ; no emulator status to display VTSTAT ENDP ; Save the screen to a buffer and then append buffer to a disk file. [jrd] ; Default filename is Kermit.scn; actual file can be a device too. Filename ; is determined by mssset and is passed as pointer dmpname. DUMPSCR PROC NEAR ; Dumps screen contents to a file. Just Beeps here push ax push bx push cx push dx mov dmphand,-1 ; preset illegal handle mov dx,offset dmpname ; name of disk file, from mssset mov ax,dx ; where isfile wants name ptr call isfile ; what kind of file is this? jc dmp5 ; c = no such file, create it test byte ptr filtst.dta+21,1fh ; file attributes, ok to write? jnz dmp0 ; nz = no. mov al,1 ; writing mov ah,open2 ; open existing file int dos jc dmp0 ; c = failure mov dmphand,ax ; save file handle mov bx,ax ; need handle here mov cx,0ffffh ; setup file pointer mov dx,-1 ; and offset mov al,2 ; move to eof minus one byte mov ah,lseek ; seek the end int dos jmp dmp1 dmp5: test filtst.fstat,80h ; access problem? jnz dmp0 ; nz = yes mov ah,creat2 ; file did not exist mov cx,20h ; attributes, archive bit int dos mov dmphand,ax ; save file handle jnc dmp1 ; nc = ok dmp0: call beep pop dx pop cx pop bx pop ax clc ret dmp1: mov ah,ioctl ; is destination ready for output? mov al,7 ; test output status mov bx,dmphand ; handle int dos jc dmp0 ; c = error cmp al,0ffh ; ready? jne dmp0 ; ne = not ready. ; test flags.vtflg,ttvt100 jz dmp_v1 call ent_vt dmp_v1: mov bx,dmphand ; need file handle call vt100_dump ; mov bx,offset tmpbuf mov byte ptr [bx],CTLZ ; put EOF mark mov dx,bx mov bx,dmphand mov cx,1 mov ah,write2 int dos ; write EOF ; mov ah,close2 ; close the file now int dos ; pop dx pop cx pop bx pop ax clc ret DUMPSCR ENDP notimp: mov ah,prstr mov dx,offset noimp int dos jmp prserr ; Initialize variables to values used by this routine. lclini: mov prthnd,0 ; No handle yet mov flags.comflg,1 ; Communication port 1 mov scrn_page,0 ; start page is DOS screen mov curkey_mode,0 ; cursor key is ANSI normal mov keypad_mode,0 ; keypad is normal mov vt100_flags,AUTOTEK_BIT+CURSOR_BIT+BLINK_BIT ; set flags mov kanji_scode,2 ; DEC kanji code mov kanji_rcode,2 mov kanji_smode,0 ; 1st character must be Kanji 1st byte. mov kanji_rmode,0 mov xmtcnt,0 ; clear counter for xfer or flags.remflg,d8bit ; display 8-bit call set_keydef mov lclexit,offset netclose call msuinit ; declare keyboard translator present call vt100_ini call tek4014_ini ret showkey: mov ax,offset shkmsg mov cx,shklen ret ; serial port interrupt routine. This is not accessible outside this ; module, handles serial port receiver interrupts. SERINT PROC NEAR push ds ; save these on remote stack push ax mov ax,seg datas ; get our own data segment mov ds,ax mov mnsp,sp ; save remote stack information mov mnsseg,ss mov sp,offset mnstk ; switch to local stack mov ss,ax push es ; and save remaining registers push bp push di push si push dx push cx push bx mov es,ax call mnproc ; process the interrupt mov al,icEOI mov dx,intcmda out dx,al pop bx ; restore registers from stack pop cx pop dx pop si pop di pop bp pop es mov ax,mnsseg ; switch back to remote stack mov ss,ax mov ax,mnsp mov sp,ax pop ax pop ds iret ; handler for serial input mnproc: cld mov di,srcpnt ; get buffer pointer mov dx,modem.mdstat ; is data available? in al,dx test al,rxrdy jz mnpro7 mov dx,modem.mddat ; read data in al,dx or al,al jz mnpro7 ; Ignore nulls. ; do NOT ignore rubouts, because TEK LOY code use this. ; cmp al,7FH ; Ignore rubouts, too. ; jz mnpro7 mov ah,al ; ; originally the following was ; ; and ah,7fH ; only consider low-order 7 bits for flow ctl. ; do NOT mask 8-th bit for flow control when parity is none. ; and ah,parmsk ; apply parity mask for flow ctl. mov bp,portval cmp ds:[bp].floflg,0 ; Doing flow control? je mnpro4 ; Nope. mov bx,ds:[bp].flowc ; Flow control char (BH = XON, BL = XOFF). cmp ah,bl ; Is it an XOFF? jne mnpro3 ; Nope, go on. mov xofrcv,true ; Set the flag. jmp short mnpro7 mnpro3: cmp ah,bh ; Get an XON? jne mnpro4 ; No, go on. mov xofrcv,false ; Clear our flag. jmp mnpro7 mnpro4: stosb cmp di,offset source + bufsiz jb mnpro5 ; not past end... mov di,offset source ; wrap buffer around mnpro5: mov srcpnt,di ; update ptr inc count cmp ds:[bp].floflg,0 ; Doing flow control? je mnpro7 ; No, just leave. cmp xofsnt,true ; Have we sent an XOFF? je mnpro7 ; Yes. cmp count,mntrgh ; Past the high trigger point? jbe mnpro7 ; No, we're within our limit. mov ah,bl ; Get the XOFF. call outchr ; Send it. nop ; ignore failure. nop nop mov xofsnt,true ; Remember we sent it. mnpro7: ret SERINT ENDP ; Initialization for using serial port. Returns normally. SERINI PROC NEAR cmp flags.comflg,'N' ;@@@@@ je serin1 ;@@@@@ call inita serin0:;;;; call clrbuf ; Clear input buffer. ;; push bx ;; mov bx,portval ; get port ;; mov parmsk,0ffh ; parity mask, assume parity is None ;; cmp [bx].parflg,parnon ; is it None? ;; je serin1 ; e = yes ;; mov parmsk,07fh ; no, pass lower 7 bits as data ;;serin1: mov bx,[bx].flowc ; get flow control chars ;; mov flowoff,bl ; xoff or null ;; mov flowon,bh ; xon or null ;; pop bx serin1: ret ; We're done. SERINI ENDP ; Reset the serial port. This is the opposite of serini. Calling ; this twice without intervening calls to serini should be harmless. ; Returns normally. SERRST PROC NEAR call scrn_chk cmp portinia,0 ; Did we reset port already? je rsta0 ; Yes, so just leave. push es cli ; Disable interrupts xor ax,ax ; Address low memory mov es,ax mov ax,oldsera_ofs ; Restore interrupt vector mov es:[4*icsvcta],ax mov ax,oldsera_sgm mov es:[4*icsvcta+2],ax mov dx,intmska ; restore old master controller mask mov al,oldmska out dx,al mov dx,mnmska ; disable serial interrupts at port ; mov al,txmsk+rxmsk+tbemsk mov al,oldmsdat out dx,al mov portinia,0 ; Remember port has been reset sti ; Allow interrupts pop es rsta0: ret SERRST ENDP ; Local routine to initialize the standard serial port INITA PROC NEAR cmp portinia,1 ; Did we initialize port already ? je inita0 ; Yes, so just leave. ; cli ; Disable interrupts push ax push dx push es ; mov ax,offset port1 mov portval,ax xor ax,ax mov es,ax mov ax,es:[4*icsvcta] ; save interrupt vector for port1 mov oldsera_ofs,ax mov ax,es:[4*icsvcta+2] mov oldsera_sgm,ax mov ax,offset serint ; pointer to our routine mov es:[4*icsvcta],ax ; set interrupt routine offset mov es:[4*icsvcta+2],cs ; and segment mov dx,intmska in al,dx mov oldmska,al ; save old master controller mask ; and al,not icsmska ; enable serial interrupt at master out dx,al mov dx,mnmska in al,dx mov oldmsdat,al and al,0f8h or al,rxmsk out dx,al mov modem.mddat,mndata mov modem.mdstat,mnst1a mov modem.mdcom,mncmda mov timer.tmdat,tmdata mov timer.tmcmd,tmcmda mov timer.tmsel,tmsela call domode call dobaud mov portinia,1 call clrbuf ; pop es pop dx pop ax sti inita0: ret INITA ENDP ; ; Produce a short beep. The PC DOS bell is long enough to cause a loss ; of data at the port. Returns normally. BEEP PROC NEAR mov dl,bell mov ah,dconio int dos ret BEEP ENDP ; ; Dumb terminal emulator. Doesn't work too well above 1200 baud (and ; even at 1200 baud you sometimes lose the first one or two characters ; on a line). Does capture (logging), local echo, debug display, tests ; for printer/logging device not ready. Uses keyboard translator ; 20 March 1987 [jrd]. term proc near mov kanji_smode,0 ; clear Kanji pending flag mov kanji_rmode,0 mov argadr,ax ; save argument ptr mov si,ax ; this is source mov di,offset ourarg ; place to store arguments mov ax,ds mov es,ax ; address destination segment mov cx,size termarg cld rep movsb ; copy into our arg blk and ourarg.flgs,not (prtscr) ; no screen printing at startup mov ax,ourarg.captr mov captrtn,ax ; buffer capture routine mov mode_len,0 mov ax,1001h test vt100_flags,BLINK_BIT jz term_01 mov ax,1000h term_01: int bios test vt100_flags,CURSOR_BIT jz term_02 mov ax,1100h int bios term_02: test ourarg.flgs,modoff ; mode line off? jnz term_1 call set_modlin ; setup mode line mov mode_len,MODE_LINE_LENG term_1: mov parmsk,0ffh ; parity mask, assume parity = None cmp ourarg.parity,parnon ; is parity None? je term_2 ; e = yes, keep all 8 bits mov parmsk,07fh ; else keep lower 7 bits term_2: cmp flags.vtflg,ttvt100 ; vt100 emulation ? je term_vt ; e = yes. cmp flags.vtflg,tttek ; Tek4014 emulation ? je term_tk ; e = yes. jmp term0 ; non supported terminal ; ; vt100 emulation term_vt: call ent_vt jmp term0 ; ; tek4014 emulation term_tk: call ent_tk ; term0: test vt100_flags,LOOPTEST_BIT je term1 jmp term_tst1 term1: call portchr ; get char from port, apply parity mask jnc short term2 ; nc = no char, go on call outtty ; display and capture char jmp term1 ; do quick loop back for more term2: call keybd ; keyboard translator to read and send text jnc term1 ; nc = do not exit Connect mode ret term_tst1: mov ax,3D00h ; open file (read only) mov dx,offset test_fnam int dos jc term_tstz ; if error, then normal operation mov test_hndl,ax term_tst2: call portchr jnc short term_tst3 call outtty jmp term_tst2 term_tst3: mov ah,3Fh ; read file/device mov dx,offset tmpbuf mov bx,test_hndl mov cx,8 int dos jc term_tstx mov cx,ax jcxz term_tstx mov si,offset tmpbuf term_tst4: push cx push si mov ah,[si] call outchr nop nop nop pop si pop cx inc si loop term_tst4 jmp term_tst2 term_tstx: mov ah,3Eh mov bx,test_hndl int dos term_tstz: and vt100_flags,NOT LOOPTEST_BIT clc jmp term1 term 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 exit Connect mode (kbdflg has transfer char). ; chrout is called from KEYBD after key definition translation. ; the character is in AL. chrout: cmp kanji_scode,0 ; if kanji is not used, no translation je chroutx test kanji_scode,4 ; if shift-JIS is used, no translation jnz chroutx cmp kanji_smode,0 ; 1st byte ? je chrout_1 ; e = yes, jmp chrout_knj2 chrout_1: call is_kanji1 ; Kanji code 1st byte ? jnc chroutx ; nc = no. ASCII character mov kanjis1,al mov kanji_smode,1 jmp chroutxx chroutx: call outprt ; put char in al to serial port mov kanji_smode,0 chroutxx: clc ; stay in Connect mode ret chrout_knj2: mov ah,al mov al,kanjis1 call s2jis or ax,8080h ; convert to DEC code mov kanjis1,ah mov ah,0 call outprt mov al,kanjis1 jmp chroutx trnprs: push ax ; toggle Copy screen to printer test ourarg.flgs,prtscr ; are we currently printing? jnz trnpr2 ; nz = yes, its on and going off mov ah,ioctl mov al,7 ; get output status of printer push bx mov bx,4 ; file handle for system printer int dos pop bx jc trnpr1 ; c = printer not ready cmp al,0ffh ; Ready status? je trnpr2 ; e = Ready trnpr1: call beep ; Not Ready, complain jmp trnpr3 ; and ignore request trnpr2: xor ourarg.flgs,prtscr ; flip the flag trnpr3: pop ax clc ret klogon proc near ; resume logging (if any) test flags.capflg,logses ; session logging enabled? jz klogn ; z = no, forget it or ourarg.flgs,capt ; turn on capture flag klogn: clc ret klogon endp klogof proc near ; suspend logging (if any) and argadr.flgs,not capt ; stop capturing klogo: clc ret klogof endp uparrw: mov al,'A' jmp short comarr dnarrw: mov al,'B' jmp short comarr rtarrw: mov al,'C' jmp short comarr lfarrw: mov al,'D' comarr: push ax mov ah,ESCAPE call outchr nop nop nop mov ah,'[' cmp curkey_mode,0 je comar1 mov ah,'O' comar1: call outchr nop nop nop pop ax mov ah,al call outchr nop nop nop clc ret pf1: mov al,'P' jmp short compf pf2: mov al,'Q' jmp short compf pf3: mov al,'R' jmp short compf pf4: mov al,'S' compf: push ax mov ah,ESCAPE call outchr nop nop nop mov ah,'O' call outchr nop nop nop pop ax mov ah,al call outchr nop nop nop clc ret kp0: mov al,'p' jmp short comkp kp1: mov al,'q' jmp short comkp kp2: mov al,'r' jmp short comkp kp3: mov al,'s' jmp short comkp kp4: mov al,'t' jmp short comkp kp5: mov al,'u' jmp short comkp kp6: mov al,'v' jmp short comkp kp7: mov al,'w' jmp short comkp kp8: mov al,'x' jmp short comkp kp9: mov al,'y' jmp short comkp kpmins: mov al,'m' jmp short comkp kpcoma: mov al,'l' jmp short comkp kpentr: mov al,'M' jmp short comkp kpdot: mov al,'n' jmp short comkp comkp: cmp keypad_mode,0 je comkp1 push ax mov ah,ESCAPE call outchr nop nop nop mov ah,'O' call outchr nop nop nop pop ax jmp short comkp2 comkp1: sub al,40h comkp2: mov ah,al call outchr nop nop nop clc ret snull: mov ah,0 ; send a null call outchr ; send without echo or logging nop nop nop clc ret keyinchg: xor keyin_dos,1 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 chang: mov al,'H' ; Hangup, drop DTR & RTS ;;; jmp short cmdcom cmdcom: mov kbdflg,al ; pass char to msster.asm via kbdflg stc ; say exit Connect mode ret ;; end of action routines ; 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 outtty_knj0 ; e = yes, off push bx ; Translate incoming char mov bx,offset rxtable ; address of translate table xlatb ; new char is in al pop bx ; ; Kanji test ; outtty_knj0: cmp kanji_rcode,0 ; Kanji code used ? je outnp7 ; e = no, no translation test kanji_rcode,2 ; DEC code ? jz outtty_knj1 ; z = no jmp outtty_dknj0 outtty_knj1: test kanji_rcode,4 ; Shift-JIS code ? jz outtty_knj2 jmp outtty_sknj0 outtty_knj2: ; outnp7: push bx mov bx,argadr ; args from msster directly test [bx].flgs,capt ; capturing output? Can be shut off pop bx ; if out dev becomes not ready. jz outnoc ; no, forget this part push ax ; save char call captrtn ; give it captured character cmp kanji_rmode,0 je outnp71 mov al,kanjir1 call captrtn outnp71: pop ax ; restore character and keep going outnoc: test ourarg.flgs,prtscr ; should we be printing? jz outnop ; no, keep going push ax mov ah,print_out ; write to system printer device mov dl,al int dos cmp kanji_rmode,0 je outnoc1 mov dl,kanjir1 int dos outnoc1: pop ax jnc outnop ; nc = successful print push ax call beep ; else make a noise and call trnprs ; turn off printing pop ax outnop: cmp flags.vtflg,0 ; emulating vt100 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: cmp flags.vtflg,ttvt100 ; vt100 emulation? je outtty_vt cmp flags.vtflg,tttek ; tek4014 emulation? je outtty_tk ; outnp5: test flags.remflg,d8bit ; keep 8 bits for displays? jnz outnp9 ; nz = yes, 8 bits if possible and al,7fh ; remove high bit outnp9: mov ah,conout ; dostty screen mode mov dl,al ; write without intervention. int dos ; else let dos display char cmp kanji_rmode,0 je outnpx test flags.remflg,d8bit jnz outnp91 and al,7fh outnp91: mov ah,conout mov dl,kanjir1 int dos mov kanji_rmode,0 outnpx: ret ; and return ; outtty_vt: cmp al,CHR_GS jne outtty_vt1 test vt100_flags,AUTOTEK_BIT jz outtty_vt1 push ax call vt100_save call ent_tk mov flags.vtflg,tttek pop ax jmp outtty_tk1 outtty_vt1: cmp kanji_rmode,0 je outtty_vt2 mov al,kanjio1 call vt100 mov al,kanjio2 outtty_vt2: call vt100 jmp outtty_snd outtty_tk: cmp al,CHR_CAN jne outtty_tk1 test vt100_flags,AUTOTEK_BIT jz outtty_tk1 push ax call tek4014_save call ent_vt mov flags.vtflg,ttvt100 pop ax jmp outtty_vt1 outtty_tk1: call tek4014 outtty_snd: mov kanji_rmode,0 jcxz outtty_snd_ex ; If there is no answer-back, return outtty_snd1: mov ah,[si] call outchr ; send character without echo nop nop nop inc si loop outtty_snd1 outtty_snd_ex: ret outtty_dknj0: cmp kanji_rmode,0 ; 1st byte ? jne outtty_dknj2 cmp al,0A0h ; Is kanji ? ja outtty_dknj1 ; a = Yes. jmp outnp7 outtty_dknj1: mov kanji_rmode,1 mov kanjir1,al mov kanjio1,al ret outtty_dknj2: test al,0A0h jbe outtty_dknj3 mov kanjio2,al mov ah,al mov al,kanjir1 and ax,7F7Fh call jis2s mov kanjir1,ah outtty_dknj3: jmp outnp7 ; outtty_sknj0: cmp kanji_rmode,0 ; 1st byte ? jne outtty_sknj2 call is_kanji1 jc outtty_sknj1 ; c = Yes. jmp outnp7 outtty_sknj1: mov kanji_rmode,1 mov kanjir1,al mov kanjio1,al ret outtty_sknj2: mov kanjio2,al mov ah,al mov al,kanjio1 call s2jis or ax,8080h xchg kanjio1,al xchg kanjio2,ah mov kanjir1,ah jmp outnp7 ; outtty endp ; send the character in al out to the serial port; handle echoing. ; Can send an 8 bit char while displaying only 7 bits locally. outprt proc near test ourarg.flgs,lclecho ; echoing? jz outpr1 ; z = no, forget it push ax ; save char call outtty ; print it pop ax ; restore outpr1: mov ah,al ; this is where outchr expects it call outchr ; output to the port nop nop nop ; skip returns... ret outprt endp ; Get a char from the serial port manager ; returns with carry on if a character is available portchr proc near call prtchr ; character at port? jmp short portc1 ; yes nop portc0: clc ; no carry -> no character ret ; and return... portc1: and al,parmsk ; apply 8/7 bit parity mask or al,al ; catch nulls jz portc0 ; z = null, ignore it ;;-------------------------------------------------------- ;; DO NOT IGNORE DELs. TEK4014 uses DEL code for LOY byte. ;; (H.Fujii 19-May-1988) ;; ;; cmp al,del ; catch dels ;; je portc0 ; e = del, ignore it ;;-------------------------------------------------------- portc2: stc ; have a character ret ; and return portchr 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 ; ;+ End of MSXP98.ASM