name msxap3 ; File MSXAP3.ASM ; Last modification: 13 April 1986 ; System dependent module for NEC APC III ;*********************************************************************** ; Add global entry point vtstat for use by Status routine in mssset. ; Joe R. Doupnik 12 March 1986 ; Add global procedures ihosts and ihostr to handle host initialization ; when packets are to be sent or received by us,resp. 24 March 1986 ; Add global procedure Dtrlow (without worker serhng) to force DTR and RTS ; low in response to Kermit command Hangup. Yields Not Yet Implemented. [jrd] ; Add global procedure Dumpscr, called by Ter in file msster, to dump screen ; to a file. Just does a beep for now. 13 April 1986 [jrd] ; ;* ;* RAL 6/12/85 ;* ;* 7/3/85 Changed Poscur from NEC ROM BIOS to emulate VT100 cursor ;* positioning....ROM version caused Kermit to lose characters ;* for unknown reasons ;* ;* Changed escape character from Control-A to Control-] ;* ;* Kermit for NEC APC III ;* ;*********************************************************************** public serini, serrst, clrbuf, outchr, coms, vts, vtstat, dodel, ctlu public cmblnk, locate, lclini, prtchr, dobaud, clearl public dodisk, getbaud, beep, puthlp public count, poscur, machnam, sendbr, putmod, clrmod public setktab, setkhlp, xofsnt, showkey public term public ihosts, ihostr, dtrlow, dumpscr ; [jrd] include mssdef.h false equ 0 true equ 1 auxin equ 3 auxout equ 4 auxfil equ 3 ; file number of aux file. iordy equ 6 ; input ready function datas segment public 'datas' extrn drives:byte, flags:byte, trans:byte extrn portval:word, port1:byte, port2:byte, dmpname:byte ; [jrd] portin db 0 crlf db cr,lf,'$' machnam db '* NEC APC III - RAL Version 2.0 *',cr,lf,'$' badbd db cr,lf,'Unimplemented baud rate, Baud = 9600$' noimp db cr,lf,'Command not implemented.$' shkmsg db 'Not implemented.' shklen equ $-shkmsg hngmsg db cr,lf,' The phone should have hungup.',cr,lf,'$' ; [jrd] hnghlp db cr,lf,' The modem control lines DTR and RTS for the current' db ' port are forced low (off)' db cr,lf,' to hangup the phone. Normally, Kermit leaves them' db ' high (on) when it exits.' db cr,lf,'$' ; [jrd] rdbuf db 80 dup (?) ; temp buf [jrd] xofsnt db 0 ; Say if we sent an XOFF. xofrcv db 0 ; Say if we received an XOFF. setktab db 0 setkhlp db 0 invseq db esc,'[7m$' ; Reverse video on. nrmseq db esc,'[0m',esc,'[33m$' ; Reverse video off. ivlseq db esc,'[7m' db 79 dup (' '),cr,'$' ; Make a line inverse video delstr db BS,' ',BS,'$' ; Delete string...Used in DODEL........ clrlin db cr,esc,'[K$' ; Erase line...Used in CTLU..... tmp db ?,'$' temp dw 0 temp1 dw ? ; Temporary storage. temp2 dw ? ; Temporary storage. ; variables for serial interrupt handler source db bufsiz DUP(?) ; Buffer for data from port. bufout dw 0 ; buffer removal ptr count dw 0 ; Number of chars in int buffer. bufin dw 0 ; buffer insertion ptr telflg db 0 ; Are we acting as a terminal. [16] [17c] clreol db esc,'[0K$' ; Clear to end of line....... blank db esc,'[H',esc,'[J$' ; Home cursor, then Clear screen.... movcur db esc,'[' colno db 20 dup (?) ten db 10 prthnd dw 0 ourarg termarg <> ; must parallel baud rate defs in pcdefs. ; Unsupported baud rates must be FF..... ; NEC APC has only 8 possible baud rates....... ; RAL.... ; baudtab db 0FFH ; 45.5 db 0FFH ; 50 db 0 ; 75 db 0FFH ; 110 db 0FFH ; 134.5 db 1 ; 150 db 2 ; 300 db 3 ; 600 db 4 ; 1200 db 0FFH ; 1800 db 0FFH ; 2000 db 5 ; 2400 db 6 ; 4800 db 7 ; 9600 db 0FFH ; 19.2k db 0ffh ; 38.4k (ha) nbaud equ $-baudtab first db true ; RAL...Used in Get Baud...... qid dw ? prtcnt dw ? trqid dw ? tmqid dw ? brflg db ? datas ends code segment public 'code' extrn comnd:near, dopar:near, prserr:near extrn sleep:near ; [jrd] assume cs:code,ds:datas DODISK PROC NEAR mov ah,gcurdsk ; Current disk value to AL. int dos mov dl,al ; Put current disk in DL. mov ah,seldsk ; Select current disk. int dos ; Get number of drives in AL. mov drives,al ret DODISK ENDP ;********************************************************************* ; Clear the input buffer before sending a packet. [20e] ; RAL.... ;********************************************************************* CLRBUF PROC NEAR mov ah,2 ; Get data length in CX...Page SE-12 int 1AH ; Call APC ROM BIOS or ch,cl ; check for zero in both halfs of CX cmp ch,0 ; is CH 0? je clrb1 ; If zero then buffer is clear else mov ah,auxin ; get character from auxiliary device int dos jmp clrbuf clrb1: mov count,0 ret CLRBUF ENDP ;********************************************************************* ; Common routine to clear to end-of-line. [19a] CLEARL PROC NEAR mov dx,offset clreol mov ah,prstr int dos ret CLEARL ENDP ;******************************************************************* ; This routine should set the baud rate for the current port but it ; is actually done in SERINI. dobaud proc near push si ; [jrd] push bx mov bx,portval mov si,[bx].baud ; get baud rate index pointer.. pop bx mov al,baudtab[si] ; load up baud rate......... pop si ; [jrd] cmp al,0FFH ; Is Baud Rate Possible?? je badbaud call serini ; Simply re-init port with new baud rate dbret: ret BadBaud: mov ah,prstr ; MS-DOS Print String... mov dx,offset badbd ; point at message int DOS push bx mov bx,portval mov [bx].baud,0Dh ; Go back to 9600 baud..... pop bx jmp dbret dobaud endp ;******************************************************************* ; Send a break out the current serial port. Returns normally. sendbr: ret ; RAL Leave out for a while ;******************************************************************* ; Write a line in inverse video at the bottom of the screen... ; the line is passed in dx, terminated by a $. Returns normally. putmod proc near push dx ; save line pointer mov dh,24 ; Row... mov dl,0 ; Column... call poscur ; Position cursor at bottom of screen mov ah,prstr mov dx,offset ivlseq ; Put into reverse video. int dos pop dx mov ah,prstr int dos ; Print message..... mov ah,prstr mov dx,offset nrmseq ; Normal video. int dos ret putmod endp ;******************************************************************** ; Clear the mode line written by putmod. Returns normally. clrmod proc near mov dh,24 mov dl,0 call poscur ; Line 24, column 0... call clearl ; Clear Line...... ret clrmod endp ;***************************************************************** ; Put a help message one the screen in reverse video. Pass ; the message in AX, terminated by a null. Returns normally. ; The message is put wherever the cursor currently is located. puthlp proc near push ax mov ah,prstr ; Leave some room before the message. mov dx,offset crlf ; write CR,LF int dos pop si ; Put message address here. cld ; set direction for auto increment puth0: push si mov ah,prstr mov dx,offset ivlseq ; Make line inverse video int dos pop si puth1: lodsb cmp al,0 ; End of String??? je puth2 push ax push si mov ah,14 ; Write Teletype... int 19h ; Call NEC Bios pop si pop ax cmp al,lf ; Line feed? je puth0 ; Yes, clear the next line. jmp puth1 ; Else, just keep on writing. puth2: mov dx,offset crlf ; Next line..... mov ah,prstr int dos mov dx,offset nrmseq ; Return to Normal video. int dos ret puthlp endp ;********************************************************************* ; This routine blanks the screen. CMBLNK PROC NEAR mov ah,prstr mov dx,offset blank int dos ret CMBLNK ENDP ;********************************************************************* ;* Home cursor LOCATE PROC NEAR mov dx,0 ; Go to top left corner of screen. jmp poscur ; callret... LOCATE ENDP ;******************************************************************** ;* RAL..This routine appears to be called every time a status is done. ;* I will set baud rate first time, and simply return from then on. ;* ;* Page SA-2 APC III Programmer Reference Manual GETBAUD PROC NEAR mov al,First ; Check to see if this is the first time.... cmp al,false je GBRET ; Quit if baud rate already known..... mov First,False ; Flip Flag... push bx mov bx,portval mov [bx].baud,0Dh ; Default to 9600 Baud..... pop bx call serini ; Set up port........ GBRET: ret GETBAUD ENDP ;********************************************************************** ;* Position the cursor according to contents of DX. ;* Page SE-4 ;* DH,DL - Row, Column ;* BH Page number - 0,1 ;* Ral ;POSCUR PROC NEAR ; mov bh,0 ; Use page 0 ; mov ah,2 ; set cursor position... ; int 19h ; CRT IO with NEC APC ROM BIOS ; ret ;POSCUR ENDP ; Position the cursor according to contents of DX. POSCUR PROC NEAR push ax ; save regs. [jrd] push di push es mov ax,ds mov es,ax ; address data segment!!! cld mov di,offset colno mov al,dh ; row inc al call nout mov al,';' stosb mov al,dl ; col inc al call nout mov al,'H' stosb mov al,'$' stosb mov dx,offset movcur mov ah,prstr int dos ; print the sequence pop es ; [jrd] pop di pop ax ret POSCUR ENDP NOUT PROC NEAR cbw ; extend to word div byte ptr ten ; divide by 10 or al,al ; any quotient? jz nout1 ; no, forget this push ax ; save current result call nout ; output high order pop ax ; restore nout1: mov al,ah ; get digit add al,'0' ; make printable stosb ret ; put in buffer and return NOUT endp ;****************************************************************** ; Perform a delete. DODEL PROC NEAR mov ah,prstr mov dx,offset delstr ; Erase weird character. int dos ret DODEL ENDP ;******************************************************************** ; Perform a Control-U. CTLU PROC NEAR mov ah,prstr mov dx,offset clrlin int dos ret CTLU ENDP ;******************************************************************** ;* Select various I/O ports for Kermit to use...Not Implemented.... COMS PROC NEAR jmp notimp ; function in use.... COMS ENDP ;******************************************************************** ;* Set Heath-19 Emulation on & off VTS PROC NEAR jmp notimp ; Wasn't Implemented in original Wang.. VTS ENDP VTSTAT PROC NEAR ; For Status display [jrd] ret ; no emulator status to display VTSTAT ENDP ; Save the screen to a buffer and then append buffer to a disk file. [jrd] ; Default filename is Kermit.scn; actual file can be a device too. Filename ; is determined by mssset and is passed as pointer dmpname. DUMPSCR PROC NEAR ; Dumps screen contents to a file. Just Beeps here call beep ; [jrd] ret DUMPSCR ENDP ;********************************************************************* ;* Print not implemented message....... ;********************************************************************* notimp: mov ah,prstr mov dx,offset noimp int dos jmp prserr ;********************************************************************* ;* Perform initialization ;********************************************************************* lclini: mov trans.escchr,1Dh ; Use Control-] as escape char. mov flags.vtflg,0 ; Turn Heath Emulation Off..... mov ah,5 ; Select active page number mov al,0 ; use page 0.. int 19h ; Call NEC ROM BIOS.... ret ;******************************************************************** ;* Not implemented....RAL showkey: jmp notimp ;************* RAL ***************************************************** ;* Page SE-10 MS-DOS Programmers Manual ;* Performs Serial Port Initialization............. ;*********************************************************************** ; Common initialization for using serial port. SERINI PROC NEAR push es push di mov AX,datas ; point at start of this segement? mov ES,AX mov DI,offset source ; Point at Serial Buffer.... push bx mov bx,portval mov si,[bx].baud ; get baud rate index pointer.. mov ah,[bx].floflg pop bx mov al,baudtab[si] ; load up baud rate......... ; AH = 1 XON/XOFF flow control ; AH = 0 No Flow control ; Page SE-10 NEC Programmer Ref manual cmp AH,0 ; doing flow control? je NoFlow ; 0 if not flow control mov ah,1 ; Init with Xon/Xoff NoFlow: mov CH,01001110B ; set up various parameters.... ; | | | | ; | | | +--- Clock 10 x16, 11 x64 ; | | +----- Word Length 10 7, 11 8 ; | +------- Parity 00 None, 01 Odd, 11 Even ; +--------- Stop Bits 01 1, 10 1.5, 11 2 mov CL,00100111B ; Page 24 Compupro System Support ; appears to be same IC.... mov dx,200 ; load with Buffer Size... ; Buffer is actually 2048 long ; but NEC Bios will not work that long.. ; Manual does not give much info ; on this variable...Will leave at 200 ; until I learn more.... mov bh,0 ; try defaults for these... mov bl,0 int 1AH ; Call NEC Rom cmp ah,0 ; Did everything go ok?? je serin1 ; continue if so...else call beep serin1: call clrbuf ; Clear Input buffer........ pop di pop es ret ; We're done. [21c] SERINI ENDP ;********************************************************************* ;* Should reset serial port to settings before kermit, but its not ;* worth the trouble....RAL....... SERRST PROC NEAR serrs1: ret SERRST ENDP ;********************************************************************* ; Generate a short beep. BEEP PROC NEAR mov dl,bell mov ah,conout int dos ret BEEP ENDP ;********************************************************************* ; Jumping to this location is like retskp. It assumes the instruction ; after the call is a jmp addr. RSKP PROC NEAR pop bp add bp,3 push bp ret RSKP ENDP ;********************************************************************* ; Jumping here is the same as a ret. R PROC NEAR ret R ENDP ;********************************************************************* ;* Very simple Terminal Emulator.....RAL term proc near mov si,ax ; this is source mov di,offset ourarg ; place to store arguments mov ax,ds mov es,ax ; address destination segment mov cx,size termarg rep movsb ; copy into our arg blk ;__________________ Terminal Emulator ______________________________ ;* RAL 6/14/85 term1: call prtchr ; Try to get char from Serial port... jmp short term2 ; have a char... nop nop jmp short term3 ; no char, go on term2: and al,7fh ; strip 8th bit - ral push ax call print ; print character in AL.. pop ax test ourarg.flgs,capt ; capturing output? jz term3 ; no, forget it call ourarg.captr ; else call the routine term3: mov ah,1 ; Check to see if keyboard has a char ; Page SE-1... ; Zero Flag = 1....No Chars... ; Zero Flag = 0...Character in queue int 18H ; Call NEC ROM jz term1 ; no character, restart terminal loop mov ah,0 ; Get char from queue in AL.... int 18h ; Call NEC ROM cmp al,ourarg.escc ; escape char? je term4 ; yes, exit push ax ; preserve AX mov ah,al call outchr ; output the character nop nop nop pop ax ; Restore AX test ourarg.flgs,lclecho ; echoing? jz term1 ; no, continue loop ; Echo Character... call print jmp term1 ; else echo and keep going term4: ret Print: mov DL,AL mov ah,06 ; Print Character in DL on CRT int DOS ret term endp ;******************************************************************* ; skip returns if no character available at port, ; otherwise returns with char in al, # of chars in buffer in dx. ;* RAL 6/12/85 change get character from AUX port PRTCHR PROC NEAR mov ah,2 ; Get data length in CX...Page SE-12 int 1AH ; Call APC ROM BIOS mov count,cx ; save count or ch,cl ; check for zero in both halfs of CX cmp ch,0 ; is CH 0? je prtc1 ; give up if no characters........ mov ah,4 ; Receive Character...by way of NEC BIOS int 1AH mov al,ch ; Character is returned in CH.... dec count ; show that we took character... mov dx,count ; load dx with count for return ret prtc1: jmp rskp PRTCHR ENDP ;******************************************************************** ;* Will send a character to the AUX port... ;* RAL ; 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 character cannot be written... OUTCHR PROC NEAR push dx mov al,ah ; parity works on AH call dopar ; do parity work before sending mov ah,3 ; NEC ROM BIOS send character in AL int 1AH ; send character... pop dx jmp rskp OUTCHR ENDP ; IHOSTS - Initialize the host by sending XON, or equivalent, and enter the ; cycle of clear input buffer, wait 1 second, test if buffer empty then exit ; else repeat cycle. Requires that the port be initialized before hand. ; Ihosts is used by the local send-file routine just after initializing ; the serial port. ; 22 March 1986 [jrd] IHOSTS PROC NEAR push ax ; save the registers push bx push cx push dx mov bx,portval ; port indicator mov ax,[bx].flowc ; put Go-ahead flow control char in ah call outchr ; send it (release Host's output queue) nop ; outchr can do skip return nop nop ihosts1:call clrbuf ; clear out interrupt buffer mov ax,1 ; sleep for 1 second call sleep ; procedure sleep is in msscom.asm call prtchr ; check for char at port jmp ihosts1 ; have a char in al, repeat wait/read cycle nop ; prtchr does skip return on empty buffer pop dx ; empty buffer. we are done here. pop cx pop bx pop ax ret IHOSTS ENDP ; IHOSTR - initialize the remote host for our reception of a file by ; sending the flow-on character (XON typically) to release any held ; data. Called by receive-file code just after initializing the serial ; port. 22 March 1986 [jrd] IHOSTR PROC NEAR push ax ; save regs push bx push cx mov bx,portval ; port indicator mov ax,[bx].flowc ; put Go-ahead flow control char in ah call outchr ; send it (release Host's output queue) nop ; outchr can do skip return nop nop pop cx pop bx pop ax ret IHOSTR ENDP DTRLOW PROC NEAR ; Global proc to Hangup the Phone by making ; DTR and RTS low. mov ah,cmtxt ; allow text to be able to display help mov bx,offset rdbuf ; dummy buffer mov dx,offset hnghlp ; help message call comnd ; get a confirm jmp r ;not yet imp. call serhng ; drop DTR and RTS mov ah,prstr ; give a nice message ;not yet imp. mov dx,offset hngmsg mov dx,offset noimp ; say "not implemented" 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. code ends end