home *** CD-ROM | disk | FTP | other *** search
/ Columbia Kermit / kermit.zip / mskermit / msyz10.asm < prev    next >
Assembly Source File  |  2020-01-01  |  75KB  |  2,421 lines

  1.     NAME    msyz10
  2. ; File MSYZ10.ASM
  3.     include mssdef.h
  4. ;       Copyright (C) 1982,1991, Trustees of Columbia University in the
  5. ;       City of New York.  Permission is granted to any individual or
  6. ;       institution to use, copy, or redistribute this software as long as
  7. ;       it is not sold for profit and this copyright notice is retained.
  8. ; Kermit system dependent module for Heath/Zenith Z100
  9. ; Edit history
  10. ; 2 March 1991 version 3.10
  11. ; Last change: 3 November 1990.
  12. ; Minor changes to outtty and outprt.  Added setchtab, modified termtb.
  13. ; Putcirc and getcirc have been modified from msyibm and added but remains
  14. ; untested and inactive.  VTS and VTSTAT and most of the corresponding data
  15. ; is kept in msx in order to allow assemly of this file , msy, with MASM 4.
  16. ; Procedures savescr, restscr, atsclr and setcol added and calls to these
  17. ; added to scrini and quit.  Procedure revscn (2 variants) added.
  18. ; Procedure dumpscr moved from msxz10.asm and restructured to allow general
  19. ; use of some code now put in local subroutines rdset, rdlne and endfix. 
  20. ; Procedure scroll added, to allow 26 lines scrolling entirely in video
  21. ; memory, provided 64k video ram chips are installed.
  22. ; Handling of ESC E and ESC J in outtty for the S-100 ports, COM3/COM4,
  23. ; refined.
  24. ; Getpos and setpos corrected (dl = col, dh = row, comments incorrect in 
  25. ; msyibm.asm).
  26. ;
  27. ; Bo Gedda
  28. ;
  29.  
  30.     public    term, lclyini, holdscr, scroll, savescr, restscr, atsclr
  31.     public    outprt, prtbout, chrout, vclick, vtemu, yflags
  32.     public    cquit, udkclear, low_rgt, vtclear, getpos, setpos
  33.     public    csrtype, termtb, comptab, ontab, beltab
  34.     public    scrtab, curtab, chatab, cntltab, kpamtab, dirtab
  35.     public    vtbell, dumpscr, fcsrtype
  36.     public    f0, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, sf0
  37.     public    sf1, sf2, sf3, sf4, sf5, sf6, sf7, sf8, sf9, sf10, sf11
  38.     public    i_chr, d_chr, i_line, d_line
  39.     public    uparrw, dnarrw, rtarr, lfarr, pf1, pf2, pf3, pf4
  40.     public    kp0, kp1, kp2, kp3, kp4, kp5, kp6, kp7, kp8, kp9
  41.     public    kpminus, kpcoma, kpenter, kpdot, cstatus, cquit
  42.     public    out8bit, trnmod, cdos, cquery, chang, trnprs, dmpscn
  43.     public    homwnd, endwnd, dnwpg, upwpg, upone, dnone, klogon, klogof
  44.     public    snull, doscol, setcol, revscn, lincur
  45.     public    belltype, vtroll, setchtab
  46.     public    extmacro, vtmacname, vtmaclen
  47.  
  48. true        equ    1
  49. false        equ    0
  50. delaycount    equ    1fffh    ; Range 1h to 0h (ffffh + 1h = 0h!)
  51.  
  52. ; Entry points to ROM monitor
  53.  
  54. MTR_SEG    SEGMENT    AT 0FE01H    ; Segment addr for Monitor ROM calls
  55.     ORG    000H
  56.   MTR_RES    LABEL    FAR    ; Reset function
  57.     ORG    005H
  58.   MTR_MON    LABEL    FAR    ; Monitor call
  59.     ORG    00AH
  60.   MTR_SWIM    LABEL    FAR    ; Trace/breakpoint handler
  61.     ORG    00FH
  62.   MTR_DCRT    LABEL    FAR    ; Dumb display output
  63.     ORG    014H
  64.   MTR_DKBD    LABEL    FAR    ; Dumb keyboard handler
  65.     ORG    019H
  66.   MTR_SCRT    LABEL    FAR    ; Smart display output
  67.     ORG    01EH
  68.   MTR_SKBD    LABEL    FAR    ; Smart keyboard input
  69.     ORG    023H
  70.   MTR_TTY_INTR    LABEL    FAR    ; Vertical retrace interrupt handler
  71. MTR_SEG    ENDS
  72.  
  73. MTR_D_SEG SEGMENT AT 0        ; Monitor data segment(not really at 0)
  74.     ORG    000H
  75.  
  76. ; Monitor Parameters
  77.   MTR_WIP    LABEL    FAR    ; Far jump to wild interrupt handler
  78.         DB 5 DUP(?)    ; the far jump
  79.   MTR_VER    DB ?        ; BCD version of ROM monitor
  80.     MTR_CVER      EQU 01H      ; Lowest version BIOS can run on
  81.   MTR_DS_SIZE    DW ?        ; Size of the ROM monitor data segment
  82.  
  83. ; Boot parameters
  84.   MTR_BINDX    DB ?        ; Boot device index
  85.   MTR_BPORT    DB ?        ; Boot device base port number
  86.   MTR_BSTRING    DB 80 DUP(?)    ; Boot string
  87.   MTR_BUNIT    DB ?        ; Boot unit number
  88.  
  89.  
  90. ; Pointers to All sorts of things
  91.   MTR_DCI    DD ?        ; Addr of Display Character Initialization
  92.   MTR_DFC    DD ?        ; Addr of Display Font Character Routine
  93.   MTR_DXMTC    DD ?        ; Addr of Dumb Keyboard Transmit Character
  94.   MTR_EDC    DD ?        ; Addr of Erase Display Character Routine
  95.   MTR_EMEC    DD ?        ; Addr of Escape Character Handler Routine
  96.   MTR_FONT    DD ?        ; Addr of Character Font table
  97.     MTR_FNT_SIZE  EQU 9*(256-' ') ; Size of reserved font table
  98.                   ;  number of bytes copied from rom font
  99.                   ;  area if version = 1)
  100.   MTR_MDC    DD ?        ; Addr of Move Display Characters Routine
  101.   MTR_MDL    DD ?        ; Addr of Move Display Line Routine
  102.   MTR_PROMPT    DD ?        ; Addr of Display ROM Monitor Prompt Routine
  103.   MTR_RDC    DD ?        ; Addr of Read Displayed Character Routine
  104.   MTR_SXMTC    DD ?        ; Addr of Smart Keyboard Transmit Character
  105.   MTR_UIES    DD ?        ; Addr of Unimplemented Escape Sequence
  106.   MTR_XCA    DD ?        ; Addr of Transmit Character Attributes
  107.   MTR_FNTSIZ    DW ?        ; Size of FONT in bytes (If version > 1)
  108.   MTR_KYB    DB 256 DUP (?)    ; Keyboard map table
  109.   MTR_CHR    DB 256 DUP (?)    ; Display map table
  110.   MTR_HORP    DB ?        ; Horizontal position of cursor (column)
  111.   MTR_VERP    DB ?        ; Vertical position of cursor (row)
  112.   MTR_MIB    DB ?        ; Base interrupt number for master
  113.   MTR_SIB    DB ?        ; Base interrupt number for slave
  114.   MTR_RESF    DB ?        ; Reset flag to re-enter monitor
  115.  
  116. ; Color structure
  117.     ORG    2A1H
  118.  FORE        DB ?        ; Current foreground color
  119.  BACK        DB ?        ; Current backpround color
  120.  MSK        DB ?        ; Color to mask
  121.  CLEAR        DB ?        ; Color to clear
  122.  PAINTED    DB ?        ; Color to paint
  123.  PFONT        DB ?        ; Color to set to font pattern
  124.  COMP_FONT    DB ?        ; Color to set to complement of font pattern
  125. ; These are the new ones
  126.  BACK_CB    DB ?        ; Back control bits
  127.  BACK_SEG    DW ?        ; Back segment
  128.  CP_BACK_CB    DB ?        ; Complement back control bits
  129.  CP_BACK_SEG    DW ?        ; Complement back segment
  130.  CLEAR_CB    DB ?        ; Clear control bits
  131.  CLEAR_SEG    DW ?        ; Clear segment
  132.  PAINTED_CB    DB ?        ; Painted control bits
  133.  PAINTED_SEG    DW ?        ; Painted segment
  134.  PFONT_CB    DB ?        ; Font control bits
  135.  PFONT_SEG    DW ?        ; Font segment
  136.  CP_FONT_CB    DB ?        ; Complement font control bits
  137.  CP_FONT_SEG    DW ?        ; Complement font segment
  138.  
  139. ; CRT-C display structure
  140.     ORG    2BDH
  141.   DISP_START    DW ?        ; CRT-C display start address
  142.   DISP_UPDATE    DB ?        ; FF to request update
  143.  
  144. ; H-19 mode structure
  145.     ORG    2D1H
  146.   BWO        DB ?        ; Black/white optimization
  147.     ORG    2DBH
  148.   STATUS    DB ?        ; FF modeline on, 0 modline off
  149.  
  150. ; H-19 parameter structure
  151.     ORG    2E1H
  152.   PROVRAM    DB ?        ; 0 = monochrome, 3 = color
  153.     ORG    2E6H
  154.   VRAM_SIZE    DB ?        ; 0 = 32k, 1 = 64k
  155. MTR_D_SEG ENDS
  156.  
  157. IPAGE_SEG SEGMENT AT 0        ; The interrupt area page
  158.     ORG    03FEH
  159.   MTR_DS    LABEL WORD    ; Location that contains monitor DS value
  160. IPAGE_SEG ENDS
  161.  
  162. ;bios definitions
  163. BIOS_SEG SEGMENT AT 40H        ; Define segment where BIOS really is
  164.     ORG    1*3
  165. BIOS_STATUS    LABEL FAR    ; Console input status
  166.     ORG    2*3
  167. BIOS_CONIN    LABEL FAR    ; Console input
  168.     ORG    3*3
  169. BIOS_CONOUT    LABEL FAR    ; Console output
  170.     ORG    4*3
  171. BIOS_PRINT    LABEL FAR    ; Printer output
  172.     ORG    6*3
  173. BIOS_AUXOUT    LABEL FAR    ; AUX output routine
  174.     ORG    25*3
  175. BIOS_PRNFUNC    LABEL FAR    ; PRN: FUNCTION
  176.     ORG    26*3
  177. BIOS_AUXFUNC    LABEL FAR    ; AUX: function
  178.     ORG    27*3
  179. BIOS_CONFUNC    LABEL FAR    ; CON: function
  180. BIOS_SEG ENDS
  181.  
  182. ;  Define functions of BIOS_CONFUNC, BIOS_PRNFUNC, and BIOS_AUXFUNC
  183. CHR_WRITE    EQU 0        ; Write function
  184. CHR_READ    EQU CHR_WRITE+1 ; Read function
  185. CHR_STATUS    EQU CHR_READ+1    ; Status function
  186.   CHR_SFGS      EQU 0          ; Get status subfunction
  187.     CHRS_WA        EQU 00000001B   ; <ETX> sent, waiting for <ACK>
  188.     CHRS_WD        EQU 00000010B   ; <DC3> seen, waiting for <DC1>
  189.     CHRS_SN        EQU 00000100B   ; Sending nulls
  190.     CHRS_TXR        EQU 10000000B   ; Transmitter ready to send data
  191.     CHRS_RXR        EQU 01000000B   ; Receiver has data 
  192.     CHRS_RXOF        EQU 00100000B   ; Receiver queue overflow
  193.     CHRS_RXE        EQU 00010000B   ; Other type of reciver error
  194.     CHRS_TXE        EQU 00001000B   ; Transmitter error
  195.   CHR_SFGC      EQU CHR_SFGS+1  ; Get configuration info subfunction
  196. CHR_CONTROL    EQU CHR_STATUS+1 ; Control function
  197.   CHR_CFSU      EQU 0          ; Setup new configuration parms subfunction
  198.   CHR_CFCI      EQU CHR_CFSU+1  ; Clear input subfunction
  199.   CHR_CFCO      EQU CHR_CFCI+1  ; Clear output subfunction
  200. CHR_LOOK    EQU CHR_CONTROL+1; Nondestructive read function
  201. CHR_FMAX    EQU CHR_LOOK    ; Maximum function number
  202.  
  203. ; Z-100 Keyboard commands
  204. keyrst    equ    00h        ; reset
  205. keyrpon equ    01h        ; auto repeat on
  206. keyrpof equ    02h        ; auto repeat off
  207. keyclon equ    03h        ; click on
  208. keyclof equ    04h        ; click off
  209. keyclr    equ    05h        ; clear buffer
  210. keycli    equ    06h        ; make key click
  211. keybel    equ    07h        ; make bell sound
  212. keyena    equ    08h        ; enable keyboard
  213. keydis    equ    09h        ; disable keyboard
  214. keyeve    equ    0ah        ; make keyboard event driven (up/down mode)
  215. keyasc    equ    0bh        ; make keyboard scan ascii
  216. keyiena equ    0ch        ; enable interrupt
  217. keyidis equ    0dh        ; disable interrupt
  218.  
  219. ; Definitions for cursor type.
  220. ; bit 0 set = 1 => Cursor on        cleared = 0 => Cursor off
  221. ; bit 1 set = 2 => Block cursor        cleared = 0 => Underline cursor 
  222. ; bit 2 set = 4 => Non blinking cursor    cleared = 0 => Blinking cursor
  223. cur_on    equ    1        ; 00000001b
  224. cur_blo equ    2        ; 00000010b
  225. cur_nob equ    4        ; 00000100b
  226.  
  227. ; Miscellaneous scan codes used for functions
  228. prscan    equ    0a2h        ; print-screen scan code (F12)...
  229. brkscan equ    0aah        ; Break key
  230.  
  231. COLUMNS EQU    80        ; Characters per screen line
  232. ROWS    EQU    24        ; Text lines per screen
  233. VID_CMD EQU    0d8h        ; Video-memory control port
  234. VID_NOR    EQU    01111000b    ; Video access on, individual color write
  235.                 ;  only, all colors displayed
  236. PAR_GRN EQU    0e000h        ; Green video plane segment address
  237. PAR_RED EQU    0d000h        ; Red    video plane segment address
  238. PAR_BLU EQU    0c000h        ; Blue    video plane segment address
  239.  
  240. ; Kinds of terminals available
  241. ;ttgenrc equ    0            ; Type 0: no emulation done by Kermit
  242. ;ttheath equ    1            ; Type 1: Heath-19
  243. ;ttvt52 equ    2            ; Type 2: VT52
  244. ;ttvt100 equ    3            ; Type 3: VT102
  245. ;TTTYPES equ    4            ; Number of terminal types defined
  246.  
  247. ; DEC emulator status flags (bits in words vtemu.vtflgst and vtemu.vtflgop)
  248. ;anslnm     equ    1H            ; ANSI line feed/new line mode
  249. ;decawm     equ    2H            ; DEC autowrap mode
  250. ;decscnm equ    80H            ; DEC screen mode
  251. ;decckm     equ    200H            ; DEC cursor keys mode
  252. ;deckpam equ    400H            ; DEC keypad application mode
  253. ;decom     equ    800H            ; DEC origin mode
  254. ;deccol equ    1000H            ; DEC column mode (0=80 col)
  255. ;decanm     equ    2000H            ; ANSI mode
  256. ;dececho equ    4000H            ; ANSI local echo on (1 = on)
  257. ;
  258. ; Terminal SETUP mode flags (joint with bits above, some name dups)
  259. ;vsnewline    equ    1H        ; ANSI new line (0 = off)
  260. ;vswrap        equ    2H        ; Line wrap around (0 = no wrap)
  261. ;vsnrcm        equ    4H        ; National Rep Char set (0=none)
  262. ;vswdir        equ    8H        ; Writing direction (0=left, 1 right)
  263. ;vskeyclick    equ    10H        ; Keyclick (0 = off)
  264. ;vsmarginbell    equ    20H        ; Margin bell (0 = off)
  265. ;vscursor    equ    40H        ; Cursor (0 = block, 1 = underline)
  266. ;vsscreen    equ    80H        ; Screen (0 = normal, 1 = rev. video)
  267. ;vscntl        equ    100h        ; 8 or 7 bit controls (1 = 8-bit)
  268.  
  269. ; bit for flag byte
  270. havtt    equ 10h                ; have translate table
  271.  
  272. modfrm    struc                ; format of mode line
  273.     db    'Esc chr: '
  274. m_echr    db    2 dup (?)
  275.     db    ' Help: '
  276. m_hlp    db    2 dup (?)
  277.     db    '?'
  278.     db    ' Port: '
  279. m_prt    db    1 dup (?)
  280.     db    ' Speed: '
  281. m_baud    db    4 dup (?)
  282.     db    ' Parity: '
  283. m_par    db    4 dup (?)
  284.     db    ' Echo: '
  285. m_echo    db    3 dup (?)
  286.     db    ' '
  287. m_emul    db    10 dup (?)
  288. m_pad    db    1 dup (?)
  289.     db    ' '
  290. m_prn    db    3 dup (?)
  291.     db    '$'
  292. modfrm    ends
  293.  
  294. data    segment
  295.     extrn    flags:byte, caplft:byte, portval:word, trans:byte
  296.     extrn    klen:word, ktab:word, krpl:word, flowon:byte, flowoff:byte
  297.     extrn    dosnum:word, kbdflg:byte, kbcodes:byte, npages:word
  298.     extrn    taklev:byte, takadr:word, mcctab:byte, dupflg:byte
  299.     extrn    ttyact:byte, dmpname:byte, filtst:byte, rdbuf:byte
  300.     extrn    prnhand:word
  301.  
  302. anspflg db    0            ; printer flag bits and definitions
  303.  
  304. vtmacname dw    0            ; pointer to selected macro name
  305. vtmaclen db    0
  306. udkseg    dw    18 dup (0)        ; segment of user definable key defs
  307. oldsp    dw    0            ; offset to longjmp to for i/o failure
  308. inited    equ    08h            ; been here before
  309. vtinited db    0            ; flag for emulator having been inited
  310. cursor    dw    0
  311. lincur    dw    ?            ; cursor type save area
  312. doscol    db    ?,?            ; foreground col, background col
  313. tercol    db    6,0            ; foreground col, background col
  314. dosattr db    ?            ; screen attributes at init time
  315. tv_segs dw    0            ; Topview virtual screen, segment
  316. tv_sego dw    0            ; and offset
  317. yflags    db    0            ; status flags
  318. argadr    dw    ?            ; address of arg blk
  319. savadr    dw    2 dup (0)        ; offset then segment of saved screen
  320. trmtyp    dw    0            ; most recent terminal type
  321. vtclear db    0            ; nonzero to redo emulator screen
  322. insert    db    'O'            ; flag for overwrite/insert mode, O/@
  323. temp    dw    0            ; scratch storage
  324. pntmsg    db    'Printer not ready, printing request skipped$'
  325. pntptr    dw    dumpbuf            ; pointer to next free byte in buffer
  326. dumplen equ    132
  327. dumpbuf db    dumplen dup (?)        ; / 134 byte dump work buffer
  328. crlf    db    cr,lf,'$'        ; \ needs these too
  329. scbattr db    ?            ; screen background attribute
  330. belltype db    0            ; 0 = aural bell, 1 = visual
  331. fairness dw    0
  332. savattr db    78h            ; cur. emul. attrib., 78h = all colors
  333. fairprn dw    0
  334. parmsk    db    0            ; 8/7 bit parity mask, for reception
  335. captrtn dw    0            ; routine to call for captured output
  336. portno    db    0
  337. memerr    db    cr,lf,'Not enough memory for terminal emulator$'
  338.  
  339. vstate    db    0            ; Video ram port-status at invocation.
  340. int_cy    dw    0            ; Vertical screen index (line number).
  341. line    db    (COLUMNS+4) dup (0)    ; Screen's line buffer.
  342. lines    dw    0            ; Number of lines valid on screen.
  343. eos    db    0            ; flag: 0= not end of screen, 1= yes.
  344. dmphand dw    ?            ; screen dump file handle [jrd]
  345. dmperr    db    cr,' Cannot open save screen file $'
  346. dmperr1 db    cr,' Cannot write save screen file $'  
  347. holdscr db    0        ; Hold-Screen, non-zero to stop reading
  348.  
  349. ; storage for multi-window stuff
  350. swidth    equ    COLUMNS            ; max screen width, 80
  351. slen    equ    ROWS            ; and length of text, 24
  352. crt_norm db    3            ; video mode for normal screen
  353. crt_mode db    3            ; video mode (typ 3, must be text)
  354. crt_cols db    COLUMNS            ; number of screen columns (typ 80)
  355. crt_lins db    ROWS            ; number of screen rows - 1 (typ 24)
  356. low_rgt dw    174fh            ; lower right corner of text window
  357. startad    dw    0            ; storage for CRTC Start Address
  358. refresh    db    0            ; screen refresh (0=wait for retrace)
  359. vtroll    db    0            ; auto roll back allowed (0 = no)
  360.  
  361. inipara dw    0            ; initial paragraphs of scroll memory
  362.     even                ; screen rollback material
  363. iniseg    dw    ?            ; (BDT) initial seg of scroll memory
  364. ppl    dw    0            ; (BDT) paragraphs per line
  365. lcnt    dw    0            ; (BDT) number of "filled" buffer lines
  366. linef    dw    0            ; (BDT) "first" filled line is here
  367. linec    dw    0            ; (BDT) "current" screen line number
  368. linee    dw    0            ; (BDT) total # of lines in the buffer
  369. lmax    dw    0            ; (BDT) max lines in buff (less 1 scrn)
  370. lxtra    dw    0            ; (BDT) "extra" lines rqd for screen
  371.                     ; begin video ram complement storage
  372. vidmsg    db    cr,' Cannot scroll, need 64k video ram $'
  373. mtrmsg    db    cr,lf,'Monitor boot rom must be Version 2.5 or above.  Refer '
  374.     db    'to your Z-100 Manual$',cr,lf
  375.                     ; begin Terminal emulator data set
  376. setchtab db    6            ; Set File Character-Set table
  377.     mkeyw    'CP437',437        ; hardware default Code Page
  378.     mkeyw    'CP850',850        ; Multilingual CP
  379.     mkeyw    'CP860',860        ; Portuguese CP
  380.     mkeyw    'CP863',863        ; French Canadian CP
  381.     mkeyw    'CP865',865        ; Norwegian CP
  382.     mkeyw    'CP866',866        ; Latin5/Cryillic CP
  383.  
  384. termtb    db    2        ; entries for Status, not Set
  385.     mkeyw    'Heath-19',ttheath
  386.     mkeyw    'none',ttgenrc
  387.  
  388. comptab db    12             ; Twelve entries.
  389.     mkeyw    '1',1    
  390.     mkeyw    '2',2        
  391.     mkeyw    '3',3        
  392.     mkeyw    '4',4        
  393.     mkeyw    'COM1',1
  394.     mkeyw    'COM2',2       
  395.     mkeyw    'COM3',3       
  396.     mkeyw    'COM4',4       
  397.     mkeyw    'A',2
  398.     mkeyw    'B',1        
  399.     mkeyw    'J1',2    
  400.     mkeyw    'J2',1         
  401.  
  402. cntltab db    2            ; 8-bit controls
  403.     mkeyw    '7-bit',0
  404.     mkeyw    '8-bit',1
  405.  
  406. scrtab    db    2            ; screen attributes
  407.     mkeyw    'normal',0
  408.     mkeyw    'reverse',1
  409.  
  410. ontab    db    2            ; two entries
  411.     mkeyw    'off',0
  412.     mkeyw    'on',1
  413.  
  414. chatab    db    14            ; National Replacement Character sets
  415.     mkeyw    'ASCII',0        ; ASCII is default (0, no NRC)
  416.     mkeyw    'British',1        ; start NRC set (1-12)
  417.     mkeyw    'Dutch',2
  418.     mkeyw    'Finnish',3
  419.     mkeyw    'French',4
  420.     mkeyw    'Fr-Canadian',5
  421.     mkeyw    'German',6
  422.     mkeyw    'Italian',7
  423.     mkeyw    'Norwegian/Danish',8
  424.     mkeyw    'Portuguese',9
  425.     mkeyw    'Spanish',10
  426.     mkeyw    'Swedish',11
  427.     mkeyw    'Swiss',12        ; end of NRC proper
  428.     mkeyw    'Transparent',14    ; use native display adapter hardware
  429.  
  430. curtab    db    3            ; cursor attributes
  431.     mkeyw    'block',0
  432.     mkeyw    'underline',1
  433.     mkeyw    'none',2
  434.      
  435. beltab    db    3            ; bell type
  436.     mkeyw    'audible',0
  437.     mkeyw    'visual',1
  438.     mkeyw    'none',2
  439.  
  440. dirtab    db    2            ; writing direction
  441.     mkeyw    'left-to-right',0
  442.     mkeyw    'right-to-left',1
  443.  
  444. kpamtab db    2            ; keypad, application
  445.     mkeyw    'Numeric',0
  446.     mkeyw    'Application',1
  447.  
  448. flags1    db    0            ; internal flags
  449. prtscr    equ    80h            ; print screen pressed flag
  450. escflg    db    0            ; esc character received flag
  451. padflg    db    0            ; keypad mode changed flag
  452. ansflgs dw    0            ; ANSI/VT100 mode flags
  453. ; (flags are defined in mssdefs.h)
  454.  
  455. vtemu    emulst    <>            ; emulator flags
  456.  
  457. eeolstr db    ESCAPE,'K$'       ; Erase to end of line
  458. enascan db    ESCAPE,'y?$'       ; Enable scan codes, disable key expansion
  459. disscan db    ESCAPE,'x?$'       ; Disable scan codes, enable key expansion
  460. enacurs db    ESCAPE,'y5$'       ; Enable cursor
  461. discurs db    ESCAPE,'x5$'       ; Disable cursor
  462. enablnk db    ESCAPE,'y;$'       ; Enable cursor blink
  463. disblnk db    ESCAPE,'x;$'       ; Disable cursor blink
  464. enabloc db    ESCAPE,'x4$'       ; Enable block cursor
  465. enaunde db    ESCAPE,'y4$'       ; Enable underscore cursor
  466. savcur    db    ESCAPE,'j$'       ; Save current cursor position
  467. begrev    db    ESCAPE,'p$'       ; Enter reverse video
  468. padpos    db    ESCAPE,'Y8k$'       ; Row 25 column 75
  469. endrev    db    ESCAPE,'q$'       ; Exit reverse video
  470. precur    db    ESCAPE,'k$'       ; Restore cursor to previous position
  471.  
  472. modbuf    modfrm    <>            ; mode line buffer
  473.  
  474. ; some static data for mode line
  475. unkbaud db    'Unk '            ; must be 4 chars...
  476. baudn    db    '45.5'
  477.     db    '  50'
  478.     db    '  75'
  479.     db    ' 110'
  480.     db    ' 135'
  481.     db    ' 150'
  482.     db    ' 300'
  483.     db    ' 600'
  484.     db    '1200'
  485.     db    '1800'
  486.     db    '2000'
  487.     db    '2400'
  488.     db    '4800'
  489.     db    '9600'
  490.     db    ' 19K'
  491.     db    ' 38K'
  492.  
  493. baudnsiz  equ    16            ; # of baud rates known (tbl size / 4)
  494.  
  495. parnams db    'Even'
  496.     db    'Mark'
  497.     db    'None'
  498.     db    'Odd '            ; must be 4 chars
  499.     db    'Spc '
  500. lclmsg    db    'Lcl'
  501. remmsg    db    'Rem'
  502. prmsg    db    'PRN'
  503.     db    '   '
  504.  
  505. noleds    db    '   None   '        ; For no emulation
  506. ansleds db    'VT102 ....'        ; "LEDs". Terminal ident (10 bytes)
  507. v52leds db    '   VT52   '        ; This is used in VT52 mode
  508. h19leds db    ' Heath-19 '        ; For Heath-19 mode
  509.  
  510. vtable    dw    ontab, ontab, chatab, dirtab ,ontab, ontab, curtab, scrtab
  511.     dw    cntltab, kpamtab, 0
  512. ; which are    newline     wrap    char   direct  key   margin  cursor  screen  
  513. ;        controls key-app
  514.  
  515. data    ends
  516.  
  517. code1    segment
  518. fcsrtype proc    far
  519.     ret
  520. fcsrtype endp
  521. code1    ends
  522.  
  523. code    segment
  524.     extrn    prtchr:near,outchr:near,putmod:near,clrmod:near,sendbr:near
  525.     extrn    sprtch:near, beep:near, pcwait:near, poscur:near, cmblnk:near
  526.     extrn    msuinit:near, keybd:near, keycom:near, isfile:near, outch2:near
  527.     extrn    atoi:near, strlen:near
  528.     extrn    comnd:near, statc:near, replay:near, pntchr:near, pntflsh:near
  529.  
  530.     assume    cs:code, ds:data, es:nothing
  531.  
  532. ; do initialization local to this module
  533. ; Dynamically allocates 4000 bytes for screen save/restore buffer plus
  534. ;  320 to 38400 bytes for screen scroll back buffers. Tries to leave space
  535. ;  for Command.com before enlarging buffers. [jrd]
  536. lclyini proc    near
  537.     mov    ax,ipage_seg        ; the interrupt page
  538.     mov    es,ax
  539.     mov    es,word ptr es:mtr_ds    ; find monitor data segment here
  540.     cmp    es:MTR_VER,25        ; Must be higher than Version 2.5
  541.     jnl    lclyini1
  542.     mov    ah,prstr        ; Tell user and abort
  543.     mov    dx,offset mtrmsg
  544.     int    dos
  545.     mov    ah,4ch 
  546.     int     dos
  547. lclyini1:mov    ax,word ptr es:FORE    ; get current colors
  548.     mov    word ptr doscol,ax    ; save it
  549.     in    al,VID_CMD        ; Get the current video status.
  550.     mov    dosattr,al        ; Save it.
  551.     mov    al,VID_NOR        ; Set up video to normal
  552.     out    VID_CMD,al        ;  suit us, normally all colors active
  553.     call    msuinit            ; initialize keyboard module msuxxx
  554.     mov    al,1            ; underscore
  555.     call    csrtype            ; turn on underline cursor
  556. ;    call    getpos            ; get cursor position
  557. ;    mov    ax,1            ; underline cursor
  558. ;    call    setpos            ; set cursor position and type
  559.                     ; screen roll back buffers
  560.     mov    al,crt_lins        ; physical length of user area
  561.     mul    crt_cols        ; physical width
  562.     add    ax,7            ; round up
  563.     mov    cl,3
  564.     shr    ax,cl            ; bytes/screen to paragraphs/screen
  565.     mov    si,ax            ; save a copy in si
  566.     mov    bx,npages        ; number of roll back screens wanted
  567.     inc    bx            ; include current screen in count
  568.     mul    bx            ; total number of screens wanted
  569.     mov    cx,ax            ; save total wanted paragraphs in cx
  570.     mov    bx,0ffffh        ; ask for all of memory, to get size
  571.     mov    ah,alloc        ; allocate all of memory (must fail)
  572.     int    dos            ; bx has # free paragraphs
  573.     mov    ax,bx            ; ax has copy of number free paragraphs
  574.     sub    bx,26000D/16        ; space for Command.com copy #2
  575.     jc    lclyin2            ; c = not enough for it
  576.     cmp    bx,si            ; minimum roll back space left over?
  577.     jle    lclyin2            ; le = not even that much
  578.     cmp    bx,cx            ; got vs wanted paras for roll back
  579.     jle    lclyin3            ; le = enough but not more than needed
  580.     mov    bx,cx            ; limit to our actual needs
  581.     jmp    short lclyin3        ; ask for all we really want
  582. lclyin2:xor    bx,bx            ; use no space at all
  583.     mov    cx,bx            ; remember this new request
  584. lclyin3:mov    ah,alloc
  585.     int    dos
  586.     mov    tv_segs,PAR_GRN        ; the green video plane holds it all
  587.     mov    tv_sego,0        ;  and it starts at PAR_GRN:00
  588.     mov    iniseg,ax        ; (BDT) memory segment, window area
  589.     mov    inipara,bx        ; save for later resizing of buffers
  590.     cmp    cx,bx            ; paragraphs wanted vs delivered
  591.     jae    lclyin4            ; ae = enough
  592.     mov    ah,prstr
  593.     mov    dx,offset memerr    ; say not enough memory to operate
  594.     int    dos
  595.     mov    flags.extflg,1        ; set Kermit exit flag
  596. lclyin4:call    bufadj            ; set roll back buffer parameters
  597. ;    call    vsinit            ; init terminal emulator module MSZ
  598. ;    mov    bx,vtemu.att_ptr    ; attributes pointer
  599. ;    mov    ah,dosattr        ; startup video attributes
  600. ;    and    ah,not att_intensity    ; emulation intensity to normal
  601. ;    or    ah,userbold
  602. ;    mov    [bx],ah            ; set initial emulation attributes
  603.     ret
  604. lclyini endp
  605.  
  606. ; This is the terminal emulator.
  607. term    proc    near            ; terminal mode entry point
  608.     mov    argadr,ax        ; save argument ptr
  609.     call    argini            ; init options from arg address
  610.     call    scrini            ; init screen stuff
  611.     or    kbcodes,80h        ; set need-to-init flg for kbd xtlator
  612.     mov    bx,portval        ; port data structure address
  613.     mov    bx,[bx].flowc        ; get flow control chars (bl=xoff)
  614.     mov    flowon,bh
  615.     mov    flowoff,bl        ; save for later
  616.     mov    oldsp,sp        ; remember stack for i/o failure,
  617.                     ;  used by procedure  endcon
  618.     mov    fairprn,0        ; set printer buffer flush counter
  619. lp:    call    prtchr            ; char at port?
  620.     jnc    short lpinp        ; nc = yes, go handle
  621.     cmp    flags.comflg,2        ; check if S-100 ports
  622.     ja    lpkbd            ; yes, go do it the simple way
  623.     push    bx
  624.     mov    bx,portval        ; port structure address
  625.     cmp    [bx].portrdy,0        ; is port ready for business?
  626.     pop    bx
  627.     jne    lpkbd            ; ne = ready
  628.     jmp    endcon            ; end the communications now
  629. lpkbd:    mov    fairness,0        ; say kbd was examined
  630.     inc    fairprn            ; inc printer dump counter
  631.     cmp    fairprn,1000        ; been here enough times now?
  632.     jb    lpkbd1            ; b = no
  633.     cmp    flags.comflg,2        ; check if S-100 ports
  634.     ja    lpkbd1            ; yes, this will delay us too much
  635.     call    pntflsh            ; flush printer buffer
  636.     mov    fairprn,0        ; reset for next time
  637. lpkbd1: call    keybd            ; call keyboard translator in msu
  638.     jnc    lp            ; nc = no char or have processed it
  639.     jmp    short quit        ; carry set = quit connect mode
  640. lpinp:    and    al,parmsk        ; apply 8/7 bit parity mask
  641.     call    outtty            ; print on terminal
  642.     inc    fairness        ; say read port but not kbd, again
  643.     cmp    fairness,100        ; this many port reads before kbd?
  644.     jb    lp            ; b = no, read port again
  645.     jmp    short lpkbd        ; yes, let user have a chance too
  646.  
  647. quit:    mov    ah,scbattr        ; current emulator attributes
  648.     mov    savattr,ah        ; save them here
  649.     call    pntflsh            ; flush printer buffer
  650.     call    getpos            ; get cursor position into dx
  651.     mov    cursor,dx        ; save position
  652.     mov    al,1            ; underscore
  653.     call    csrtype            ; turn on underline cursor
  654.     cmp    flags.vtflg,0        ; terminal type of none?
  655.     je    quit1            ; e = yes
  656.     cmp    flags.modflg,2        ; is modeline owned by remote host?
  657.     je    quit1            ; e = yes
  658.     call    clrmod            ; clear it before storing screen
  659. quit1:    
  660.     call    savescr            ; save screen
  661.           mov    dh,byte ptr low_rgt+1    ; bottom line
  662.     xor    dl,dl            ; left most column
  663.     call    setpos            ; set cursor position
  664.     mov    dx,word ptr doscol    ; set color back to dos values
  665.     xchg    dl,dh            ; get the sequence right
  666.     call    setcol
  667.     mov    al,VID_NOR        ; reset video port
  668.     out    VID_CMD,al
  669.     mov    al,yflags
  670.     and    al,not lclecho        ; don't copy host's echo flag
  671.     mov    bx,argadr
  672.     mov    ah,[bx].flgs        ; get user's flag settings
  673.     and    ah,lclecho        ; clear all but local echo bit
  674.     or    [bx].flgs,al        ; update flags in arg block
  675.     ret
  676. term    endp
  677.  
  678. argini    proc    near            ; read passed arguments
  679.     mov    bx,argadr        ; base of argument block
  680.     mov    al,[bx].flgs        ; get flags
  681.     and    al,capt+emheath+trnctl+lclecho+modoff
  682.     mov    yflags,al        ; mask for allowable and save
  683.     mov    al,[bx].prt
  684.     mov    portno,al        ; update port number
  685.     mov    crt_lins,ROWS        ; init # of rows
  686.     mov    ax,[bx].captr
  687.     mov    captrtn,ax        ; buffer capture routine
  688.     mov    parmsk,0ffh        ; parity mask, assume parity = None
  689.     cmp    [bx].parity,parnon    ; is parity None?
  690.     je    argini1            ; e = yes, keep all 8 bits
  691.     mov    parmsk,07fh        ; else keep lower 7 bits
  692. argini1:ret                ; that's it
  693. argini    endp
  694.  
  695. scrini    proc    near            ; init screen stuff
  696.     mov    dx,word ptr tercol    ; set terminal color
  697.     xchg    dl,dh            ; get the sequence right
  698.     call    setcol
  699.     call    clrmod            ; clear mode line
  700.     test    yflags,modoff        ; is mode line disabled?
  701.     jnz    scrin1            ; yes, skip it
  702.     call    modlin            ; turn on mode line
  703. scrin1: 
  704.     cmp    flags.vtflg,0        ; terminal type of None?
  705.     ja    scrin3            ; a = no, emulating
  706.  
  707. ;some code?
  708.  
  709. scrin3: 
  710.     in    al,VID_CMD        ; Get the current video status.
  711.     mov    savattr,al        ; Save it.
  712.     mov    scbattr,al        ; Here too
  713.     mov    dx,cursor        ; use old cursor, if any
  714.     call    restscr            ; restore screen, if any saved
  715.     call    setpos            ; set cursor position
  716.     or    flags1,inited        ; remember we've run already
  717.     cmp    flags.vtflg,0        ; current terminal type = None?
  718.     je    scrin13            ; e = yes, nothing to init
  719.     cmp    vtclear,2        ; screen need clearing?
  720.     jae    scrin10            ; ae = yes, do emulator reinit now
  721.     cmp    vtinited,inited        ; inited emulator yet?
  722.     je    scrin11            ; e = yes
  723. scrin10:call    vtinit            ; init it now
  724.     jmp    short scrin13
  725. scrin11:
  726. ;    call    ansrei            ; reinit the emulator
  727.  
  728. scrin13:mov    ax,flags.vtflg        ; current terminal type
  729.     mov    trmtyp,ax        ; place to remember it til next time
  730.     mov    vtclear,0        ; say screen is updated
  731.     ret
  732. scrini    endp
  733.  
  734. ; Routine to initialize VT102/52/Heath-19 terminal emulator.
  735. vtinit    proc    near
  736.     mov    holdscr,0        ; clear holdscreen
  737.     mov    ah,conout
  738.     mov    dl,ESCAPE        ; Take the
  739.     int    dos            ;  Z-100
  740.     mov    dl,'y'            ;  terminal
  741.     int    dos            ;  out of
  742.     mov    dl,'3'            ;  holdscreen
  743.     int    dos            ;  mode
  744.     or    vtinited,inited
  745.     cmp    flags.vtflg,0        ; doing emulation?
  746.     je    vtinix            ; e = no
  747.     mov    bx,argadr        ; address of argument block
  748.     mov    dl,[bx].flgs
  749.     and    dl,lclecho        ; local echo flag
  750.     and    yflags,not lclecho
  751.     or    yflags,dl
  752.     mov    dl,[bx].baudb        ; baud rate code in dl
  753.     mov    dh,[bx].parity        ; parity code in bits
  754.     mov    cl,4            ; 0-3 of dh
  755.     shl    dh,cl
  756.     or    dh,07H            ; just say 7 data bits
  757.     test    flags.remflg,d8bit    ; eight bit display?
  758.     jz    vtini1            ; z = no
  759.     inc    dh            ; set low four bits to value 8
  760. vtini1: 
  761. ;    call    ansini            ; call startup routine
  762. vtinix: clc
  763.     ret
  764. vtinit    endp
  765.  
  766.  
  767. trnprs: push    ax            ; toggle ^ PrtSc screen to printer
  768.     test    flags1,prtscr        ; are we currently printing?
  769.     jnz    trnpr2            ; nz = yes, its on and going off
  770.     mov    ah,ioctl
  771.     mov    al,7            ; get output status of printer
  772.     push    bx
  773.     mov    bx,prnhand        ; file handle for Connect printing
  774.     int    dos
  775.     pop    bx
  776.     jc    trnpr1            ; c = printer not ready
  777.     cmp    al,0ffh            ; Ready status?
  778.     je    trnpr2            ; e = Ready    
  779. trnpr1: call    vtbell            ; Not Ready, complain
  780.     jmp    trnpr3            ; and ignore request
  781. trnpr2: xor    flags1,prtscr        ; flip the flag
  782.     test    yflags,modoff        ; mode line off?
  783.     jnz    trnpr3            ; nz = yes
  784.     call    modlin            ; else rewrite mode line
  785.     call    pntflsh            ; print the last of printer buffer
  786. trnpr3: pop    ax
  787.     clc                ; return carry clear (don't quit)
  788.     ret
  789.  
  790. ; Put the character in al to the screen.
  791. ; Monitor rom calls used in emulator mode for speed reasons.
  792. ; The Z-100 screen is very slow in the handling of esc E and esc J;
  793. ;  if esc E or esc J and S-100 modem, trap these and do it our own way
  794. ;  while polling port in order to avoid loosing characters at port.
  795. ; The esc sequencies esc x ?, esc y ? and esc y @ are trapped and defused
  796. ;  as these would either lock up the keyboard or interfere with the function
  797. ;  of the keys.
  798. outtty    proc    near
  799.     cmp    escflg,true    ; Esc last time?
  800.     jl    outtt04        ; No, but maybe this time
  801.     jz    outtt01        ; Yes
  802.     jmp    outtt31        ; No, but earlier
  803. outtt01:cmp    al,'='        ; Is it =?
  804.     jnz    outtt02        ; No, go on
  805.     mov    ansflgs,deckpam ; Yes, it is application keypad mode
  806.     or    vtemu.vtflgop,deckpam    ; here too
  807.     mov    modbuf.m_pad,'A'; A for Application
  808.     mov    padflg,true    ; Keypad mode changed
  809.     jmp    outtt03
  810. outtt02:cmp    al,'>'        ; Is it >?
  811.     jnz    outtt1        ; No, go on
  812.     mov    ansflgs,false    ; Yes, it is numeric keypad mode
  813.     and    vtemu.vtflgop,not deckpam
  814.     mov    modbuf.m_pad,'N'; N for Numeric
  815.     mov    padflg,true    ; Keypad mode changed
  816. outtt03:mov    escflg,false    ; reset
  817.     jmp    outtt4        ; Go display it
  818. outtt04:cmp    al,ESCAPE    ; Esc now?
  819.     jnz    outtt05        ; No
  820.     mov    escflg,true
  821. outtt05:jmp    outtt4        ; Go display it
  822. outtt1: inc    escflg        ; Count
  823.     cmp    escflg,true
  824.     jnz    outtt11
  825.     mov    escflg,false    ; reset
  826. outtt11:cmp    al,ESCAPE    ; Esc now?
  827.     jnz    outtt2        ; No, just go on
  828.     mov    escflg,true    ; Yes, set escflg to 1
  829. outtt2: cmp    al,'x'        ; Yes, set modes?
  830.     jz    outtt05        ; Yes, just deliver
  831.     cmp    al,'y'        ; Reset modes?
  832.     jz    outtt05        ; Yes, just deliver
  833.     mov    escflg,false    ; reset
  834.     cmp    flags.comflg,2    ; check if S-100 ports
  835.     jle    outtt4        ; no, go do it the simple way
  836.     cmp    al,'E'        ; Is it E?
  837.     jz    outtt3        ; Yes, go handle
  838.     cmp    al,'J'        ; Is it J?
  839.     jnz    outtt4        ; No, go write the character
  840.     push    ax        ; Need this later
  841.     jmp    short outtt3a    ; Have ESC J
  842. outtt3: push    ax        ; Yes, we have ESC E
  843.     mov    ah,conout    ;  break it up into smaller parts,
  844.     mov    dl,'H'        ;  first, home cursor (ESC was sent before)
  845.     int    dos
  846.     mov    dl,ESCAPE    ; Send ESC again (first part of ESC j)
  847.     int    dos
  848. outtt3a:            ; This is where we handle ESC J
  849.     mov    cx,1        ; No delay for sprtch
  850.     call    sprtch        ; Go get possible char at port
  851.     mov    ah,conout
  852.     mov    dl,'j'        ; Save cursor position (ESC was sent before) 
  853.     int    dos
  854.     mov    ah,prstr
  855.     mov    dx,offset eeolstr ; Clear to the end of the current line
  856.     int    dos    
  857.     call    getpos        ; Get cursor position
  858.     xor    dl,dl        ; Column 0
  859.     cmp    dh,23        ; Line 23 = the 24th line?
  860.      jae    outtt3d        ; Yes, we are at 23 or 24 (24th or 25th), done
  861.     push    dx        ; Save cursor position
  862. outtt3b:pop    dx        ; Get cursor
  863.     inc    dh        ; Next line
  864.     cmp    dh,24        ; Will this one be line 24, the 25th line
  865.     jae    outtt3c        ; Yes, done
  866.     push    dx        ; Save it again
  867.     mov    cx,1        ; No delay
  868.     call    sprtch        ; Go get possible char at port
  869.     pop    dx        ; Get cursor back
  870.     push    dx        ; Save it again
  871.     call    poscur        ; Set cursor to beginning this new line     
  872.     mov    ah,prstr
  873.     mov    dx,offset eeolstr ; Clear to the end of the current line
  874.     int    dos
  875.     jmp    short outtt3b
  876. outtt3c:mov    dx,offset precur; Set cursor to 'original' position
  877.     int    dos
  878. outtt3d:mov    escflg,false    ; reset
  879.     jmp    outtt5
  880. outtt31:mov    escflg,false    ; reset
  881.     cmp    al,'?'        ; key expansion?
  882.     jz    outtt32        ; yes, inhibit it
  883.     cmp    al,'@'        ; event driven?
  884.     jnz    outtt4        ; no, just deliver
  885. outtt32:xor    al,al        ; put something harmless in
  886. outtt4: push    ax        ; Need it later
  887.     test    flags.remflg,d8bit ; keep 8 bits for displays?
  888.     jnz    outtt40        ; nz = yes, 8 bits if possible
  889.     and    al,7fh        ; Strip parity
  890. outtt40:test    yflags,emheath    ; Are we using emulation?
  891.     jnz    outtt41        ; Yes, go on, do it fast
  892.                 ; No, use dos to allow term. device driver
  893.     mov    dl,al        ; We need it here
  894.     mov    ah,conout    ; Write char in dl    ; This may loose
  895.     int    dos        ;  do it        ;  characters
  896.     jmp    outtt5
  897. outtt41:mov    ah,chr_write    ; Write char in al    ; This is faster
  898. ;     call     bios_confunc     ; Do it fast
  899.     call    MTR_SCRT    ; Do it very fast    
  900. outtt5: pop    ax        ; Restore char
  901.     test    yflags,capt    ; capturing output?
  902.     jz    outtt7        ; no, forget it
  903.     cmp    flowoff,0    ; Are we doing flow control
  904.     je    outtt6        ; No, just continue
  905.     cmp    caplft,1    ; yes, one more space left in capture buffer?
  906.     jnz    outtt6        ; no, give it the char
  907.     push    ax        ; yes, send xoff first
  908.     mov    bx,portval
  909.     mov    ax,[bx].flowc    ; ah gets xon al gets xoff
  910.     call    outpr1
  911.     cmp    flags.comflg,2    ; check if S-100 ports
  912.     jle    outtt51        ; no, go do it the simple way
  913.     mov    cx,delaycount    ; delay to ensure that, in spite of possible
  914.     call    sprtch        ;  slow link, xoff is in effect
  915. outtt51:pop    ax        ; get char back
  916.     push    ax        ; save it again
  917.     call    captrtn        ; give it the captured char
  918.     mov    bx,portval
  919.     mov    ax,[bx].flowc    ; ah gets xon al gets xoff
  920.     mov    al,ah
  921.     call    outpr1
  922.     pop    ax
  923.     jmp    outtt7        
  924. outtt6: call    captrtn
  925. outtt7: test    flags1,prtscr        ; print screen?
  926.     jz    outtt8            ; no, keep going
  927.     call    pntchr            ; queue char for printer
  928.     jnc    outtt8            ; nc = successful print
  929.     push    ax
  930.     call    beep            ; else make a noise and
  931.     call    trnprs            ;  turn off printing
  932.     pop    ax
  933. outtt8: test    padflg,true        ; no, has keypad mode been changed?
  934.     jz    outtt9            ; no, skip it
  935.     test    yflags,modoff        ; is mode line disabled?
  936.     jnz    outtt9            ; yes, skip it
  937.     call    dispad            ; yes, display keypad mode
  938.     mov    padflg,false        ; reset flag
  939. outtt9: ret
  940. outtty    endp
  941.  
  942. ; display the keypad mode information on the mode line
  943. dispad    proc    near
  944.     mov    ah,prstr        ; print string
  945.     mov    dx,offset savcur    ; save cursor position
  946.     int    dos
  947.     mov    dx,offset begrev    ; reverse video
  948.     int    dos
  949.     mov    dx,offset padpos    ; position cursor
  950.     int    dos
  951.     mov    dl,modbuf.m_pad        ; this is it
  952.     mov    ah,conout
  953.     int    dos
  954.     mov    ah,prstr
  955.     mov    dx,offset endrev    ; normal video
  956.     int    dos
  957.     mov    dx,offset precur    ; reposition cursor
  958.     int    dos
  959.     ret
  960. dispad    endp
  961.  
  962.                     ; general character out for emulator
  963. chrout: cmp    flags.vtflg,0        ; emulating?
  964.     je    chrou5            ; e = no
  965. ;    call    anskbi            ; say we had keyboard input
  966.     cmp    al,cr            ; CR?
  967.     jne    chrou5            ; ne = no, just output it and return
  968.     test    vtemu.vtflgop,anslnm    ; ANSI new-line mode set?
  969.     jz    chrou5            ; z = no, just send the cr
  970.     cmp    dupflg,0        ; full duplex?
  971.     je    chrou4            ; e = yes
  972.     cmp    al,trans.seol        ; End of Line char?
  973.     jne    chrou5            ; ne = no
  974. chrou4: mov    ah,trans.seol        ; save eol char
  975.     push    ax            ; save on stack
  976.     mov    trans.seol,lf        ; make LF the eol char
  977.     call    outprt            ; output a carriage-return
  978.     mov    al,lf            ; followed by a line feed
  979.     call    outprt            ; send the LF
  980.     pop    ax
  981.     mov    trans.seol,ah        ; restore eol char
  982.     ret
  983. chrou5: jmp    outprt
  984.  
  985. ; send the character in al out to the serial port; handle echoing.
  986. ; Can send an 8 bit char while displaying only 7 bits locally.
  987. outprt    proc    near
  988. prtbout    label    near            ; label used in msz
  989.     test    yflags,lclecho        ; echoing?
  990.     jz    outpr1            ; z = no, forget it
  991.     push    ax            ; save char
  992.     call    outtty            ; print it
  993.     pop    ax            ; restore
  994. OUTPR1:    mov    ah,al            ; outpr1 entry point used for no echo
  995.                      ;  sending of char in al
  996.     call    outchr            ; output to the port
  997.      jc    outpr3            ; c = failure
  998.     ret
  999. OUTPR2: mov    ah,al            ; outpr2 entry point used for no echo
  1000.                     ;  no flow control sending of char
  1001.     call    outch2            ; output to the port, no flow control
  1002.      jc    outpr3            ; c = failure
  1003.     ret
  1004. outpr3:    jmp    endcon            ; failure, end connection
  1005. outprt    endp
  1006.                     ; Toggle Mode Line
  1007. trnmod    proc    near
  1008.     cmp    flags.modflg,1        ; mode line enabled and owned by us?
  1009.     jne    trnm1            ; ne = no, don't touch it
  1010.     test    yflags,modoff        ; mode line already off?
  1011.     jnz    trnm2            ; nz = yes, go turn on
  1012.     or    yflags,modoff        ; say modeline is toggled off
  1013.     call    clrmod            ; clear mode line
  1014. trnm1:    clc                ; clear c bit so don't exit Connect
  1015.     ret
  1016. trnm2:    cmp    flags.vtflg,0        ; emulating a terminal?
  1017.     jne    trnm3            ; ne = yes
  1018.     push    dx            ; scroll screen to save bottom line
  1019.     mov    ah,prstr        ; for terminal type none
  1020.     mov    dx,offset crlf
  1021.     int    dos
  1022.     pop    dx
  1023. trnm3:    call    modlin            ; turn on modeline
  1024.     and    yflags,not modoff    ; say modeline is not toggled off
  1025.     clc
  1026.     ret
  1027. trnmod    endp
  1028.  
  1029. modlin    proc    near            ; turn on mode line
  1030.     push    es
  1031.     mov    al,trans.escchr
  1032.     mov    modbuf.m_echr,' '    ; first char is initial space
  1033.     mov    modbuf.m_hlp,' '    ; goes here too.
  1034.     cmp    al,32            ; printable?
  1035.     jnb    modl0            ; yes, keep going
  1036.     add    al,40h            ; made printable
  1037.     mov    modbuf.m_echr,'^'    ; note control char
  1038.     mov    modbuf.m_hlp,'^'
  1039. modl0:    mov    modbuf.m_echr+1,al    ; fill in character
  1040.     mov    modbuf.m_hlp+1,al
  1041.     mov    bx,argadr        ; get argument block
  1042.     mov    al,[bx].baudb        ; get baud bits
  1043.     mov    si,offset unkbaud    ; assume unknown baud
  1044.     cmp    al,baudnsiz        ; too big?
  1045.     jnb    modl3            ; yes, use default
  1046.     shl    al,1            ; each is 4 bytes long...
  1047.     shl    al,1
  1048.     mov    ah,0
  1049.     add    ax,offset baudn
  1050.     cmp    flags.comflg,2        ; com1/com2?
  1051.     jna    modl2            ; yes, jump
  1052.     add    ax,5*4            ; no, starts 5 rates higher
  1053. modl2:    mov    si,ax
  1054. modl3:    mov    cx,size m_baud        ; length of baud space
  1055.     mov    di,offset modbuf.m_baud
  1056.     push    ds
  1057.     pop    es
  1058.     cld
  1059.     rep    movsb            ; copy in baud rate
  1060.     mov    al,[bx].parity        ; get parity code
  1061.     shl    al,1            ; each is 4 bytes long...
  1062.     shl    al,1
  1063.     mov    ah,0
  1064.     add    ax,offset parnams    ; names of parity settings
  1065.     mov    si,ax
  1066.     mov    cx,4            ; each is 4 long
  1067.     mov    di,offset modbuf.m_par
  1068.     rep    movsb
  1069.     mov    si,offset remmsg    ; assume remote echoing
  1070.     test    yflags,lclecho        ; echoing?
  1071.     jz    modl4            ; no, keep going
  1072.     mov    si,offset lclmsg
  1073. modl4:    mov    cx,3            ; size of Rem & Lcl
  1074.     mov    di,offset modbuf.m_echo
  1075.     rep    movsb
  1076.     cmp    flags.comflg,1        ; port 1 (port B)?
  1077.     mov    al,'B'            ; enter 'B'
  1078.     je    modl5            ; yes, keep going
  1079.     cmp    flags.comflg,3        ; port 3 (S-100 port 1)
  1080.     mov    al,'3'            ; enter '3'
  1081.     je    modl5            ; yes, keep going
  1082.     cmp    flags.comflg,4        ; port 4 (S-100 port 2)
  1083.     mov    al,'4'            ; enter '4'
  1084.     je    modl5            ; yes, keep going
  1085.     mov    al,'A'            ; then must be port 2 (port A)!
  1086. modl5:    mov    modbuf.m_prt,al        ; fill in port number
  1087.     mov    cx,3            ; size of PRN
  1088.     mov    di,offset modbuf.m_prn
  1089.     test    flags1,prtscr        ; print screen?
  1090.     mov    si,offset prmsg        ; printer on msg
  1091.     jnz    modl6            ; yes, prepare to display it
  1092.     add    si,3            ; no, print blank
  1093. modl6:    rep    movsb
  1094.     mov    cx,10            ; size of leds
  1095.     mov    di,offset modbuf.m_emul
  1096.     test    yflags,emheath        ; are we using Heath-19 emulation?
  1097.     mov    si,offset noleds    ; "None" message
  1098.     jz    modl7            ; no, prepare to display it
  1099.     mov    si,offset h19leds    ; Heath-19 emulation
  1100. modl7:    rep    movsb
  1101.     mov    modbuf.m_pad,'N'    ; N for Numeric
  1102.     test    ansflgs,deckpam        ; are we in keypad application mode?
  1103.     jz    modl8            ; no, leave the blank in
  1104.     mov    modbuf.m_pad,'A'    ; A for Application
  1105. modl8:    mov    cx,size modfrm        ; this is size of mode line
  1106.     mov    si,offset modbuf    ; mode line image
  1107.     mov    dx,offset modbuf
  1108.     call    putmod
  1109.     pop    es
  1110.     ret                ; and return
  1111. modlin    endp
  1112.  
  1113. ; Invoked by keyboard translator when an unknown keyboard verb is used as
  1114. ; a string definition, such as {\ktest}. Enter with vtmacname pointing to
  1115. ; uppercased verb name, asciiz, and vtmaclen set to its length.
  1116. extmacro proc    near
  1117.     jmp    short vtmacro
  1118. extmacro endp
  1119. ;
  1120. ; Reference    Macro structure for    db    number of entries (mac names)
  1121. ;  is file     table mcctab       |->    db    length of macroname, excl '$'
  1122. ;  mssset.asm        each entry |->    db    'macroname','$'
  1123. ;  where these               |->    dw    segment:0 of definition string
  1124. ;  are stored.                      (offset part is always 0)    
  1125. ;        Definition string in    db    length of <string with null>
  1126. ;         buffer macbuf        db    'string with trailing null'
  1127. ;
  1128.  
  1129. vtmacro    proc    far            ; common code for macros vtsmac,vtrmac
  1130.     push    bx            ; and Product
  1131.     push    cx
  1132.     push    si
  1133.     push    di
  1134.     push    es
  1135.     mov    ax,ds
  1136.     mov    es,ax
  1137.     mov    di,offset rdbuf+1    ; macro def buffer starts here
  1138.     mov    si,vtmacname        ; pointer to macro name
  1139.     mov    cl,vtmaclen        ; length of macro name<sp/null>text
  1140.     xor    ch,ch
  1141.     mov    [di-1],cl        ; counted string field
  1142.     cld
  1143.     rep    movsb            ; copy to rdbuf
  1144.     mov    byte ptr [di],0        ; null terminator
  1145.     mov    si,offset rdbuf+1    ; look for name-text separator
  1146.     mov    cl,vtmaclen
  1147.     xor    ch,ch
  1148. vtmac1:    lodsb
  1149.     cmp    al,' '            ; space separator?
  1150.     je    vtmac1a            ; e = yes, stop here
  1151.     or    al,al            ; null terminator?
  1152.     jz    vtmac1a            ; e = yes, stop here
  1153.     loop    vtmac1
  1154.     inc    si            ; to do null lenght correctly
  1155. vtmac1a:sub    si,offset rdbuf+1+1    ; compute length of macro name
  1156.     mov    cx,si
  1157.     mov    vtmaclen,cl        ; save a macro name length
  1158.                     ; check for existence of macro
  1159.     mov    bx,offset mcctab    ; table of macro names
  1160.     mov    cl,[bx]            ; number of names in table
  1161.     xor    ch,ch
  1162.     jcxz    vtmacx            ; z = empty table, do nothing
  1163.     inc    bx            ; point to length of first name
  1164. vtmac2:    mov    al,[bx]            ; length of this name
  1165.     xor    ah,ah
  1166.     cmp    al,vtmaclen        ; length same as desired keyword?
  1167.     jne    vtmac3            ; ne = no, search again
  1168.     mov    si,bx
  1169.     inc    si            ; point at first char of name
  1170.     push    cx            ; save name counter
  1171.     push    di            ; save reg
  1172.     mov    cl,vtmaclen        ; length of name, excluding '$'
  1173.     xor    ch,ch
  1174.     mov    di,vtmacname        ; point at desired macro name
  1175.     push    es            ; save reg
  1176.     push    ds
  1177.     pop    es            ; make es use data segment
  1178.     cld
  1179.     repe    cmpsb            ; match strings
  1180.     pop    es            ; need current si below
  1181.     pop    cx
  1182.     pop    di            ; recover saved regs
  1183.     je    vtmac4            ; e = matched
  1184. vtmac3:    add    bx,ax            ; step to next name, add name length
  1185.     add    bx,4            ; + count, dollar sign, def word ptr
  1186.     loop    vtmac2            ; try next name
  1187. vtmacx:    pop    es
  1188.     pop    di
  1189.     pop    si            ; no macro, return to Connect mode
  1190.     pop    cx
  1191.     pop    bx
  1192.     ret
  1193.  
  1194. vtmac4:    cmp    taklev,maxtak        ; room in Take level?
  1195.     jge    vtmacx            ; ge = no, exit with no action
  1196.     inc    taklev            ; increment take level
  1197.     add    takadr,size takinfo    ; make a new Take entry/macro
  1198.     mov    bx,takadr        ; point to current macro structure
  1199.     mov    ax,ds            ; segment of rdbuf
  1200.     mov    [bx].takbuf,ax        ; segment of definition string struc
  1201.     mov    cl,rdbuf        ; length of whole string
  1202.     xor    ch,ch
  1203.     mov    [bx].takcnt,cx        ; number of chars in definition
  1204.     mov    [bx].takargc,0        ; our argument count
  1205.     mov    [bx].takptr,offset rdbuf+1 ; where to read next command char
  1206.     mov    [bx].taktyp,0ffh    ; flag as a macro
  1207.     pop    es
  1208.     pop    di
  1209.     pop    si
  1210.     pop    cx
  1211.     pop    bx
  1212.     jmp    endcon            ; exit Connect mode
  1213. vtmacro    endp
  1214.  
  1215. ; Error recovery routine used when outchr reports unable to send character
  1216. ;  or when vtmacro requests exiting Connect mode.
  1217. ; Exit Connect mode cleanly, despite layers of intermediate calls.
  1218. endcon    proc    near
  1219.     mov    kbdflg,'C'        ; report 'C' to TERM's caller
  1220.     mov    sp,oldsp        ; recover startup stack pointer
  1221.                     ; TERM caller's return address is now
  1222.                     ; on the top of stack. A longjmp.
  1223.     jmp    quit            ; exit Connect mode cleanly
  1224. endcon    endp
  1225.  
  1226.  
  1227. ; Clear all User Definable Keys, deallocate memory for their definitions
  1228. udkclear proc    near
  1229.     push    ax
  1230.     push    bx
  1231.     push    cx
  1232.     push    es
  1233.     mov    cx,17            ; 17 entries
  1234.     xor    bx,bx
  1235. udkcle1:mov    ax,udkseg[bx]        ; segment of definition
  1236.     or    ax,ax            ; segment defined?
  1237.     jz    udkcle2            ; z = no, try next key
  1238.     mov    es,ax
  1239.     mov    udkseg[bx],0        ; clear the entry
  1240.     mov    ah,freemem        ; release the memory
  1241.     int    dos
  1242. udkcle2:add    bx,2            ; word index
  1243.     loop    udkcle1            ; do all
  1244.     pop    es
  1245.     pop    cx
  1246.     pop    bx
  1247.     pop    ax
  1248.     clc
  1249.     ret
  1250. udkclear endp
  1251.  
  1252. ; Determine screen roll back buffer parameters depending on current screen
  1253. ; dimensions and available memory. Each rollback screen line has its own
  1254. ; segment (lines start on segment boundaries for rollback).
  1255.  
  1256. bufadj    proc    near
  1257.     push    bx
  1258.     push    cx
  1259.     push    dx
  1260.     mov    lxtra,0            ; assume no storage for "extra" lines
  1261.     xor    bh,bh            ; (BDT) get bytes / line
  1262.     mov    bl,crt_cols        ; (BDT) physical line width
  1263.     add    bx,7            ; (BDT) round up to paragraph boundary
  1264.     mov    cl,3            ; (BDT) now convert to
  1265.     shr    bx,cl            ; (BDT) paragraphs / line
  1266.     mov    ppl,bx            ; (BDT) save this in buffer area
  1267.     mov    ax,inipara        ; (BDT) compute the number of lines
  1268.     xor    dx,dx
  1269.     div    bx            ; (BDT)     in the buffer
  1270.     mov    lmax,ax            ; max line capacity of the buffer
  1271.     mov    linee,ax        ; (BDT) save as number of total lines
  1272.     or    ax,ax            ; is this zero?
  1273.     je    bufadj1            ; e = yes, no space at all
  1274.     xor    bh,bh            ; (BDT) get lines / screen
  1275.     mov    bl,byte ptr low_rgt+1    ; (BDT) rows on user/host screen
  1276.     inc    bx            ; (BDT) adjust for counting from 0
  1277.     mov    lxtra,bx        ; (BDT) save as "extra" lines
  1278.     sub    lmax,bx            ; (BDT) deduct "extra" lines req'd
  1279.     jg    bufadj1            ; g = have some rollback space
  1280.     mov    lmax,0            ; say none
  1281.     mov    lxtra,0            ; say none of these too
  1282. bufadj1:mov    lcnt,0            ; (BDT) # of lines filled in buffer
  1283.     mov    linef,0            ; (BDT) first filled in line
  1284.     mov    linec,0            ; (BDT) last  filled in line
  1285.     pop    dx
  1286.     pop    cx
  1287.     pop    bx
  1288.     ret
  1289. bufadj    endp
  1290.  
  1291. ; Routine to set cursor type.  Pass bits for cursor type in al:
  1292. ; bit 0 set = 1 => Cursor on        cleared = 0 => Cursor off
  1293. ; bit 1 set = 2 => Block cursor        cleared = 0 => Underline cursor 
  1294. ; bit 2 set = 4 => Non blinking cursor    cleared = 0 => Blinking cursor
  1295. ; Thus, in decimal form
  1296. ; 0 = No cursor, 1 = Blinking underline cursor , 3 = Blinking block cursor
  1297. ; 4 = No cursor, 5 = No blink underline cursor , 6 = No blink block cursor
  1298. csrtype proc    near
  1299.     mov    byte ptr lincur,al    ; remember type set
  1300.     push    ax
  1301.     push    dx            ; save the reg
  1302.     mov    ah,prstr
  1303.     test    al,cur_on        ; any cursor at all?
  1304.     jz    csrty3            ; z=no, go put it out
  1305.     mov    dx,offset enacurs    ; enable cursor
  1306.     int    dos
  1307.     mov    dx,offset enablnk    ; assume blink
  1308.     int    dos
  1309.     test    al,cur_nob        ; non blinking?
  1310.     jnz    csrty1            ; nz=no to no blink, leave as is
  1311.     mov    dx,offset disblnk    ; set blink off
  1312.     int    dos
  1313. csrty1: mov    dx,offset enaunde    ; assume underline
  1314.     int    dos
  1315.     test    al,cur_blo        ; block?
  1316.     jz    csrty2            ; z=no, leave as is 
  1317.     mov    dx,offset enabloc    ; set block
  1318.     int    dos
  1319. csrty2: jmp short csrty4
  1320. csrty3: mov    dx,offset discurs    ; disable cursor
  1321.     int    dos
  1322. csrty4: pop    dx
  1323.     pop    ax
  1324.     ret    
  1325. csrtype endp
  1326.  
  1327. ; Save the screen to a buffer and then append buffer to a disk file. [jrd]
  1328. ; Default filename is Kermit.scn; actual file can be a device too. Filename
  1329. ; is determined by mssset and is passed as pointer dmpname.
  1330. DUMPSCR PROC    NEAR            ; dumpscr dumps sreen to file
  1331.     push    ax
  1332.     push    bx
  1333.     push    cx
  1334.     push    dx
  1335.     push    di
  1336.     push    si
  1337.     push    es
  1338.                     ; Open and prepare screen dump file
  1339.     mov    dmphand,-1        ; preset illegal handle
  1340.     mov    dx,offset dmpname    ; name of disk file, from mssset
  1341.     mov    ax,dx            ; where isfile wants name ptr
  1342.     call    isfile            ; what kind of file is this?
  1343.     jc    dmp1            ; c = no such file, create it
  1344.     test    byte ptr filtst.dta+21,1fh ; file attributes, ok to write?
  1345.     jnz    dmp2            ; nz = no, indicate open failure
  1346.     mov    al,1            ; writing
  1347.     mov    ah,open2        ; open existing file
  1348.     int    dos
  1349.     jc    dmp2            ; c = failure, indicate open failure
  1350.     mov    dmphand,ax        ; save file handle
  1351.     mov    bx,ax            ; need handle here
  1352.     mov    cx,0            ; setup file pointer
  1353.     mov    dx,0            ; to end of file
  1354.     mov    al,2            ; seek the end
  1355.     mov    ah,lseek
  1356.     int    dos
  1357.     jc    dmp2            ; failure, indicate open failure
  1358.     jmp    short dmp3        ; success
  1359. dmp1:    mov    ah,creat2        ; file did not exist
  1360.     mov    cx,20h            ; attributes, archive bit
  1361.     int    dos
  1362.     mov    dmphand,ax        ; save file handle
  1363.     jnc    dmp3            ; nc = ok
  1364. dmp2:    call    beep
  1365.     mov    ah,prstr        ; print string
  1366.     mov    dx,offset dmperr    ; cannot open file
  1367.     int    dos
  1368.     jmp    short dmp8        ; Failure, exit
  1369. dmp3:    call    rdset            ; Set up for screen reading
  1370. dmp4:    call    rdlne            ; Read a screen line
  1371.     call    endfix            ; Fix end of line and srceen
  1372.                     ; Write out the line
  1373. dmp5:    mov    dx,offset line        ; array to be written
  1374.     mov    bx,dmphand        ; need file handle
  1375.     mov    ah,write2        ; write the line
  1376.     int    dos
  1377.     jc    dmp6            ; Go if trouble.
  1378.     cmp    cx,ax            ; Write as many bytes as requested?
  1379.     jnz    dmp6            ; Go if trouble.
  1380.     cmp    eos,1            ; End of screen?
  1381.     je    dmp7            ; If yes, go.
  1382.     mov    ax,int_cy        ; Else get the line index and set the
  1383.     shl    al,1            ; pointer to the next line of screen
  1384.     shl    al,1            ; data.
  1385.     shl    al,1
  1386.     mov    bh,al
  1387.     jmp    short dmp4        ; Now loop back, do another line
  1388. dmp6:    call    beep            ; Error writing file
  1389.     mov    ah,prstr        ; print string
  1390.     mov    dx,offset dmperr1    ; The message
  1391.     int    dos
  1392. dmp7:    mov    ah,close2        ; close the file now
  1393.     mov    bx,dmphand        ; file handle
  1394.     int    dos
  1395.     mov    al,vstate        ; Restore the original video port
  1396.     out    VID_CMD,al        ; state.
  1397. dmp8:    pop    es
  1398.     pop    si
  1399.     pop    di
  1400.     pop    dx
  1401.     pop    cx
  1402.     pop    bx
  1403.     pop    ax
  1404.     ret                ; Done with screen: return.
  1405. DUMPSCR ENDP
  1406.  
  1407. ; Local routine rdset to set up for screen buffer reading.  Modifies ax, bx
  1408. ; and es and enables acces to video memory.
  1409. RDSET:    cld                ; Clear direction indicator.
  1410.     mov    eos,0            ; Initialize end of screen flag to NO
  1411.     mov    lines,ROWS        ; Assume 24 lines on the screen.
  1412.     mov    ax,IPAGE_SEG        ; The interrupt page
  1413.     mov    es,ax            ; Fetch the variable containing the
  1414.     mov    es,es:[MTR_DS]        ; status of the 25th line:
  1415.     cmp    byte ptr es:[STATUS],0    ; 00= disabled, FF= enabled.
  1416.     je    rdset1 
  1417.     inc    lines            ; Set number of lines on screen to 25.
  1418. rdset1: in    al,VID_CMD        ; Get the current video status.
  1419.     mov    vstate,al        ; Save it.
  1420.     mov    al,78h            ; Enable access to the memory.
  1421.     out    VID_CMD,al
  1422.     mov    ax,PAR_GRN        ; Address the green plane, which is
  1423.     mov    es,ax            ; where the characters are stored.
  1424.     mov    int_cy,0        ; Start at line 0 on the screen.
  1425.     xor    bh,bh
  1426.     ret
  1427.  
  1428. ; Local routine rdlne to read a screen line.  Enter with es pionting to
  1429. ; the monitor interrup page.  Modifies ax, bx, si and di. 
  1430. RDLNE:    mov    bl,COLUMNS-1        ; Offset of the last character.
  1431.     mov    di,COLUMNS-1        ; Offset to the end of the line.
  1432.     xor    si,si            ; Show no non-spaces found yet.
  1433. rdlne1: mov    al,es:[bx+9*128]    ; Get the character's font index.
  1434.     add    al,' '            ; Then make it into the character.
  1435.     cmp    al,' '            ; Is the character a space?
  1436.     jne    rdlne2            ; If not, go.
  1437.     and    si,si            ; Any non-space found yet?
  1438.     jz    rdlne3            ; If no, go.
  1439. rdlne2: mov    line[di],al        ; Save the character.
  1440.     and    si,si            ; Non-space found yet?
  1441.     jnz    rdlne3            ; If yes, just go.
  1442.     lea    si,[di+1]        ; Else keep the offset to the non-space.
  1443. rdlne3: dec    bl            ; Go to next character.
  1444.     dec    di            ; Decrement the offset to the line.
  1445.     jge    rdlne1            ; Repeat this sequence for all chars.
  1446.     ret                ; Reached the end of line:
  1447.  
  1448. ; Local routine to add cr and lf at the end of each line and ff at the
  1449. ; end of each page.  Modifies ax and cx.  Returns with number of chars
  1450. ; in line buffer in cx.
  1451. endfix: mov    byte ptr line[si],CR    ; Put in a CR
  1452.     mov    byte ptr line[si+1],LF    ; Put in a LF
  1453.     lea    cx,[si+2]        ; Set up the counter.
  1454.     inc    int_cy            ; Up index to the next line and then
  1455.     mov    ax,int_cy        ; get it.
  1456.     cmp    ax,lines        ; Are we at the end of screen?
  1457.     jne    endfix1            ; If not, go.
  1458.     mov    byte ptr line[si+2],FF    ; Else store form feed for end of page.
  1459.     inc    cx            ; Up length to print.
  1460.     mov    eos,1            ; Turn on the end-of-screen flag.
  1461. endfix1:ret
  1462.  
  1463. ; Save the entire screen in a buffer so we can restore it.
  1464. ; Saves regular (80x25) screens to memory buffer allocated dynamically from
  1465. ; DOS. Save address is savadr+2:savadr (seg:offset). A memory buffer is
  1466. ; allocated as required.
  1467. savescr    proc    near
  1468.     push    ax
  1469.     push    bx
  1470.     push    cx
  1471.     push    dx
  1472.     push    si
  1473.     push    di
  1474.     push    es
  1475.     mov    ax,low_rgt        ; text screen lower right (typ 23,79)
  1476.     add    al,3            ; plus 1 col, cr, lf
  1477.     add    ah,2            ; plus 1 row plus status line
  1478.     mul    ah            ; times rows = characters on screen
  1479.     inc    ax            ;  plus the last one, ff
  1480.     mov    dx,ax            ; save number of screen bytes in dx
  1481.     mov    ax,savadr+2        ; seg of saved memory, if any
  1482.     or    ax,ax            ; none?
  1483.     jnz    savsc4            ; no, there is some
  1484.                     ; allocate and use DOS memory for save
  1485. savsc1:    mov    bx,dx            ; bytes to do
  1486.     add    bx,16            ; round up
  1487.     mov    cl,4
  1488.     shr    bx,cl            ; bytes/screen to paragraphs/screen
  1489.     mov    ah,alloc        ; allocate memory
  1490.     int    dos            ; bx has # free paragraphs
  1491.     jc    savsc2            ; c = not enough for it, skip
  1492.     mov    savadr+2,ax        ; working seg address for restore
  1493.     jmp    short savsc4
  1494. savsc2:    mov    savadr+2,0        ; then say no seg because no save
  1495.     jmp    short savsc7        ; exit without saving screen
  1496.                     ; save the screen
  1497. savsc4:    mov    savadr,0        ; no offset for memory buffer
  1498.     mov    cx,dx            ; number of screen bytes
  1499.          call    rdset            ; Set up for screen reading
  1500. savsc5:    call    rdlne            ; Read screen line
  1501.     call    endfix            ; Add cr, lf and possibly ff
  1502.            mov    ax,savadr+2        ; Reached the end of line:
  1503.     push    es
  1504.     mov    es,ax            ; Segment for buffer
  1505.     mov    si,offset line        ; Array to be written
  1506.     mov    di,savadr        ; We are here in buffer
  1507.     cld
  1508.     rep    movsb
  1509.     pop    es
  1510.     mov    savadr,di        ; Save it for next line
  1511.     cmp    eos,1            ; End of screen?
  1512.     je    savsc6            ; If yes, go.
  1513.     mov    ax,int_cy        ; Else get the line index and set the
  1514.     shl    al,1            ; pointer to the next line of screen
  1515.     shl    al,1            ; data.
  1516.     shl    al,1
  1517.     mov    bh,al
  1518.     jmp    short savsc5        ; Now loop back, do another line
  1519. savsc6: mov    al,vstate        ; Restore the original video port
  1520.     out    VID_CMD,al        ; state.
  1521. savsc7:    pop    es
  1522.     pop    di
  1523.     pop    si
  1524.     pop    dx
  1525.     pop    cx
  1526.     pop    bx
  1527.     pop    ax
  1528.     ret
  1529. savescr    endp
  1530.  
  1531. ; Restore screen from buffer (savadr+2:savadr, with number to write in savadr).
  1532. ; Restores all screen lines.
  1533. restscr    proc    near
  1534.     push    ax
  1535.     push    bx
  1536.     xor    ax,ax            ; upper left corner
  1537.     mov    bx,low_rgt
  1538.     call    atsclr            ; blank screen
  1539.     mov    bx,dx            ; holds cursor position
  1540.     mov    dx,ax            ; upper left corner
  1541.     call    poscur            ; set it
  1542.     cmp    savadr+2,0        ; saved anything yet?
  1543.     mov    dx,ax            ; restore it
  1544.     je    restsc2            ; e = no
  1545.     push    cx
  1546.     push    bx            ; this is in reality dx, cursor
  1547.     push    si
  1548.     push    di
  1549.     push    es
  1550.     mov    cx,savadr        ; this many bytes to write
  1551.     sub    cx,3            ;  but skip last cr,lf and ff
  1552.     mov    ax,savadr+2        ; get segment for buffer
  1553.     mov    es,ax            ;  into es
  1554.     xor    si,si            ; offset zero for first char
  1555. restsc1:mov    al,byte ptr es:[si]    ; get char
  1556.     push    cx            ; MTR_SCRT messes up ax, bx, cx, dx,
  1557.     push    si            ;  si, di and es, so we assume this
  1558.     call    MTR_DCRT        ;  one is as bad.
  1559.     pop    si
  1560.     pop    cx
  1561.     mov    ax,savadr+2        ; get segment for buffer
  1562.     mov    es,ax            ;  into es
  1563.     inc    si            ; next char
  1564.      loop    restsc1    
  1565.     pop    es
  1566.     pop    di
  1567.     pop    si
  1568.     pop    dx
  1569.     pop    cx
  1570. restsc2:pop    bx
  1571.     pop    ax
  1572.     ret
  1573. restscr    endp
  1574.  
  1575. ; Read cursor position
  1576. ; DL = column, DH = row, both counted from 0,0 at upper left corner
  1577. getpos    proc    near
  1578.     push    bx
  1579.     push    es
  1580.     mov    bx,IPAGE_SEG        ; the interrupt page
  1581.     mov    es,bx
  1582.     mov    es,word ptr es:MTR_DS    ; find monitor data segment here
  1583.     mov    dl,byte ptr es:MTR_HORP ; column 0 to 79
  1584.     mov    dh,byte ptr es:MTR_VERP ; row     0 to 24
  1585.     pop    es
  1586.     pop    bx
  1587.     ret
  1588. getpos    endp
  1589.  
  1590. ; Screen clearing routine atsclr.
  1591. ;
  1592. ; Call:        ax/    coordinates of first screen location to be cleared.
  1593. ;        bx/    coordinates of last location to be cleared.
  1594. ; Coord: ah = row [0-24], al = column [0-79]. Preserves all registers.
  1595. ATSCLR    PROC    NEAR
  1596.            push    ax
  1597.     push    bx
  1598.     push    cx
  1599.     push    dx
  1600.     push    si
  1601.     push    di
  1602.     push    bp
  1603.     push    es
  1604.           push    ds
  1605.     mov    cx,IPAGE_SEG        ; Get into es
  1606.     mov    es,cx
  1607.     mov    ds,es:[MTR_DS]        ; Now get MTR_DS into ds and the
  1608.      mov    bp,offset es:MTR_EDC    ;  offset to the dword into bp
  1609.     mov    cx,ax            ; Top left corner
  1610.     mov     cl,ch            ; Top line to cl
  1611.     xor    ch,ch            ; Top line now in cx
  1612.     push    cx            ; *   First parameter
  1613.     mov    cl,al            ; Left column now in cx
  1614.     push    cx            ; **  Second parameter
  1615.     sub    bh,ah            ; Line count
  1616.     inc    bh            ;  adjust
  1617.     sub    bl,al            ; Char count
  1618.       inc    bl            ;  adjust
  1619. atsclr1:push    bx            ; *** Third parameter in bl (and bh)
  1620.     call    dword ptr ds:[bp]    ; Do a line
  1621.     sub    sp,2        ; -2    ; Point to first parameter, line
  1622.     pop    cx        ; 0     ; Get it
  1623.     inc    cx            ; Go to the next line
  1624.     push    cx        ; -2    ; Put it back into stack
  1625.     sub    sp,4        ; -6    ; The next param, left column, is ok
  1626.     pop    bx        ; -4    ; But we will check on the line count
  1627.     dec    bh            ;  which we sneaked into here
  1628.     jnz    atsclr1            ; If more lines left, do it again
  1629.     add    sp,4        ; 0    ; Don't waste time popping this junk
  1630.     pop    ds
  1631.     pop    es
  1632.     pop    bp
  1633.     pop    di
  1634.     pop    si
  1635.     pop    dx
  1636.     pop    cx
  1637.     pop    bx
  1638.     pop    ax
  1639.     ret
  1640. ATSCLR    ENDP
  1641.  
  1642. ; Routine to do close to VT100-style bell, no arguments
  1643. vtbell    proc    near
  1644.     cmp    belltype,1        ; visual bell?
  1645.     je    vtbell1            ; e = yes
  1646.     call    beep
  1647.     ret
  1648. vtbell1:
  1649.     in    al,VID_CMD        ; Get the current video status.
  1650.     mov    ah,al            ; Save it.
  1651.     mov    al,0f0h            ; Make screen all white
  1652.     out    VID_CMD,al        ; Do it
  1653.     push    ax
  1654.     mov    ax,40            ; for 40 milliseconds
  1655.     call    pcwait
  1656.     pop    ax
  1657.     mov    al,ah            ; Get old status back
  1658.     out    VID_CMD,al        ; Do it
  1659.     ret
  1660. vtbell    endp
  1661.  
  1662. comment @
  1663. ; This routine is called when we want to reverse everything on the screen
  1664. ; from normal to reverse video, or vice versa.    It is called only when
  1665. ; the decscnm attribute is changed.  Preserves all registers.
  1666. ; Call:        no arguments.
  1667. ; This will work on graphics as well as text.  However, this is a true
  1668. ; reverser meaning that ALL 'dark bits' will be 'lit upp' all 'lit up'
  1669. ; ones will be 'darkened'.  This means for example that the reverse of
  1670. ; yellow (green + red) on black (none) will be blue on white (all =
  1671. ; blue + green + red).
  1672. revscn    proc    near
  1673.     push    ax
  1674.     push    cx
  1675.     push    si
  1676.     push    di
  1677.     push    ds
  1678.     push    es
  1679.     in    al,VID_CMD        ; Get video port status
  1680.     push    ax            ; Save it
  1681.     mov    al,7fh            ; Turn off multiple access
  1682.     out    VID_CMD,al        ;  and display
  1683.     mov    ax,PAR_GRN        ; Green first
  1684. revscn0:mov    ds,ax            ; Set up
  1685.     mov    es,ax            ;  all
  1686.     xor    si,si            ;  the
  1687.     mov    di,si            ;  pointers
  1688.     mov    bx,8000h        ; The whole plane
  1689.     mov    cx,40            ; One line
  1690.     mov    dx,9            ; 9 scan lines per char
  1691.     cld
  1692. revscn1:lodsw
  1693.     xor    ax,0ffffh
  1694.     stosw
  1695.     loop    revscn1            ; A full scan line
  1696.     dec    dx            ;  done
  1697.     jnz    revscn2            ; A full char line?
  1698.     add    si,7*128        ; Yes, skip the
  1699.     mov    di,si            ;  7 next lines
  1700.     sub    bx,7*64            ;  and adjust count
  1701.     mov    dx,9            ; Prepare for next char line
  1702. revscn2:sub    bx,64            ; Plane done?
  1703.     jz    revscn3            ; z = yes, plane done
  1704.     add    si,48            ; no, skip the non displayed
  1705.     mov    di,si            ;  last 48
  1706.     mov    cx,40            ; Prepare for next scan line
  1707.     jmp    short revscn1        ;  and go do it
  1708. revscn3:mov    ax,ds            ; Have we done
  1709.     cmp    ax,PAR_BLU        ;  the blue?
  1710.     jz    revscn5            ; Yes, all done, almost
  1711.     sub    ah,10h            ; Go do next plane
  1712.     jmp    short revscn0 
  1713. revscn5:pop    ax            ; Restore video
  1714.     out    VID_CMD,al        ;  status
  1715.     pop    es
  1716.     pop    ds
  1717.     pop    di
  1718.     pop    si
  1719.     pop    cx
  1720.     pop    ax
  1721.     ret
  1722. revscn    endp
  1723. end comment @
  1724.  
  1725. ; This is revscn which reverses the color attributes of characters currently
  1726. ; displayed on the video screen.  It will only work on text and graphic
  1727. ; characters.  Takes no arguments, preserves all registers.
  1728. REVSCN    PROC NEAR
  1729.            push    ax
  1730.     push    bx
  1731.     push    cx
  1732.     push    dx
  1733.     push    si
  1734.     push    di
  1735.     push    bp
  1736.     push    es
  1737.     push    ds
  1738.     in    al,VID_CMD    ; Read video state
  1739.     push    ax        ; Save it
  1740.     mov    al,01111000b    ; Mask current write bits, enable vram
  1741.     out    VID_CMD,al    ; Set up 
  1742.     mov    ax,IPAGE_SEG    ; Interrupt page
  1743.     mov    es,ax        ;  into es
  1744.     mov    bp,offset es:MTR_DFC
  1745.     mov    ds,es:[MTR_DS]    ; Monitor data segment
  1746.     mov    es,es:[MTR_DS]    ; Monitor data segment
  1747.     xor    cx,cx        ; Char index 0
  1748. revscn1:push    cx        ; Preserve around call to mtr rom
  1749.     push    es        ; This too
  1750.         mov    ax,cx        ; Index here
  1751.     mov    bl,COLUMNS
  1752.     div    bl        ; Line now in al and column in ah
  1753.     mov    bh,al        ; Line in bh
  1754.     mov    bl,ah        ; Parameter 1, column, in bl
  1755.     push    bx        ; *    Parameter # 1 set
  1756.     xchg    bh,bl        ; Parameter 2, line, from bh to bl
  1757.     push    bx        ; **   Parameter # 2 set
  1758.     xchg    bh,bl        ; Get right order back
  1759.     mov    ax,PAR_GRN    ; Point to green plane
  1760.     mov    es,ax
  1761.     shl    bh,1
  1762.     shl    bh,1
  1763.     shl    bh,1
  1764.     mov    al,es:byte ptr [bx+9*128]    ; Char index
  1765.     mov    ah,es:byte ptr [bx+10*128]    ; Char attributes
  1766.     push    ax        ; ***  Third param, al holds char index
  1767.     mov    dh,ah
  1768.     and    dh,111b        ; Foreground color
  1769.     mov    dl,ah
  1770.     shr    dl,1
  1771.     shr    dl,1
  1772.     shr    dl,1
  1773.     and    dl,111b        ; Background color
  1774.     cmp    cs:tempcol,dx    ; New color or fresh start?
  1775.     jz    revscn2        ; No, just skip all of this
  1776.     mov    cs:tempcol,dx    ; Remember color
  1777.     xchg    dh,dl        ; Reverse it
  1778.     call    setcol        ; Set the reversed color
  1779. revscn2:mov    ax,0
  1780.     push    ax         ; **** Fourth, display it as is
  1781.      call    dword ptr ds:[bp] ; Display char
  1782.     pop    es        ; Get these
  1783.     pop    cx        ;  back
  1784.     inc    cx
  1785.      cmp    byte ptr es:[STATUS],0        ; Status line not on?
  1786.     jz    revscn3                ; No, go do 24 lines
  1787.     cmp    cx,COLUMNS * (ROWS + 1)        ; < 80 * (24 + 1) = 2000?
  1788.     jb    revscn1                ; Yes, go do next char
  1789. revscn3:cmp    cx,COLUMNS * ROWS        ; < 80 * 24 = 1920?
  1790.     jb    revscn1                ; Yes, go do next char
  1791.     pop    cx                ; No, all done, almost
  1792.     out    VID_CMD,al    ; Restore video
  1793.     mov    cs:tempcol,0ffffh ; Reset for next time
  1794.     pop    ds
  1795.     pop    es
  1796.     pop    bp
  1797.     pop    di
  1798.     pop    si
  1799.     pop    dx
  1800.     pop    cx
  1801.     pop    bx
  1802.     pop    ax
  1803.     ret
  1804. tempcol    dw    0ffffh        ; Storage for the last set colors
  1805. REVSCN    ENDP
  1806.  
  1807. ; Set cursor postion.  Destroys dx.
  1808. ; DL = column, DH = row, both counted from 0,0 at upper left corner
  1809. setpos    proc    near
  1810.     jmp    poscur
  1811. setpos    endp
  1812.  
  1813. ; Set coloring attributes.
  1814. ; Enter with AH holding current video attribute byte,
  1815. ; BL holding ANSI color code (30-37 or 40-47) where 30's are foreground,
  1816. ; 40's are background. ANSI colors are 1 = red, 2 = green, 4 = blue.
  1817. ; Return new attribute byte in AH.
  1818.  
  1819. setcolor proc    near
  1820. setcol0:cmp    bl,30            ; ANSI color series?
  1821.     jb    setcol7            ; b = no
  1822.     cmp    bl,37            ; foreground set (30-37)?
  1823.     ja    setcol4            ; a = no, try background set
  1824.     sub    bl,30            ; take away the bias
  1825.     test    bl,1            ; ANSI red?
  1826.     jz    setcol1            ; z = no
  1827.     or    ah,2            ; Z-100 red foreground bit
  1828. setcol1:test    bl,2            ; ANSI green?
  1829.     jz    setcol2            ; z = no
  1830.     or    ah,4            ; Z-100 green foreground bit
  1831. setcol2:test    bl,4            ; ANSI blue?
  1832.     jz    setcol3            ; z = no
  1833.     or    ah,1            ; Z-100 blue foreground bit
  1834. setcol3:ret
  1835.  
  1836. setcol4:cmp    bl,40            ; background color set?
  1837.     jb    setcol7            ; b = no
  1838.     cmp    bl,47            ; background set is 40-47
  1839.     ja    setcol7            ; nb = no, not a color command
  1840.     sub    bl,40            ; take away the bias
  1841.     test    bl,1            ; ANSI red?
  1842.     jz    setcol5            ; z = no
  1843.     or    ah,10h            ; Z-100 red background bit
  1844. setcol5:test    bl,2            ; ANSI green?
  1845.     jz    setcol6            ; z = no
  1846.     or    ah,20h            ; Z-100 green background bit
  1847. setcol6:test    bl,4            ; ANSI blue?
  1848.     jz    setcol7            ; z = no
  1849.     or    ah,8h            ; Z-100 blue background bit
  1850. setcol7:ret
  1851. setcolor endp
  1852.  
  1853. ; Set screen color.  Destroys dx.
  1854. ; DH = foregroung color, DL = backgrond color per Z-100 standards.
  1855. ; 0 = black, 1 = blue, 2 = green, 3 = cyan, 4 = red, 5 = magenta,
  1856. ; 6 = yellow, 7 = white
  1857. setcol    proc    near
  1858.     push    ax
  1859.     push    dx
  1860.     mov    ah,conout
  1861.     mov    dl,ESCAPE
  1862.     int    dos
  1863.     mov    dl,'m'
  1864.     int    dos
  1865.     pop    dx
  1866.     push    dx
  1867.     mov    dl,dh
  1868.     add    dl,'0'
  1869.     int    dos
  1870.     pop    dx
  1871.     add    dl,'0'
  1872.     int    dos
  1873.     pop    ax
  1874.     ret
  1875. setcol    endp
  1876.  
  1877. ; Routine to do keyclick if flag is set, no arguments
  1878. vclick    proc    near
  1879.     test    vtemu.vtflgop,vskeyclick ; is keyclick flag on?
  1880.     jz    vclick1            ; z = no, just return
  1881.     mov    dl,keycli    
  1882.     call    keycom
  1883. vclick1:ret
  1884. vclick    endp
  1885.  
  1886. ;;; Action routines (verbs) for keyboard translator KEYBD in msuibm.
  1887. ; These are invoked by a jump instruction. Return carry clear for normal
  1888. ; processing, return carry set for invoking Quit (kbdflg has transfer char).
  1889. uparrw: mov    al,'A'            ; cursor keys
  1890.     jmp    short comarr
  1891. dnarrw: mov    al,'B'
  1892.     jmp    short comarr
  1893. rtarr:    mov    al,'C'
  1894.     test    vtemu.vtflgop,vswdir    ; writing left to right?
  1895.     jz    comarr            ; z = yes
  1896.     mov    al,'D'            ; reverse sense of keys
  1897.     jmp    short comarr
  1898. lfarr:    mov    al,'D'
  1899.     test    vtemu.vtflgop,vswdir    ; writing left to right?
  1900.     jz    comarr            ; z = yes
  1901.     mov    al,'C'            ; reverse sense of keys
  1902. comarr: push    ax            ; save final char
  1903.     mov    ttyact,0        ; network, group chars for packet
  1904.     test    vtemu.vtflgop,decanm    ; ANSI mode?
  1905.     jz    comar2            ; z = no
  1906.     mov    al,CSI            ; CSI character
  1907.     test    vtemu.vtflgop,decckm    ; cursor key mode reset?
  1908.     jz    comar1            ; z = yes
  1909.     mov    al,SS3            ; SS3 character
  1910. comar1: call    out8bit            ; send in 7 or 8 bit form
  1911.     jmp    short comar3
  1912.  
  1913. comar2: mov    al,escape        ; do Heath/VT52 mode "ESC char"
  1914.     call    prtbout
  1915. comar3: pop    ax            ; recover final char
  1916.     mov    ttyact,1        ; network, restore tty active flag
  1917.     call    prtbout
  1918.     ret
  1919.  
  1920. f0:    mov    al,'J'            ; Z-100 function keys
  1921.     jmp    short comf
  1922. f1:    mov    al,'S'
  1923.     jmp    short comf
  1924. f2:    mov    al,'T'
  1925.     jmp    short comf
  1926. f3:    mov    al,'U'
  1927.     jmp    short comf
  1928. f4:    mov    al,'V'
  1929.     jmp    short comf
  1930. f5:    mov    al,'W'
  1931.     jmp    short comf
  1932. f6:    mov    al,'P'
  1933.     jmp    short comf
  1934. f7:    mov    al,'Q'
  1935.     jmp    short comf
  1936. f8:    mov    al,'R'
  1937.     jmp    short comf
  1938. f9:    mov    al,'I'
  1939.     jmp    short comf0
  1940. f10:    mov    al,'J'
  1941.     jmp    short comf0
  1942. f11:    mov    al,'K'
  1943.     jmp    short comf0
  1944. f12:    mov    al,'L'
  1945.     jmp    short comf0
  1946. sf0:    mov    al,'E'
  1947. comf:    mov    ah,0            ; only one char
  1948.     jmp    short comf_
  1949. sf1:    mov    al,'A'
  1950.     jmp    short comf1
  1951. sf2:    mov    al,'B'
  1952.     jmp    short comf1
  1953. sf3:    mov    al,'C'
  1954.     jmp    short comf1
  1955. sf4:    mov    al,'D'
  1956.     jmp    short comf1
  1957. sf5:    mov    al,'E'
  1958.     jmp    short comf1
  1959. sf6:    mov    al,'F'
  1960.     jmp    short comf1
  1961. sf7:    mov    al,'G'
  1962.     jmp    short comf1
  1963. sf8:    mov    al,'H'
  1964.     jmp    short comf1
  1965. sf9:    mov    al,'I'
  1966.     jmp    short comf1
  1967. sf10:    mov    al,'J'
  1968.     jmp    short comf1
  1969. sf11:    mov    al,'K'
  1970.     jmp    short comf1
  1971. i_chr:    cmp    insert,'O'        ; overwrite mode?
  1972.     mov    insert,'O'
  1973.     jnz    i_chr1            ; no, make it overwrite
  1974.     mov    insert,'@'        ; yes, make it insert
  1975. i_chr1: mov    al,insert
  1976.     jmp    short comf
  1977. d_chr:    mov    al,'N'
  1978.     jmp    short comf
  1979. i_line: mov    al,'L'
  1980.     jmp    short comf
  1981. d_line: mov    al,'M'       
  1982.     jmp    short comf
  1983. comf0:    mov    ah,'0'            ; second char is '0'
  1984.     jmp    short comf_
  1985. comf1:    mov    ah,'1'            ; second char is '1'
  1986. comf_:    push    ax            ; save final char
  1987.     mov    ttyact,0        ; network, group chars for packet
  1988.     mov    al,escape        ; output ESC
  1989.     call    prtbout
  1990.     pop    ax            ; get the saved char
  1991.     cmp    ah,0            ; only one char?
  1992.     jz    comf_1
  1993.     push    ax            ; save it again
  1994.     xchg    al,ah            ; need ah first
  1995.     call    prtbout
  1996.     pop    ax            ; get the saved char
  1997. comf_1: mov    ttyact,1        ; network, restore tty active flag
  1998.     call    prtbout
  1999.     ret
  2000.  
  2001. pf1:    mov    al,'P'            ; keypad function keys PF1-4
  2002.     jmp    short compf
  2003. pf2:    mov    al,'Q'
  2004.     jmp    short compf
  2005. pf3:    mov    al,'R'
  2006.     jmp    short compf
  2007. pf4:    mov    al,'S'
  2008. compf:    push    ax            ; save final char
  2009.     mov    ttyact,0        ; network, group chars for packet
  2010.     test    vtemu.vtflgop,decanm    ; ansi mode?
  2011.     jz    short compf1        ; z = no
  2012.     mov    al,SS3
  2013.     call    out8bit            ; send 7 or 8 bit version
  2014.     jmp    short compf2
  2015. compf1: mov    al,escape        ; output ESC
  2016.     call    prtbout
  2017. compf2: pop    ax            ; get the saved char
  2018.     mov    ttyact,1        ; network, restore tty active flag
  2019.     call    prtbout
  2020.     ret
  2021.  
  2022. kp0:    mov    al,'p'            ; keypad numeric keys
  2023.     jmp    short comkp
  2024. kp1:    mov    al,'q'
  2025.     jmp    short comkp
  2026. kp2:    mov    al,'r'
  2027.     jmp    short comkp
  2028. kp3:    mov    al,'s'
  2029.     jmp    short comkp
  2030. kp4:    mov    al,'t'
  2031.     jmp    short comkp
  2032. kp5:    mov    al,'u'
  2033.     jmp    short comkp
  2034. kp6:    mov    al,'v'
  2035.     jmp    short comkp
  2036. kp7:    mov    al,'w'
  2037.     jmp    short comkp
  2038. kp8:    mov    al,'x'
  2039.     jmp    short comkp
  2040. kp9:    mov    al,'y'
  2041.     jmp    short comkp
  2042. kpminus:mov    al,'m'
  2043.     jmp    short comkp
  2044. kpcoma: mov    al,'l'
  2045.     jmp    short comkp
  2046. kpenter:mov    al,'M'
  2047.     jmp    short comkp
  2048. kpdot:    mov    al,'n'
  2049. comkp:    test    vtemu.vtflgop,deckpam    ; keypad application mode active?
  2050.     jnz    comkp1            ; nz = yes, use escape sequences
  2051.     sub    al,40h            ; deduct offset to numeric symbols
  2052.     push    ax            ; save final char
  2053.     jmp    comkp3            ; and send that single char
  2054. comkp1: push    ax
  2055.     mov    ttyact,0        ; network, group chars for packet
  2056.     test    vtemu.vtflgop,decanm    ; ANSI mode?
  2057.     jz    comkp2            ; z = no
  2058.     mov    al,SS3            ; SS3 character
  2059.     call    out8bit            ; send 7 or 8 bit version
  2060.     jmp    comkp3
  2061. comkp2: mov    al,escape        ; output "ESC ?"
  2062.     call    prtbout
  2063.     mov    al,'?'
  2064.     call    prtbout
  2065. comkp3: pop    ax            ; recover final char
  2066.     mov    ttyact,1        ; network, restore tty active flag
  2067.     call    prtbout            ; send it
  2068.     ret
  2069.  
  2070. klogon    proc    near            ; resume logging (if any)
  2071.     test    flags.capflg,logses    ; session logging enabled?
  2072.     jz    klogn            ; z = no, forget it
  2073.     or    argadr.flgs,capt    ; turn on capture flag
  2074.     or    yflags,capt        ; set local msy flag as well
  2075. klogn:    clc
  2076.     ret
  2077. klogon    endp
  2078.  
  2079. klogof    proc    near            ; suspend logging (if any)
  2080.     and    argadr.flgs,not capt    ; stop capturing
  2081.     and    yflags,not capt        ; reset local msy flag as well
  2082.     clc
  2083.     ret
  2084. klogof    endp
  2085.  
  2086. snull    proc    near            ; send a null byte
  2087.     xor    al,al            ; the null
  2088.     jmp    prtbout            ; send without logging and local echo
  2089. snull    endp
  2090.  
  2091. ; output, no echo, 8-bit control chars as literals or "ESC char" form
  2092. out8bit proc    near
  2093.     mov    ttyact,0        ; network, group chars for packet
  2094.     cmp    flags.vtflg,ttvt320    ; VT320?
  2095.     jne    out8bi1            ; ne = no
  2096.     cmp    parmsk,7fh        ; using parity?
  2097.     je    out8bi1            ; e = yes
  2098.     test    vtemu.vtflgop,vscntl    ; doing 8-bit controls?
  2099.     jnz    out8bi2            ; nz = yes, send 8-bit control char
  2100. out8bi1:test    al,80h            ; in range for C1 controls?
  2101.     jz    out8bi2            ; z = no
  2102.     cmp    al,9fh
  2103.     ja    out8bi2            ; a = no
  2104.     push    ax
  2105.     mov    al,escape        ; send ESCAPE
  2106.     call    prtbout
  2107.     pop    ax
  2108.     sub    al,40h            ; compose second char
  2109. out8bi2:mov    ttyact,1        ; network, restore single char mode
  2110.     jmp    prtbout            ; send final char
  2111. out8bit endp
  2112.                     ; these commands invoke Quit
  2113. cdos:    mov    al,'P'            ; Push to DOS
  2114.     jmp    short cmdcom
  2115. cstatus:mov    al,'S'            ; Status
  2116.     jmp    short cmdcom
  2117. cquit:    mov    al,'C'            ; Exit Connect mode
  2118.     jmp    short cmdcom
  2119. cquery: mov    al,'?'            ; Help
  2120.     jmp    short cmdcom
  2121. chang:    mov    al,'H'            ; Hangup, drop DTR & RTS
  2122. cmdcom: mov    kbdflg,al        ; pass char to msster.asm via kbdflg
  2123.     stc                ; signal that Quit is needed
  2124.     ret
  2125.  
  2126. ;SCROLL makes it possible to review the last screen (up to 26 lines).  F11
  2127. ;invokes scroll and scrolling is done with BACK SPACE and LINE FEED keys.
  2128. ;The RETURN key latches the screen in the new position, any other key restores
  2129. ;to the original status.
  2130. scroll    proc near
  2131.     push    ax
  2132.     push    cx
  2133.     push    dx
  2134.     push    es
  2135.     mov    ax,ipage_seg        ; the interrupt page
  2136.     mov    es,ax
  2137.     mov    es,word ptr es:mtr_ds    ; find monitor data segment here
  2138.     cmp    byte ptr es:VRAM_SIZE,1    ; Must be 1 for 64k video chips
  2139.     jz    scroll1            ; Yes, go on
  2140.     mov    ah,prstr        ; No, tell user, skip
  2141.     mov    dx,offset vidmsg
  2142.     int    dos
  2143.     jmp    short scroll6
  2144. scroll1:mov    dx,word ptr es:DISP_START ; get start address
  2145.     mov    startad,dx        ; save it
  2146. scroll2:mov    dx,word ptr es:DISP_START ; get start address
  2147.     sub    dx,80            ; assume 1 line backwards
  2148.     cmp    al,10            ; line feed ^J
  2149.     jnz    scroll3            ; no, backwards
  2150.     add    dx,160            ; yes, forward
  2151. scroll3:mov    word ptr es:DISP_START,dx ; set new start address
  2152.     mov    dx,0ffh
  2153.     mov    byte ptr es:DISP_UPDATE,dl ; request update
  2154.     mov    ah,coninq
  2155.     int    dos
  2156.     cmp    al,8            ; if back space ^H, go scroll up
  2157.     jz    scroll2
  2158.     cmp    al,10            ; if line feed ^J, go scroll down
  2159.     jz    scroll2
  2160.     cmp    al,cr            ; if carrage return, go latch it
  2161.     jz    scroll4
  2162.     mov    dx,startad        ; else, just go back
  2163.     mov    word ptr es:DISP_START,dx ; set start address
  2164.     mov    dx,0ffh
  2165.     mov    byte ptr es:DISP_UPDATE,dl ; request update
  2166.     jmp    short scroll6
  2167. ;
  2168. scroll4:
  2169.     mov    ax,word ptr es:DISP_START ; get start address
  2170.     mov    cl,4            ; shift count
  2171.     shr    ax,cl            ; al now has latch value
  2172.     out    0dah,al            ; initialize latch
  2173.     mov    dx,1700h        ; put cursor at beginning of last line
  2174.     call    poscur
  2175.     test    yflags,modoff        ; is mode line disabled?
  2176.     jnz    scroll5            ; yes, skip it
  2177.     call    modlin            ; enable and write modline
  2178.     jmp    short scroll6
  2179. scroll5:call    clrmod            ; clear mode line
  2180. scroll6:pop    es
  2181.     pop    dx
  2182.     pop    cx
  2183.     pop    ax
  2184.     ret
  2185. scroll    endp
  2186.  
  2187. ; (BDT) new screen-scrolling routines.    Single, circular buffer
  2188.      
  2189. homwnd    proc    near            ; "home" to start of the buffer
  2190.     push    cx            ; save registers
  2191.     mov    cx,lxtra        ; save this many lines
  2192.     call    putcirc            ; save them
  2193.     mov    linec,0            ; reset the current pointer
  2194.     call    getcirc            ; now get the new screen
  2195.     pop    cx            ; restore registers
  2196.     clc
  2197.     ret
  2198. homwnd    endp
  2199.      
  2200. endwnd    proc    near            ; "end" to end of the buffer
  2201.     push    cx            ; save registers
  2202.     mov    cx,lxtra        ; save this many lines
  2203.     call    putcirc            ; save them
  2204.     mov    cx,lcnt            ; reset the current pointer
  2205.     mov    linec,cx        ; save the results
  2206.     call    getcirc            ; now get the new screen
  2207.     pop    cx            ; restore registers
  2208.     clc
  2209.     ret
  2210. endwnd    endp
  2211.      
  2212. dnwpg    proc    near            ; scroll down 1 page
  2213.     push    cx            ; save registers
  2214.     mov    cx,lxtra        ; save this many lines
  2215.     call    putcirc            ; save them
  2216.     mov    cx,linec        ; reset the current pointer
  2217.     add    cx,lxtra        ;  to the next page
  2218.     cmp    cx,lcnt            ; did we go past the end?
  2219.     jbe    dnwpg1            ; be = no, we're OK
  2220.     mov    cx,lcnt            ; yup, back up
  2221. dnwpg1:
  2222.     mov    linec,cx        ; save the results
  2223.     call    getcirc            ; now get the new screen
  2224.     pop    cx            ; restore registers
  2225.     clc
  2226.     ret
  2227. dnwpg    endp
  2228.      
  2229. dnone    proc    near            ; scroll down 1 line
  2230.     push    cx            ; save registers
  2231.     mov    cx,lxtra        ; save this many lines
  2232.     call    putcirc            ; save them
  2233.     mov    cx,linec        ; reset the current pointer
  2234.     inc    cx            ;  to the next line
  2235.     cmp    cx,lcnt            ; oops, did we go past the end?
  2236.     jbe    dnone1            ; be = no, we're OK
  2237.     mov    cx,lcnt            ; yup, back up
  2238. dnone1:
  2239.     mov    linec,cx        ; save the results
  2240.     call    getcirc            ; now get the new screen
  2241.     pop    cx            ; restore registers
  2242.     clc
  2243.     ret
  2244. dnone    endp
  2245.      
  2246. upwpg    proc    near            ; scroll up 1 page
  2247.     push    cx            ; save registers
  2248.     mov    cx,lxtra        ; save this many lines
  2249.     call    putcirc            ; save them
  2250.     mov    cx,linec        ; reset the current pointer
  2251.     sub    cx,lxtra        ;  to the previous page
  2252.     cmp    cx,0            ; oops, did we go past the end?
  2253.     jge    upwpg1            ; ge = no, we're OK
  2254.     xor    cx,cx            ; yup, back up
  2255. upwpg1:
  2256.     mov    linec,cx        ; save the results
  2257.     call    getcirc            ; now get the new screen
  2258.     pop    cx            ; restore registers
  2259.     clc
  2260.     ret
  2261. upwpg    endp
  2262.      
  2263. upone    proc    near            ; scroll up 1 line
  2264.     push    cx            ; save registers
  2265.     mov    cx,lxtra        ; save this many lines
  2266.     call    putcirc            ; save them
  2267.     mov    cx,linec        ; reset the current pointer
  2268.     dec    cx            ;  to the previous line
  2269.     cmp    cx,0            ; oops, did we go past the end?
  2270.     jge    upone1            ; ge = no, we're OK
  2271.     xor    cx,cx            ; yup, back up
  2272. upone1:
  2273.     mov    linec,cx        ; save the results
  2274.     call    getcirc            ; now get the new screen
  2275.     pop    cx            ; restore registers
  2276.     clc
  2277.     ret
  2278. upone    endp
  2279.      
  2280. ; Put cx lines into the circular buffer.  Characters are stored as a word
  2281. ; containig the Z-100 font index (low) and the Z-100 attributes (high).
  2282. ; Source segment is tv_segs which is set to point to the green video plane.
  2283. ; Source offset for each char is calculated below based on the screen char
  2284. ; index in si.    The index starts at 0 and ends at COLUMNS * ROWS - 1 = 1919,
  2285. ; corresponding to 1920 characters.
  2286. putcirc proc    near            ; put lines in the circular buffer
  2287.     jcxz    putcir9            ; z = no lines to save
  2288.     push    es            ; save ES for a tad
  2289.     xor    si,si            ; Screen char index
  2290.     mov    ax,linef        ; get the first line pointer
  2291.     add    ax,linec        ; add the current line counter
  2292.     dec    ax            ; get a running start
  2293.     sub    si,COLUMNS            ; Here too
  2294. putcir1:inc    ax            ; increment the current line pointer
  2295.     add    si,COLUMNS              ; This many char per line
  2296.     cmp    ax,linee        ; fallen off the end of the buffer?
  2297.     jb    putcir2            ; b = no, proceed
  2298.     sub    ax,linee        ; back up to the buffer start
  2299. putcir2:push    ax            ; save the current line pointer
  2300.     mul    ppl            ; compute the paragraph offset
  2301.     add    ax,iniseg        ; add the initial segment
  2302.     mov    es,ax            ; now we have the segment pointer
  2303.     xor    di,di            ; initial buffer offset is 0
  2304.     push    cx            ; save the number of lines
  2305.     push    si            ; Save index
  2306.     xor    ch,ch            ; get the number of characters to move
  2307.     mov    cl,COLUMNS        ; One row
  2308.     push    ds            ; get the offset of the screen
  2309.     mov    ds,tv_segs        ; get the segment of the screen
  2310.         mov    ax,si            ; Index here
  2311.     div    cl            ; Line now in al and column in ah
  2312.     mov    bh,al            ; Line in bh
  2313.     mov    bl,ah            ; Column in bl
  2314.     shl    bh,1
  2315.     shl    bh,1
  2316.     shl    bh,1
  2317. putcir3:mov    al,ds:byte ptr [bx+9*128]    ; Char index
  2318.     mov    ah,ds:byte ptr [bx+10*128]    ; Char attributes
  2319.     stosw
  2320.     inc    bl            ; Next char
  2321.     loop    putcir3            ; Go back for next char
  2322.     pop    ds            ; restore DS
  2323.     pop    si            ; Restore index
  2324.     pop    cx            ; restore the line count
  2325.     pop    ax            ; restore the buffer counter
  2326.     loop    putcir1            ; go back for more
  2327.     pop    es            ; restore ES
  2328. putcir9:ret                ; Note, also used by getcirc below
  2329. putcirc endp
  2330.      
  2331. ; Get CX lines from the circular buffer, non destructivly.  Destination
  2332. ; segment is the green video plane and destination offset for each char
  2333. ; is calculated below based on the screen char index in di.  The index
  2334. ; starts at 0 and ends at COLUMNS * ROWS - 1 = 1919, corresponding to
  2335. ; 1920 characters.  The call to MTR_DFC writes to the destination.
  2336. getcirc proc    near            ; get lines from the circular buffer
  2337.     mov    cx,lxtra        ; restore this many lines
  2338.     jcxz    putcir9            ; z = nothing to do
  2339.     push    es            ; save ES for a tad
  2340.     mov    ax,IPAGE_SEG        ; Interrupt page
  2341.     mov    es,ax            ;  into es
  2342.     mov    bp,offset es:MTR_DFC    ; Need this pointer for our call
  2343.     mov    es,es:[MTR_DS]        ; Monitor data segment
  2344.     xor    di,di            ; Screen char index
  2345.     mov    ax,linef        ; get the first line pointer
  2346.     add    ax,linec        ; add the current line counter
  2347.     dec    ax            ; get a running start
  2348.     sub    di,COLUMNS            ; Here too
  2349. getcir1:inc    ax            ; increment the current line pointer
  2350.     add    di,COLUMNS              ; This many char per line
  2351.     cmp    ax,linee        ; fallen off the end of the buffer?
  2352.     jb    getcir2            ; b = no, proceed
  2353.     sub    ax,linee        ; back up to the buffer start
  2354. getcir2:push    ax            ; save the current line pointer
  2355.     mul    ppl            ; compute the paragraph offset
  2356.     add    ax,iniseg        ; add the initial segment
  2357.     xor    si,si            ; initial offset is 0
  2358.     push    cx            ; save the number of lines
  2359.     push    di            ; Save index
  2360.     xor    ch,ch            ; get the number of characters to move
  2361.     mov    cl,COLUMNS        ; One row
  2362.     push    ds            ; save DS for a tad
  2363.     push    es            ; Save MTR_DS
  2364.     mov    ds,ax            ; now we have the segment pointer
  2365.         mov    ax,di            ; Index here
  2366.     div    cl            ; Line now in al and column in ah
  2367.     mov    bh,al            ; Line in bh
  2368.     mov    bl,ah            ; Parameter 1, column, in bl
  2369.     push    bx            ; *    Parameter # 1 set
  2370.     xchg    bh,bl            ; Parameter 2, line, from bh to bl
  2371.     push    bx            ; **   Parameter # 2 set
  2372.     xchg    bh,bl            ; Get right order back
  2373. getcir3:mov    bh,0            ; Column now in bx
  2374.     shl    bx,1            ; 2 bytes per cell in buffer
  2375.     mov    ax,word ptr ds:[di.bx]    ; Get the char from buffer
  2376.     push    ax            ; ***  Parameter # 3 set
  2377.     mov    dh,ah
  2378.     and    dh,111b            ; Foreground color
  2379.     mov    dl,ah
  2380.     shr    dl,1
  2381.     shr    dl,1
  2382.     shr    dl,1
  2383.     and    dl,111b            ; Background color
  2384.     cmp    cs:tempcol,dx        ; New color or fresh start?
  2385.     jz    getcir4            ; No, just skip all of this
  2386.     mov    cs:tempcol,dx        ; Remember color
  2387.     call    setcol            ; Set the color
  2388. getcir4:and    ah,80h            ; Reverse video?
  2389.     mov    ax,0             ; Assume no
  2390.     jz    getcir5            ; No, skip this
  2391.     mov    ax,0ffffh        ; Set up parameter # 4
  2392. getcir5:push    ax            ; **** Parameter # 4 set
  2393.      call    dword ptr es:[bp]    ; Display char
  2394.     pop    es            ; We need this for our call
  2395.     push    es            ; Save again
  2396.     sub    sp,2            ; Point to first parameter
  2397.     pop    bx            ; Get it back
  2398.     inc    bl            ; Next char
  2399.     push    bx            ; *    Parameter # 1 set
  2400.     sub    sp,2            ; **   Parameter # 2 set, old value
  2401.     loop    getcir3
  2402.     add    sp,6
  2403.     pop    ds            ; restore DS
  2404.     pop    di            ; restore index
  2405.     pop    cx            ; restore the line count
  2406.     loop    getcir1            ; go back for more
  2407.     mov    cs:tempcol,0ffffh    ; Restore for next time
  2408.     pop    es            ; restore ES
  2409. getcir6:ret
  2410. getcirc endp
  2411.                     ; Screen dump entry from keyboad xlat
  2412. dmpscn    proc    near            ; dump screen to file
  2413.     call    dumpscr            ; do buffer to file
  2414.     clc                ; do not exit Connect mode
  2415.     ret
  2416. dmpscn    endp
  2417.  
  2418. code    ends 
  2419.     end
  2420.  
  2421.