        name msyv90
; File MSYV90.ASM
; Last modification: 30 July 1986
; Kermit system dependent module for VICTOR 9000/SIRIUS
; 30 July 1986 fill out prodecure DUMPSCR - it was borrowed from MSYIBM and
;  modified to fit the Victor format.  It required a modification of
;  lclyini to get the character set base  [bgp]
; Add global procedure Dumpscr, called by Ter in file msster, to dump screen
;   to a file. Just does a beep for now. 3 May 1986 [jrd]
;
; edit history:
;      7-DEC-85 ORIGINAL        BGP
;     20-FEB-86 CORRECTED FOR ERROR IN PUTMOD IN MSXV9000      (BGP)
;     22-FEB-86 ADDED CODE TO SWALLOW ANSI ESCAPE SEQUENCES      (BGP)
; Added 'full' VT100 emulation using code by Andreas Stumpf
; (ZRZS@DS0RUS1I).    The significant parts that are not emulated are
;   esc c  - reset terminal
;   esc N  - ??
;   esc O  - ??
;   esc n  - ??
;   esc l  - ??
;   esc o  - ??
;   esc <  - go to ANSI mode (from VT52)
;   esc [ q    - fiddle with the LED's
;   esc [ h    - some modes not supported
;   esc [ l    - some modes not supported
;   esc [ i    - ??
;   esc [ p    - ??
;   esc [ y    - ??
; and some codes that are not VT100 'standard' are supported
;   esc [ E    - ??
;   esc [ F    - ??
;   esc [ G    - ??
;   esc [ L    - ??
;   esc [ M    - ??
;   esc [ @    - ??
;   esc [ P    - ??
;   esc [ X    - ??
;   esc [ d    - ??
;   esc [ e    - ??
; Last update 28 April 1986
; Add global procedure Dumpscr, called by Ter in file msster, to dump screen
;   to a file. Just does a beep for now. 3 May 1986 [jrd]
;
        public  term, lclyini, vts, vtstat ; entry points
        public  dumpscr                         ; [jrd]
        include mssdef.h

SEG_CRTC EQU    0E800H          ; segment for crt controller
OFF_CRTC EQU    0               ; offset for crt controller

modfrm  struc                   ; format of mode line
        db      ' Esc chr: '
m_echr  db      2 dup (?)
        db      ', Port: '
m_prt   db      1 dup (?)
        db      ', Speed: '
m_baud  db      4 dup (?)
        db      ', Parity: '
m_par   db      4 dup (?)
        db      ', Echo: '
m_echo  db      3 dup (?)
        db      ', Type '
m_hlp   db      2 dup (?)
        db      '? for Help'
        db      ' $'            ; must be dollar terminated
modfrm  ends

DATAS   segment public 'datas'

        extrn flags:byte        ; to get access to emulation
        extrn filtst:byte, dmpname:byte ; for screen dumping [bgp]

termhlp db      CR,LF,'Terminal type of Heath-19 or VT100$'
termtbl db      4
        mkeyw   'Heath-19',TTHEATH
        mkeyw   'none',TTHEATH  ; since none=heath on Victor
        mkeyw   'VT100',TTVT100
        mkeyw   'VT102',TTVT100

; stuff for screen routines
wflags  label   word            ; so we can push yflags
yflags  db      ?               ; status flags...
        db      0               ; extra byte for flags
flags1  db      0               ; internal flags.
prtscr  equ     80h             ; print screen pressed
inited  equ     08h             ; been here before...
esc_ch  db      ?
argadr  dw      ?               ; address of arg blk
crt_cols db     ?
crt_lins db     ?
modbuf  modfrm  <>              ; mode line buffer
; routine to call for captured output
captrtn dw      ?
oldcur  dw      0               ; save'd cursor position
; some static data for mode line
unkbaud db      'Unk '          ; must be 4 chars...
baudn   db      '45.5'
        db      '  50'
        db      '  75'
        db      ' 110'
        db      ' 135'
        db      ' 150'
        db      ' 300'
        db      ' 600'
        db      '1200'
        db      '1800'
        db      '2000'
        db      '2400'
        db      '4800'
        db      '9600'
        db      '19.2'
        db      '38.4'
baudnsiz  equ   16              ; # of baud rates known (tbl size / 4)
parnams db      'Even'
        db      'Mark'
        db      'None'
        db      'Odd '          ; must be 4 chars
        db      'Spc '
offmsg  db      'Off'
onmsg   db      'On '
lclmsg  db      'Lcl'
remmsg  db      'Rem'

portno  db      ?

screen  dw      1920 dup (?)
curloc  db      2 dup (?)       ; row,column
scrseg  dw      0F000H
rptcur  db      27,'n$'         ; request cursor location
escseq  db      0               ; ANSI escape sequence indicator
                                ; 0=none, 1=escape, 2=[

char_base dw    0               ; screen character base
dmphand dw      0               ; handle for screen dump [bgp]
dumpbuf db      80 dup (?),CR,LF ; line buffer for screen dump
dumpsep db      FF,CR,LF        ; put in file between screen dumps
dmperr  db      '  WARNING:  CAN NOT OPEN THE SCREEN DUMP FILE  $'

; stuff for ANSI emulation [as]
SUPERBIOS equ   0dfh            ; SuperBios-Interrupt

tt      struc                   ; structure of keyboardtable
head    dw      2 dup (?)
kd0     db      104*3 dup (?)
kd12    dw      104*3 dup (?)
extrtabl db     256 dup (?)
tt      ends

afirst  db      0
; Parameterblock for setting/getting of keyboard-table
parmblock db    3
laenge  dw      1196            ; length of table
offs    dw      offset oldtable
segm    dw      seg oldtable
; block for call to get Console-driver-address
condev  dw      1
drivadr dd      0               ; address of consoledriver
;
oldtable tt     <,,,>           ; saved old keytable
numtbl  tt      <,,,>           ; Table with Num-Keypad
apptbl  tt      <,,,>           ; Table with Appl-Keypad
; In order to avoid smashing stuff that may already be in the multi-char
; sequence table for the keyboard (or as little as possible) put it near the
; end of the table - the following parameters tells how deep into the table
; to start putting stuff
START_EXTRTBL EQU 160
; Cursorsequences ANSI
appcur  db      0               ; flag for cursor key modes
curseq  db      3,ESC,'[A',3,ESC,'[B',3,ESC,'[D',3,ESC,'[C'
curapp  db      3,ESC,'OA',3,ESC,'OB',3,ESC,'OD',3,ESC,'OC'
; Applikationkeypad
appkeys db      0               ; flag for keypad modes
applik  db      3,ESC,'[A',3,ESC,'[B',3,ESC,'[D',3,ESC,'[C'
        db      3,ESC,'OP',3,ESC,'OQ',3,ESC,'OR',3,ESC,'OS'
        db      3,ESC,'Ow',3,ESC,'Ox',3,ESC,'Oy',3,ESC,'Om'
        db      3,ESC,'Ot',3,ESC,'Ou',3,ESC,'Ov',3,ESC,'Ol'
        db      3,ESC,'Oq',3,ESC,'Or',3,ESC,'Os',3,ESC,'OM'
        db      3,ESC,'Op',3,ESC,'On'
sesctbl db      'DEHMNOZn|o[>=78c<' ; table for characters following single ESC
sesclen equ     $-sesctbl
; now the table for routines to process those characters
sescsub dw      processD
        dw      processE
        dw      processH
        dw      processM
        dw      ignore
        dw      ignore
        dw      procc0          ; same as ESC [0c
        dw      ignore
        dw      ignore
        dw      ignore
        dw      processbra
        dw      processgt
        dw      processeq
        dw      process7
        dw      process8
        dw      ignore
        dw      ignore
; table for the last characters in a ESC'[' sequence
mesctbl db      '`EFGABCDHLM@PXKJfghilmrcnpyqde'
mesclen equ     $-mesctbl
; processing routine table for ESC'[' sequences
mescsub dw      proce
        dw      proce
        dw      procuf
        dw      procug
        dw      curmov
        dw      curmov
        dw      curmov
        dw      curmov
        dw      procH
        dw      procL
        dw      procM
        dw      procAt
        dw      procP
        dw      procX
        dw      procK
        dw      procJ
        dw      procH
        dw      procg
        dw      prochl
        dw      ignore
        dw      prochl
        dw      proclm
        dw      procr
        dw      procc
        dw      procn
        dw      ignore
        dw      ignore
        dw      ignore
        dw      procld
        dw      procle
;
top     db      1               ; scrolling region margins
bottom  db      24
escpnt  dw      offset escstring
escstring db    80 dup (?)      ; save area for Escape sequence
tabstops db     0,0,0,0,0,0,0,0 ; tabulator stops
        db      1,0,0,0,0,0,0,0
        db      1,0,0,0,0,0,0,0
        db      1,0,0,0,0,0,0,0
        db      1,0,0,0,0,0,0,0
        db      1,0,0,0,0,0,0,0
        db      1,0,0,0,0,0,0,0
        db      1,0,0,0,0,0,0,0
        db      1,0,0,0,0,0,0,0
        db      1,0,0,0,0,0,0,0
chrset_mask db  0               ; mask for selecting character set
DATAS   ends

CODE    segment public          ; code segment
        extrn   prtchr:near,outchr:near,sendbr:near,comnd:near
        extrn   putmod:near,clrmod:near,cmblnk:near,poscur:near
        extrn   beep:near, isfile:near                          ; [jrd] [bgp]
        assume  cs:code,ds:datas,es:datas

; do initialization local to this module...
; mainly get console driver address to speed up screen access [as]
; 30 July 1986 added code to get character set base for dump [bgp]

LCLYINI proc    near
        mov     ah,DCONIO
        mov     dl,ESC          ; to set nowrap
        int     DOS
        mov     dl,'w'
        int     DOS
        mov     ax,ds
        mov     es,ax
        mov     ax,14           ; function 'get driveraddress'
        mov     bx,offset condev
        int     SUPERBIOS       ; address is now in drivadr
        push    es
        mov     ax,0F000H       ; point at base of screen memory
        mov     es,ax
        mov     ax,word ptr es:3838 ; note:  this should be the last character
                                ; of the last line on the screen - if it was
                                ; cleared as Kermit usually does when it starts
                                ; up, this will be a space - it must be a space!
        and     ax,7FFH         ; strip off mode bits
        sub     ax,' '          ; minus which char it is
        mov     char_base,ax    ; and save it
        pop     es
        ret
LCLYINI endp

; We need to save the arguments to TERM where they are a little more
; accessible than in the way they were passed

ARGINI  proc    near            ; read passed arguments
        mov     bx,argadr       ; base of argument block
        mov     al,[bx].flgs    ; get flags
        and     al,capt+emheath+havtt+trnctl+lclecho+modoff+lnwrap
        mov     yflags,al       ; mask for allowable and save
        and     flags1,not (prtscr) ; these are allowable
                                ; (others remain).
        mov     al,[bx].prt
        cmp     al,portno       ; using same port?
        je      argin1          ; yes, go on
        and     flags1,not inited ; else re-init stuff
argin1:
        mov     portno,al       ; update port number
        mov     al,[bx].cols
        mov     crt_cols,al
        mov     al,[bx].rows
        mov     crt_lins,al     ; init # of rows and cols
        mov     ax,[bx].captr
        mov     captrtn,ax      ; buffer capture routine
        mov     al,[bx].escc
        mov     esc_ch,al
        ret                     ; that's it
ARGINI  endp

; We need to generate the mode line and output it

MODLIN  proc    near            ; turn on mode line
        push    ds
        pop     es              ; make sure es is correct
        mov     al,esc_ch
        mov     modbuf.m_echr,' ' ; first char is initial space
        mov     modbuf.m_hlp,' ' ; goes here too.
        cmp     al,32           ; printable?
        jnb     modl1           ; yes, keep going
        add     al,40h          ; made printable
        mov     modbuf.m_echr,'^' ; note control char
        mov     modbuf.m_hlp,'^'
modl1:
        mov     modbuf.m_echr+1,al ; fill in character
        mov     modbuf.m_hlp+1,al
        mov     bx,argadr       ; get argument block
        mov     al,[bx].baudb   ; get baud bits
        mov     si,offset unkbaud ; assume unknown baud
        cmp     al,baudnsiz     ; too big?
        jnb     modl2           ; yes, use default
        mov     cl,2            ; each is 4 bytes long
        shl     al,cl
        mov     ah,0
        add     ax,offset baudn
        mov     si,ax
modl2:
        mov     cx,size m_baud  ; length of baud space
        mov     di,offset modbuf.m_baud
        rep     movsb           ; copy in baud rate
        mov     al,[bx].parity  ; get parity code
        mov     cl,2            ; each is 4 bytes long...
        shl     al,cl
        mov     ah,0
        add     ax,offset parnams ; names of parity settings
        mov     si,ax
        mov     cx,4            ; each is 4 long
        mov     di,offset modbuf.m_par
        rep     movsb
        mov     si,offset remmsg ; Assume remote echoing.
        test    yflags,lclecho  ; Is remote side echoing?
        jz      modl4           ; Yes, keep going
        mov     si,offset lclmsg ; Else it's local echoing.
modl4:
        mov     cx,3            ; size of on/off
        mov     di,offset modbuf.m_echo
        rep     movsb
        mov     al,'1'
        cmp     portno,1        ; port 1?
        je      modl5           ; yes, keep going
        mov     al,'2'
modl5:
        mov     modbuf.m_prt,al ; fill in port number
        mov     dx,offset modbuf ; where it is
        call    putmod
        ret
MODLIN  endp

; This is the entry point for terminal emulation
; Added option of VT100 emulation

TERM    proc    near            ; terminal emulator entry point
        mov     argadr,ax       ; save argument ptr
        push    es              ; save caller's extra segment address
        mov     ax,seg datas
        mov     es,ax
        call    argini          ; init options from arg address
        test    flags1,inited   ; have we run yet?
        jz      term1           ; no, forget this part
        call    restscr         ; restore screen
        jmp     term2
term1:
        call    cmblnk          ; clear it off
term2:
        or      flags1,inited   ; remember we've run already.
        call    clrmod          ; empty mode line
        test    yflags,modoff   ; is mode line disabled?
        jnz     term3           ; yes, skip it
        call    modlin          ; turn on mode line
term3:
        cmp     flags.vtflg,TTVT100 ; emulating VT100?
        jne     lp
        call    ansie
        jmp     quit
lp:
        call    portchr         ; char at port?
         jnc    chkinp          ; no, keep going
; we want to swallow any ANSI escapes that come for now
;     they are all of the form ESC [ nn ; nn ; nn ; nn a
;     where n is a numeric character, and a is a non-numeric character
        cmp     escseq,0        ; escape sequence in progress?
        jne     eat_esc_seq     ; yes
        cmp     al,ESC          ; got an escape?
        jne     no_esc          ; no
        mov     escseq,1        ; yes, flag it
        jmp     chkinp
eat_esc_seq:
        cmp     escseq,1        ; got [?
        jne     eat_esc_seq2    ; yes
        cmp     al,'['
        je      eat_esc_seq1
        push    ax              ; not [, print esc and char
        mov     al,ESC
        call    outtty          ; send the escape
        pop     ax              ; and the following character
        mov     escseq,0        ; no escape sequence
        jmp     no_esc
eat_esc_seq1:
        mov     escseq,2        ; flag [
        jmp     chkinp
eat_esc_seq2:
        cmp     al,';'          ; check for terminator
        je      chkinp
        cmp     al,'0'
        jl      end_esc
        cmp     al,'9'
        jg      end_esc
        jmp     chkinp          ; no terminator, keep eating
end_esc:
        mov     escseq,0        ; end of sequence
        jmp     chkinp
no_esc:
        call    outtty          ; print on terminal
chkinp:
        mov     ah,DCONIO       ; Get it with no checking
        mov     dl,0FFH
        int     DOS
        cmp     al,0            ; anything there?
        je      lp              ; no...
        cmp     al,esc_ch       ; escape character?
        je      quit            ; yes, stop here
        call    outprt
        jmp     chkinp          ; and keep going
quit:
        call    clrmod          ; erase mode line
        call    savescr         ; save screen
        mov     al,yflags
        mov     bx,argadr
        mov     [bx].flgs,al    ; update flags in arg block
        pop     es              ; restore segment register
        ret                     ; and return to caller
TERM    endp

; ANSI, VT100 emulation by Andreas Stumpf

ANSIE   proc    near
        cmp     afirst,1        ; have we run yet?
        jnz     ansi2           ; no, forget this part
        mov     bx,ds           ; now restore keyboard too
        mov     es,bx
        mov     bx,offset parmblock
        mov     ax,18
        int     SUPERBIOS
        jmp     ansi3
ansi2:
        call    initansi
ansi3:
        mov     afirst,1        ; remember we've run already.
portc:
        call    portchr         ; char at port?
         jnc    achkinp         ; no, get char from keyboard
         call   doansi          ; handle it somehow
achkinp:
        mov     ah,DCONIO       ; Get it with no checking
        mov     dl,0FFH
        int     DOS
        cmp     al,0            ; anything there?
        je      portc           ; no...
        cmp     al,esc_ch       ; escape character?
        je      aquit           ; yes, stop here
        call    outprt          ; send it
        jmp     portc           ; look for next char
aquit:
        call    finiansi        ; fix keyboard up
        ret
ANSIE   endp

; DOANSI actually takes care of emulating the ANSI screen control stuff
; code by Andreas Stumpf - it expects the character to be in al

DOANSI  proc    near
        cmp     al,ESC          ; got an escape?
        jne     w00
        jmp     procesc0        ; escape terminates Escape-sequence,
w00:                            ; so it has to be tested first
        cmp     al,'X'-40h      ; Control-X ?
        jne     w0
        jmp     ignore
w0:
        cmp     al,'Z'-40h      ; Control-Z
        jne     w01
        jmp     ignore
w01:
        cmp     escseq,0        ; escape sequence in progress?
        je      w02
        jmp     procesc         ; yes
w02:
        cmp     al,' '
        jl      controls
        jmp     noesc
controls:
        cmp     al,LF           ; Linefeed,Formfeed and Vertical tab are
                                ; processed as 'Scroll down, if at
                                ; bottom margin, same function as ESC'D'
        jne     w1
        jmp     processD        ; perform scrolling if necessary
w1:     cmp     al,FF
        jne     w2
        jmp     processD
w2:     cmp     al,11           ; vertical tab
        jne     w3
        jmp     processD
w3:     cmp     al,TAB          ; horizontal tab
        jne     w4
        call    get_cur_pos     ; get cursor position
        mov     al,dh           ; work on it here
        mov     cx,80
        sub     cl,al           ; # of cols to search for tab
        cmp     cl,0            ; already off the end?
        jg      t0              ; no
        mov     cl,0
        jmp     t1              ; go to right margin
t0:
        xor     ah,ah
        mov     di,offset tabstops
        add     di,ax           ; address of first tabstop to look for
        cld
        mov     ax,1            ; compare table with 1
        repnz   scasb           ; cl=0 is right margin
t1:
        sub     cl,80
        neg     cl
        mov     dh,cl           ; set new col pos
        call    set_cur_pos     ; done...
        jmp     ignore
w4:     cmp     al,14           ; shift to extra set?
        jne     w5
        mov     chrset_mask,80H ; set top bit on these
        jmp     ignore
w5:     cmp     al,15           ; shift to normal set?
        jne     w6
        mov     chrset_mask,0   ; clear top bit
        jmp     ignore

w6:
        jmp     noesc

procesc0:                       ; start of escape sequence processing
        mov     escpnt,offset escstring
        mov     escseq,1        ; flag it
        jmp     doansi_d        ; done with it

procesc:                        ; have just got an escape
        cmp     escseq,1        ; single char ESCape ?
        je      procesc1        ; yes process it
        inc     escseq
        inc     escpnt          ; store escape sequence for
        mov     bx,escpnt       ; further processing
        mov     [bx],al
        cmp     escseq,3
        jg      proccont1
        cmp     al,'?'          ; 1st char after ESC'[' may be a '?'
        jne     proccont1
        jmp     doansi_d        ; done with it
proccont1:
        cmp     al,';'
        jne     proccont2
        jmp     doansi_d
proccont2:
        cmp     al,'-'          ; may be first char of a number
        jne     proccont3       ; continue checking
        mov     bx,escpnt
        cmp     byte ptr [bx-1],'0' ; preceding char in [0..9] ?
        jl      procmin1        ; if yes, then syntax error =>
        jmp     ignore          ; ignore Escapesequence
procmin1:
        cmp     byte ptr [bx-1],'9'
        jg      procmin2
        jmp     ignore
procmin2:
        jmp     doansi_d
proccont3:
        cmp     al,'0'
        jl      proccont
        cmp     al,'9'
        jg      proccont
        jmp     doansi_d        ; ESC-seq hasn't finished yet
proccont:
        jmp     procmulti       ; other char than 0..9 ';' => process them
procesc1:       ; function dispatcher for single char Escapesequences
        mov     di,offset sesctbl
        mov     cx,sesclen
        cld
        repnz   scasb           ; search for legal char following ESC
        cmp     al,[di-1]
        jnz     notrecognized
        mov     bx,sesclen
        sub     bx,cx           ; get offset in table
        dec     bx
        shl     bx,1
        add     bx,offset sescsub
        mov     escseq,0        ; Escape sequence has finished
        jmp     [bx]
notrecognized:
        jmp     noesc

processbra:                     ; introduction of multi-char Escapesequence
        mov     escseq,2
        inc     escpnt
        mov     bx,escpnt
        mov     [bx],al         ; save that char
        jmp     doansi_d        ; and get next one

processH:
        call    get_cur_pos     ; get cursor position
        mov     al,dh           ; get column here
        dec     al              ; range 0 to 79
        mov     bx,offset tabstops
        xor     ah,ah
        add     bx,ax
        mov     byte ptr [bx],1
        jmp     ignore

processD:
        call    get_cur_pos     ; get cursor position
        cmp     dl,bottom       ; is it last line?
        je      delline         ; yes, need to insert
        inc     dl              ; move down one line
        call    set_cur_pos
        jmp     ignore          ; done
delline:                        ; perform a scroll-up
        push    dx              ; save where we were
        mov     dl,top
        mov     dh,1            ; goto (top,1)
        call    set_cur_pos
        mov     al,ESC
        call    outtty
        mov     al,'M'          ; delete line
        call    outtty
        pop     dx              ; get back where we were
        push    dx
        mov     dh,1            ; column 1
        call    set_cur_pos
        mov     al,ESC
        call    outtty
        mov     al,'L'          ; insert line
        call    outtty
        pop     dx              ; get it back again
        cmp     dh,1
        je      processD1       ; done
        call    set_cur_pos     ; move to final position
processD1:
        jmp     ignore

processE:
        mov     al,CR           ; same as ESC'D', but in col 1
        call    outtty          ; so write out Carriage return
        jmp     processD

processM:
        call    get_cur_pos     ; get cursor position
        cmp     dl,top
        je      insline         ; yes, jump to insert
        dec     dl              ; move up one
        call    set_cur_pos
        jmp     ignore
insline:                        ; perform a scroll-down
        push    dx              ; save current position
        mov     dl,bottom
        mov     dh,1            ; 1. position to bottom margin
        call    set_cur_pos
        mov     al,ESC          ; 2. delete line
        call    outtty
        mov     al,'M'
        call    outtty
        mov     dl,top
        mov     dh,1            ; 3. position to top margin
        call    set_cur_pos
        mov     al,ESC
        call    outtty
        mov     al,'L'          ; 4. insert line with ESC 'L'
        call    outtty
        pop     dx              ; get back my position
        cmp     dh,1            ; first col?
        je      processM1       ; yes
        call    set_cur_pos
processM1:
        jmp     ignore          ; all done

processeq:                      ; set applikation keypad
        mov     ax,ds
        mov     es,ax
        mov     cx,8
        mov     di, offset apptbl.extrtabl
        add     di,START_EXTRTBL ; don't want to start at the top
        cmp     appcur,0        ; cursor keys application ?
        je      peq1
        mov     si,offset curapp
        jmp     peq2
peq1:   mov     si,offset curseq
peq2:   rep     movsw           ; move cursor keys to key-table
        mov     appkeys,1
        mov     bx,offset parmblock
        mov     byte ptr [bx],2
        mov     offs,offset apptbl
        mov     ax,18
        int     SUPERBIOS       ; set new keytable
        jmp     ignore

processgt:                      ; set numeric keypad
        mov     ax,ds
        mov     es,ax
        mov     cx,8
        mov     di, offset numtbl.extrtabl
        add     di,START_EXTRTBL ; don't want to start at the top
        cmp     appcur,0
        je      pgt1
        mov     si,offset curapp
        jmp     pgt2
pgt1:   mov     si,offset curseq
pgt2:   rep     movsw
        mov     appkeys,0
        mov     bx,offset parmblock
        mov     byte ptr [bx],2
        mov     offs,offset numtbl
        mov     ax,18
        int     SUPERBIOS
        jmp     ignore

process7:                       ; save cursor position
        mov     al,ESC
        call    outtty
        mov     al,'j'
        jmp     noesc

process8:                       ; restore cursor position
        mov     al,ESC
        call    outtty
        mov     al,'k'
        jmp     noesc

procmulti:      ; function dispatcher for multi-character escape-sequences
                ; AL has terminating character
        mov     cx,ds
        mov     es,cx
        mov     di,offset mesctbl
        mov     cx,mesclen
        cld
        repnz   scasb
        cmp     al,[di-1]
        jnz     notrec          ; didn't find it in table
        mov     bx,mesclen
        sub     bx,cx           ; get offset in table
        dec     bx
        shl     bx,1
        add     bx,offset mescsub
        jmp     [bx]
notrec: jmp     noesc

curmov: ; process Cursor movements
        cmp     escseq,3        ; has no mumeric argument
        jne     pars
curmov0:
        mov     al,ESC
        call    outtty
        mov     bx,escpnt
        mov     al,[bx]
        jmp     noesc           ; print it without '['
pars:                           ; parse numeric argument
        mov     bx,offset escstring+2 ; skip ESC'['
        call    getnum          ; getnum returns the number in DL
        xor     dh,dh
        cmp     dl,80
        jg      curmovend
        cmp     dl,0
        jl      curmovend
        je      curmov0
        mov     cx,dx           ; becomes loop counter
        mov     bx,escpnt
        mov     bl,[bx]         ; put last char of sequence in bl
parsl2:
        mov     al,ESC
        call    outtty
        mov     al,bl
        call    outtty
        loop    parsl2
curmovend:
        jmp     ignore          ; ignore invalid positioning

procg:
        mov     bx,offset escstring+2
        call    getnum
        cmp     dl,0
        jne     procg1
        call    get_cur_pos
        mov     al,dh           ; current col here
        dec     al              ; range 0 to 79
        mov     bx,offset tabstops
        xor     ah,ah
        add     bx,ax
        mov     byte ptr [bx],0
        jmp     ignore
procg1:
        cmp     dl,3
        jne     procg3
        mov     cx,80
        push    es
        push    ds
        pop     es              ; make sure in right segment
        mov     di,offset tabstops
        xor     ax,ax
        rep     stosb
        pop     es              ; get old es back
procg3:
        jmp     ignore

procE:
        mov     al,CR           ; go to col 1
        call    outtty
procle:
        mov     bx,escpnt
        mov     byte ptr [bx],'B' ; process cursor down
        jmp     curmov

procuF:
        mov     al,CR           ; go to col 1
        call    outtty
        mov     bx, escpnt
        mov     byte ptr [bx],'A' ; cursor up
        jmp     curmov

procuG:
        mov     bx,offset escstring+2
        call    getnum
        cmp     dl,0
        jg      procug1
        mov     dl,1
procug1:
        cmp     dl,80
        jle     procug2
        mov     dl,80
procug2:
        mov     cl,dl
        call    get_cur_pos
        mov     dh,cl           ; set new column
        call    set_cur_pos
        jmp     ignore

procld:
        mov     bx,offset escstring+2
        call    getnum
        cmp     dl,0
        jg      procld1
        mov     dl,1
procld1:
        cmp     dl,24
        jle     procld2
        mov     dl,24
procld2:
        mov     cl,dl
        call    get_cur_pos
        mov     dl,cl
        call    set_cur_pos
        jmp     ignore

procH:                          ; position cursor
        mov     bx,offset escstring+2
        call    getnum
        cmp     dl,1
        jge     procH0
        mov     dl,1            ; provide default for invalid address
procH0:
        cmp     dl,24
        jg      badH
        cmp     byte ptr [bx],';'
        jne     procH01
        inc     bx
procH01:
        push    dx              ; save row value
        call    getnum
        pop     ax              ; get it back here
        cmp     dl,1
        jge     procH1
        mov     dl,1
procH1:
        cmp     dl,80
        jg      badH
        mov     dh,dl           ; get in right places
        mov     dl,al
        call    set_cur_pos
badH:
        jmp     ignore

procL:
        mov     bx,offset escstring+2
        call    getnum
        mov     cx,dx
        cmp     cx,0
        jg      procL0
        mov     cx,1
        jmp     procL1
procL0:
        cmp     cx,24
        jle     procL1
        mov     cx,1
procL1:
        call    get_cur_pos
        mov     bh,dl
        mov     bl,dh           ; save these
procL2:                         ; perform a insert line
        mov     dl,bottom
        mov     dh,1
        call    set_cur_pos
        mov     al,ESC
        call    outtty
        mov     al,'M'
        call    outtty
        mov     dl,bh           ; get in right place
        mov     dh,bl
        call    set_cur_pos
        mov     al,ESC
        call    outtty
        mov     al,'L'
        call    outtty
        loop    procL2
        jmp     ignore

procM:
        mov     bx,offset escstring+2
        call    getnum
        mov     cx,dx
        cmp     cx,0
        jg      procM0
        mov     cx,1
        jmp     procM1
procM0:
        cmp     cx,24
        jle     procM1
        mov     cx,1
procM1:
        call    get_cur_pos
        mov     bh,dl
        mov     bl,dh
procM2:                         ; perform a delete line
        mov     al,ESC
        call    outtty
        mov     al,'M'
        call    outtty
        mov     dl,bottom
        mov     dh,1
        call    set_cur_pos
        mov     al,ESC
        call    outtty
        mov     al,'L'
        call    outtty
        mov     dl,bh           ; get in right places
        mov     dh,bl
        call    set_cur_pos
        loop    procM2
        jmp     ignore

procAt:                         ; insert blank characters
        mov     bx,offset escstring+2
        call    getnum
        mov     cx,dx
        sub     cx,1
        mov     al,ESC
        call    outtty
        mov     al,'@'
        call    outtty
        mov     al,' '
        call    outtty
        mov     al,BS
        call    outtty
        cmp     cx,0
        jle     procat1
procat2:
        mov     al,' '
        call    outtty
        mov     al,BS
        call    outtty
        loop    procat2
procat1:
        mov     al,ESC
        call    outtty
        mov     al,'O'
        call    outtty
        jmp     ignore

procP:
procX:
        mov     bx,offset escstring+2
        call    getnum
        mov     cx,dx
        cmp     cx,0
        jg      procX1
        mov     cx,1
procX1:
        mov     al,ESC
        call    outtty
        mov     al,'N'
        call    outtty
        loop    procX1
        jmp     ignore

procr:                          ; set margins
        mov     top,1
        mov     bottom,24
        mov     bx,offset escstring+2
        call    getnum
        cmp     dl,1
        jl      procr1
        cmp     dl,23
        jg      procr1
        mov     top,dl
procr1:
        inc     bx
        call    getnum
        cmp     dl,top
        jl      procr2
        cmp     dl,24
        jg      procr2
        mov     bottom,dl
procr2:
        mov     dh,1            ; After inspecting what the VAX EDT editor does,

        mov     dl,1            ; it appears that ESC [ Pn r should leave
        call    set_cur_pos     ; the cursor in the upper left corner [bgp]
        jmp     ignore

procc:                          ; Terminal status request
        mov     bx,offset escstring+2
        cmp     byte ptr [bx],'>'
        je      procc2
        cmp     byte ptr [bx],'0'
        je      procc0
        cmp     byte ptr [bx],'c'
        je      procc0
        jmp     ignore
procc0:
        push    wflags          ; need to save these
        and     yflags,not lclecho ; force no echo for these
        mov     al,ESC
        call    outprt
        mov     al,'['
        call    outprt
        mov     al,'?'
        call    outprt
        mov     al,'1'
        call    outprt
        mov     al,';'          ; signal AVO option - we sort of have it
        call    outprt
        mov     al,'2'
        call    outprt
        mov     al,'c'
        call    outprt
        pop     wflags          ; get back old flags
procc2:
        jmp     ignore

procn:                          ; device status report
        mov     bx,offset escstring+2
        cmp     byte ptr [bx],'5'
        je      procn5
        cmp     byte ptr [bx],'6'
        je      procn6
        jmp     ignore
procn5:                         ; return operating status 'no malfunction'
        push    wflags          ; force no echo
        and     yflags,not lclecho
        mov     al,ESC
        call    outprt
        mov     al,'['
        call    outprt
        mov     al,'0'
        call    outprt
        mov     al,'n'
        call    outprt
        pop     wflags
        jmp     ignore
procn6:                         ; report cursor position
        push    wflags          ; force no echo
        and     yflags,not lclecho
        call    get_cur_pos
        mov     al,dh           ; get column here
        sub     al,1fh          ; get binary column
        aam
        add     ax,3030h        ; change to ASCII
        push    ax
        mov     al,dl           ; get line here now
        sub     al,1fh          ; convert to binary
        aam                     ; and to ...
        add     ax,3030h        ; ASCII
        mov     bx,ax
        mov     al,ESC          ; put string out in form : ESC'['line';'col'R'
        call    outprt
        mov     al,'['
        call    outprt
        cmp     bh,30h          ; don't need leading zero
        je      procc61
        mov     al,bh
        call    outprt
procc61:
        mov     al,bl
        call    outprt
        mov     al,';'
        call    outprt
        pop     bx
        cmp     bh,30h
        je      procc62
        mov     al,bh
        call    outprt
procc62:
        mov     al,bl
        call    outprt
        mov     al,'R'
        call    outprt
        pop     wflags          ; get these back
        jmp     ignore

proclm:                         ; do screen attributes
        mov     bx,offset escstring+2
proclm1:
        call    getnum
        cmp     dl,0
        jne     proclm2
        mov     al,ESC
        call    outtty
        mov     al,')'
        call    outtty
        mov     al,ESC
        call    outtty
        mov     al,'q'
        call    outtty
        mov     al,ESC
        call    outtty
        mov     al,'1'
        call    outtty
        jmp     proclm5
proclm2:
        cmp     dl,1
        jne     proclm3
        mov     al,ESC
        call    outtty
        mov     al,'('
        call    outtty
        jmp     proclm5
proclm3:
        cmp     dl,4
        jne     proclm4
        mov     al,ESC
        call    outtty
        mov     al,'0'
        call    outtty
        jmp     proclm5
proclm4:
        cmp     dl,7
        jne     proclm5
        mov     al,ESC
        call    outtty
        mov     al,'p'
        call    outtty
proclm5:
        cmp     byte ptr [bx],'m'
        je      proclm6
        inc     bx
        jmp     proclm1
proclm6:
        jmp     ignore

procJ:
        cmp     escseq,3
        je      procJ0
        mov     bx,offset escstring+2 ; skip ESC'['
        call    getnum
        cmp     dl,0
        je      procJ0
        cmp     dl,1
        je      procJ1
        cmp     dl,2
        je      procJ2
        jmp     ignore          ; ignore others
procJ0:
        mov     al,ESC
        call    outtty
        mov     al,'J'
        jmp     noesc
procJ1:
        mov     al,ESC
        call    outtty
        mov     al,'b'
        jmp     noesc
procJ2:
        mov     al,ESC
        call    outtty
        mov     al,'E'
        jmp     noesc

prochl:
        mov     bx,offset escstring+2 ; skip ESC'['
        call    getnum
        cmp     [escstring+2],'?'
        je      quest
        mov     bx,escpnt
        mov     bl,[bx]         ; contains 'h' or 'l'
        cmp     dl,4
        jne     not4
        mov     al,ESC
        call    outtty
        mov     al,'@'
        cmp     bl,'l'
        jne     enterins
        mov     al,'O'
enterins:
        jmp     noesc
not4:                           ; ignore the others
        jmp     ignore
quest:                          ; sequence like ESC'[?'nn'h'
        mov     bx,escpnt
        mov     bl,[bx]
        cmp     dl,1
        jne     not1
        mov     cx,8
        cmp     appkeys,0
        je      q1
        mov     offs,offset apptbl
        mov     di, offset apptbl.extrtabl
        jmp     q2
q1:     mov     offs,offset numtbl
        mov     di, offset numtbl.extrtabl
q2:     add     di,START_EXTRTBL ; don't want to start at the top
        cmp     bl,'l'
        je      q3
        mov     si,offset curapp
        mov     appcur,1
        jmp     q4
q3:     mov     si,offset curseq
        mov     appcur,0
q4:     rep     movsw
        mov     bx,offset parmblock
        mov     byte ptr [bx],2
        mov     ax,18
        int     SUPERBIOS
        jmp     ignore
not1:
        cmp     dl,5
        jne     not5
        mov     al,ESC
        call    outtty
        mov     al,'p'
        cmp     bl,'h'
        je      isreverse
        mov     al,'q'
isreverse:
        jmp     noesc
not5:
        cmp     dl,7
        jne     not7
        mov     al,ESC
        call    outtty
        mov     al,'v'
        cmp     bl,'h'
        je      autowrap
        mov     al,'w'
autowrap:
        jmp     noesc
not7:                           ; ignore the others
        jmp     ignore

procK:
        cmp     escseq,3
        je      procK0
        mov     bx,offset escstring+2 ; skip ESC'['
        call    getnum
        cmp     dl,0
        je      procK0
        cmp     dl,1
        je      procK1
        cmp     dl,2
        je      procK2
        jmp     ignore          ; ignore others
procK0:
        mov     al,ESC
        call    outtty
        mov     al,'K'
        jmp     noesc
procK1:
        mov     al,ESC
        call    outtty
        mov     al,'o'
        jmp     noesc
procK2:
        mov     al,ESC
        call    outtty
        mov     al,'l'
        jmp     noesc

noesc:                          ; That wasn't valid! (or print last char)
        or      al,chrset_mask  ; set top bit right for specified set
        call    outtty          ; print it out...
ignore:                         ; Here to flag end of escape or ignore
        mov     escseq,0        ; one that we don't like
doansi_d:
        ret                     ; Here when we have no more to do
DOANSI  endp

; GETNUM gets a number from escapestring, returns it in DL.
;   Input: pointer in BX.  Destroys BX, CX, DH. Finishes on first
;   encounteder non-numeric char except '-'.     Assumes correct syntax
;   ('-' only as first char - checked in procmulti)

GETNUM  proc    near
        xor     dx,dx
        cmp     bx,escpnt       ; is it to end of string already?
        jge     getn4           ; yes - just exit with zero
        xor     ch,ch           ; assume positive number
        cmp     byte ptr [bx],'?' ; first char may be a questionmark
        jne     getn1
        inc     bx
getn1:
        mov     cl,[bx]
        cmp     cl,';'
        je      getn3
        cmp     cl,'-'
        jne     getn2
        mov     ch,-1
getn2:
        cmp     cl,'0'
        jl      getn3
        cmp     cl,'9'
        jg      getn3
        sub     cl,'0'
        shl     dl,1            ; multiply by 10 (=1010b)
        mov     dh,dl
        shl     dl,1
        shl     dl,1
        add     dl,dh
        add     dl,cl
        inc     bx
        cmp     bx,escpnt
        jl      getn1
getn3:
        cmp     ch,-1
        jne     getn4
        neg     dx
getn4:
        ret
GETNUM  endp

; initialize keyboard and tables to build it [as]

INITANSI proc   near
        cld
        mov     bx,ds
        mov     es,bx
        mov     bx,offset parmblock
        mov     ax,18
        int     SUPERBIOS       ; get old keyboard
        or      ax,ax
        jz      ansi01
        jmp     aend
ansi01: mov     cx,598          ; copy it
        mov     si,offset oldtable
        mov     di,offset numtbl
        rep     movsw
        mov     si,offset numtbl ; Index in Table
        mov     byte ptr [si].kd0+25,7fh ; DEL to Backspace-key

; set cursorkeys
        mov     word ptr [si].kd12+2*88,0A000h  ;
        mov     word ptr [si].kd12+2*89,0A000h  ; with auto-repeat
        mov     word ptr [si].kd12+2*98,0A000h
        mov     word ptr [si].kd12+2*99,0A000h
        mov     byte ptr [si].kd0+88,START_EXTRTBL ; offset in EXTRtabl
        mov     byte ptr [si].kd0+89,START_EXTRTBL+4
        mov     byte ptr [si].kd0+98,START_EXTRTBL+8
        mov     byte ptr [si].kd0+99,START_EXTRTBL+12
        mov     di,offset numtbl.extrtabl
        add     di,START_EXTRTBL ; Don't want to overwrite stuff
        mov     si,offset curseq
        mov     cx,8
        rep     movsw           ; move the new sequences to keytable

; copy complete table to build Applikation-keypad-table
        mov     cx,598
        mov     si,offset numtbl
        mov     di,offset apptbl
        rep     movsw

; now build keypad
        mov     si,offset apptbl
        mov     word ptr [si].kd12+2*28,8000h
        mov     word ptr [si].kd12+2*29,8000h
        mov     word ptr [si].kd12+2*30,8000h
        mov     word ptr [si].kd12+2*31,8000h
        mov     word ptr [si].kd12+2*49,8000h
        mov     word ptr [si].kd12+2*50,8000h
        mov     word ptr [si].kd12+2*51,8000h
        mov     word ptr [si].kd12+2*52,8000h
        mov     word ptr [si].kd12+2*69,8000h
        mov     word ptr [si].kd12+2*70,8000h
        mov     word ptr [si].kd12+2*71,8000h
        mov     word ptr [si].kd12+2*72,8000h
        mov     word ptr [si].kd12+2*90,8000h
        mov     word ptr [si].kd12+2*91,8000h
        mov     word ptr [si].kd12+2*92,8000h
        mov     word ptr [si].kd12+2*93,8000h
        mov     word ptr [si].kd12+2*100,8000h
        mov     word ptr [si].kd12+2*102,8000h
        mov     byte ptr [si].kd0+28,START_EXTRTBL+16 ; offset in EXTRtabl
        mov     byte ptr [si].kd0+29,START_EXTRTBL+20
        mov     byte ptr [si].kd0+30,START_EXTRTBL+24
        mov     byte ptr [si].kd0+31,START_EXTRTBL+28
        mov     byte ptr [si].kd0+49,START_EXTRTBL+32
        mov     byte ptr [si].kd0+50,START_EXTRTBL+36
        mov     byte ptr [si].kd0+51,START_EXTRTBL+40
        mov     byte ptr [si].kd0+52,START_EXTRTBL+44
        mov     byte ptr [si].kd0+69,START_EXTRTBL+48
        mov     byte ptr [si].kd0+70,START_EXTRTBL+52
        mov     byte ptr [si].kd0+71,START_EXTRTBL+56
        mov     byte ptr [si].kd0+72,START_EXTRTBL+60
        mov     byte ptr [si].kd0+90,START_EXTRTBL+64
        mov     byte ptr [si].kd0+91,START_EXTRTBL+68
        mov     byte ptr [si].kd0+92,START_EXTRTBL+72
        mov     byte ptr [si].kd0+93,START_EXTRTBL+76
        mov     byte ptr [si].kd0+100,START_EXTRTBL+80
        mov     byte ptr [si].kd0+102,START_EXTRTBL+84
        mov     di,offset apptbl.extrtabl
        add     di,START_EXTRTBL ; avoid overwriting stuff...
        mov     si,offset applik
        mov     cx,44
        rep     movsw           ; move new keycodes to table
        mov     bx,offset parmblock
        mov     byte ptr [bx],2
        mov     offs,offset numtbl ; set numeric keypad
        mov     ax,18
        int     SUPERBIOS
aend:
        ret
INITANSI endp

; Save old keyboard stuff when exiting [as]

FINIANSI proc   near
        mov     bx,offset parmblock
        mov     byte ptr [bx],2
        mov     dx,offset oldtable
        xchg    dx,offs         ; save old keyboard-type in dx
        mov     ax,18
        int     SUPERBIOS
        xchg    dx,offs         ; restore old keyboard-type
        ret
FINIANSI endp

; Get the current cursor location - row in dl, col in dh
; (1,1) is upper left corner

GET_CUR_POS proc near
        mov     al,ESC          ; request cursor location
        call    outtty
        mov     al,'n'
        call    outtty
        mov     ah,CONINQ       ; input no check
        int     DOS             ; gets the ESC
        int     DOS             ; gets the Y
        int     DOS
        sub     al,31
        mov     dl,al
        int     DOS
        sub     al,31
        mov     dh,al
        ret
GET_CUR_POS endp

; Set the cursor location - row in dl, col in dh
; (1,1) is upper left corner

SET_CUR_POS proc near
        push    dx              ; save it to be sure
        mov     al,ESC
        call    outtty
        mov     al,'Y'
        call    outtty
        pop     dx
        push    dx
        mov     al,dl           ; row
        add     al,31
        call    outtty
        pop     dx
        push    dx
        mov     al,dh           ; column
        add     al,31
        call    outtty
        pop     dx
        ret
SET_CUR_POS endp

; Save the screen so we can restore it

SAVESCR proc    near
        call    get_cur_pos     ; get cursor location
        mov     curloc,dl       ; this is line number
        mov     curloc+1,dh     ; this is column number
        mov     bx,SEG_CRTC     ; where crt controller is
        mov     es,bx
        mov     bx,OFF_CRTC
        mov     byte ptr es:[bx],12
        mov     ah,es:1[bx]
        and     ah,7            ; only want bottom 3 bits
        mov     byte ptr es:[bx],13
        mov     al,es:1[bx]
        shl     ax,1            ; multiply by 2 (was word address)
        mov     si,ax
        push    ds
        pop     es
        mov     ds,scrseg
        mov     di,offset screen
        mov     cx,1920
        rep     movsw
        push    es
        pop     ds
        call    cmblnk          ; let them start with a blank one
        ret                     ; and return
SAVESCR endp

; Restore screen from scrsav buffer

RESTSCR proc    near
        call    cmblnk          ; start with a clear screen
        mov     si,offset screen
        mov     es,scrseg
        xor     di,di           ; start at start
        mov     cx,1920         ; 1920 words to go
        rep     movsw
        mov     dx,word ptr curloc ; get cursor location
        call    set_cur_pos
        ret
RESTSCR 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.
; This reads the screen that was last saved by savescr - it is expected
; that savescr will be called just before this one
; 30 July 1986 Add this routine - it is pirated from the file MSYIBM and
; modified to match the Victor's needs  [bgp]

DUMPSCR proc    near
        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:   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    clrmod                  ; clear place for mode line
        mov     dx,offset dmperr        ; get string to put there
        call    putmod                  ; on mode line...
        pop     dx
        pop     cx
        pop     bx
        pop     ax
        ret

dmp1:   push    di                      ; read screen buffer, write lines
        push    si
        push    es
        push    ds
        pop     es                      ; make sure this is right
        mov     cx,24                   ; 24 lines in buffer
        mov     si,offset screen        ; where screen is saved
dmp2:   push    cx                      ; save outer loop counter
        mov     di,offset dumpbuf       ; data segement memory
        mov     cx,80                   ; 80 columns
dmp3:   mov     ax,word ptr es:[si]     ; read char + attribute
        and     ax,7FFH                 ; take off attributes
        sub     ax,char_base            ; minus base
        mov     byte ptr [di],al        ; store the char
        inc     si                      ; update pointers
        inc     si
        inc     di
        loop    dmp3                    ; do for each column
        std                             ; set scan backward
        mov     cx,80                   ; 80 columns
        mov     di,offset dumpbuf+79    ; end of line
        mov     al,' '                  ; thing to scan over
        repe    scasb                   ; scan until non-space
        cld                             ; set direction forward
        jz      dmp3a                   ; z = all spaces
        inc     cx
        inc     di
dmp3a:  mov     word ptr [di+1],0A0Dh   ; append cr/lf
        add     cx,2                    ; line count + cr/lf
        mov     dx,offset dumpbuf       ; array to be written
        mov     bx,dmphand              ; need file handle
        mov     ah,WRITE2               ; write the line
        int     DOS
        pop     cx                      ; get line counter again
        loop    dmp2                    ; do next line
        mov     dx,offset dumpsep       ; put in formfeed/cr/lf
        mov     cx,3                    ; three bytes overall
        mov     ah,WRITE2               ; write them
        mov     bx,dmphand              ; file handle
        int     DOS
        mov     ah,CLOSE2               ; close the file now
        int     DOS
dmp6:   pop     es
        pop     si
        pop     di
        pop     dx
        pop     cx
        pop     bx
        pop     ax
        ret
DUMPSCR endp

; Send the character in al out to the serial port
; Handle echoing also...

OUTPRT  proc    near
        test    yflags,lclecho  ; echoing?
        jz      outpr1          ; no, forget it
        cmp     flags.vtflg,TTVT100 ; doing VT100?
        jz      outpr0          ; yes - echo it nicely
        push    ax              ; save char
        call    outtty          ; print it
        pop     ax              ; restore
        jmp     outpr1
outpr0:
        push    ax              ; save char
        call    doansi
        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 character from the serial port in al
; returns with carry on if a character is available

PORTCHR proc    near
        call    prtchr          ; character at port?
         jmp    short portc1    ; yes, go handle
        nop                     ; skip return is stupid...
        clc                     ; no carry -> no character
        ret                     ; and return...
portc1:
        and     al,7fh          ; we don't worry about parity here
        stc                     ; have a character
        ret                     ; and return
PORTCHR endp

; Put the character in al to the screen
; Directly call the console-driver to get better speed (4 times, ~19200
; baud)  [as]

OUTTTY  proc    near
        call    capture
        push    ax              ; these are modified by the driver
        push    bx
        push    cx
        push    dx
        push    si
        push    es
        mov     cl,al
        mov     ax,1
        call    dword ptr drivadr
        pop     es
        pop     si
        pop     dx
        pop     cx
        pop     bx
        pop     ax
        ret                     ; through
OUTTTY  endp

; Capture char in al to a file if we are supposed to

CAPTURE proc    near
        test    yflags,CAPT     ; capturing output?
        jz      nocap           ; no forget this part
        push    ax              ; save it
        call    captrtn
        pop     ax              ; get char back
nocap:
        test    flags1,PRTSCR   ; should we be printing?
        jz      noprt           ; no, go on
        push    ax              ; save char
        mov     ah,LSTOUT
        mov     dl,al
        int     DOS             ; out it goes
        pop     ax
noprt:
        ret
CAPTURE endp

; Set heath emulation on/off.

VTS     proc    near
        mov     dx,offset termtbl
        mov     bx,offset termhlp
        mov     ah,CMKEY
        call    comnd
         jmp    vt1
        push    bx
        mov     ah,CMCFM
        call    comnd           ; Get a confirm.
         jmp    vt0             ;       Didn't get a confirm.
         nop
        pop     bx
        mov     flags.vtflg,bl  ; Set the emulation flag.
        ret
vt0:
        pop     bx
vt1:
        ret
VTS     endp

VTSTAT  PROC    NEAR    ; For Status display [jrd]
        ret             ; no emulator status to display
VTSTAT  ENDP

CODE    ends

        end

