home *** CD-ROM | disk | FTP | other *** search
/ Columbia Kermit / kermit.zip / extra / nyenhuis3.arc / MSYIBM.ASM < prev    next >
Assembly Source File  |  1990-01-16  |  121KB  |  3,714 lines

  1.     NAME msyibm
  2. ; File MSYIBM.ASM
  3.     include mssdef.h
  4. ; edit history:
  5. ; Last edit 16 Jan 1990
  6. ; 9 May 1989 Add Bert Tyler's (NIH) new screen rollback routines.
  7. ; 21 Jan 1989 be more tolerate of propriatary video modes above 18 when
  8. ;  determining screen segment, Tnx to Terry Kennedy. Add check for IBM
  9. ;  85xx monitors on Video 7 boards, no 132 columns if it is the monitor.
  10. ;  Retain 43 rows on Video 7 boards.
  11. ; 30 Nov 1988 Add SET TERM CLEAR screen clearing support.
  12. ; 28 Nov 1988 Accomodate Tseng Labs UltraPAK mono/Herc board w/132 cols.
  13. ;  132 column mode is 18h. Requires Tseng's BIGSCR.COM (use BIGSCR /R:25
  14. ;  to enable 132x25 feature). Thanks to Tseng Labs for technical support.
  15. ; 21 Nov 1988 Version 2.32
  16. ; 14 Nov 1988 Write a space during lclini to obtain default screen colors.
  17. ; 12 Nov 1988 Add procs vtrmac and vtsmac to allow exit from Connect mode and
  18. ;  invokation of macros TERMINALR and TERMINALS by reception of escape seqs
  19. ;  in file mszibm.asm or by keyboard verbs.
  20. ; 7 Oct 1988 Reverse left/right arrow key codes when writing right to left.
  21. ; 24 Sept 1988 Make output to printer be buffered and flow controlled.
  22. ; 1 July 1988 Version 2.31
  23. ; 19 June 1988 Add Everex EVGA support, from Terry Kennedy.
  24. ; 10 June 1988 Add oldsp and procedure endcon to exit Connect mode if output
  25. ;  fails, mostly for networking (but we don't know that here).
  26. ; 23 May 1988 Add Everex EV-659 ega board test from Alex Zliu. Fixed incorrect
  27. ;  screen width assumption at startup.
  28. ; 29 March 1988 Include flag ttyact to group string bytes into one net packet,
  29. ;  thanks to Paul Fox of AT&T.
  30. ; 23 March 1988 Add "fairness" word to let serial port deliver max chars
  31. ;  between kbd reads, for connect mode only. [jrd]
  32. ; 10 Feb 1988 Revise getcirc and vtscrX routines to do proper scrolling with
  33. ;  MS Window 1.0x/2.0x [jrd].
  34. ; 9 Feb 1988 Mode line again. Make flags.modflg 0 for off, 1 for on and owned
  35. ;  by Kermit, and 2 for on and owned by remote host (toggling suppressed).
  36. ; 25 Jan 1988 Add global byte SCROLL, set in msz, to control emulator screen
  37. ;  scrolling for higher speeds. [jrd]
  38. ; 5 Jan 1988 Restore cursor codes broken by Tek code additions. [jrd]
  39. ; 1 Jan 1988 version 2.30
  40.  
  41.     public    term, lclyini                ; entry points
  42.     public    prtbout, prtnout, csrtype, scrseg
  43.     public    atsclr, vtscru, vtscrd, trnmod, out8bit, vclick, vtbell
  44.     public    chgdsp, vtroll, crt_lins, crt_cols, tv_mode, vtclear
  45.             ; action verb procedures for keyboard translator
  46.     public    uparrw, dnarrw, rtarr, lfarr, pf1, pf2, pf3, pf4
  47.     public    kp0, kp1, kp2, kp3, kp4, kp5, kp6, kp7, kp8, kp9
  48.     public    kpminus, kpcoma, kpenter, kpdot, chrout, cstatus, cquit
  49.     public    cquery, dmpscn,    vtans52, vtinit, dnwpg, upwpg, endwnd, homwnd
  50.     public    upone, dnone, trnprs, dumpscr, modlin, snull
  51.     public    klogon, klogof, cdos, chang, khold, vtrmac, vtsmac
  52.     public    decf6,decf7,decf8,decf9,decf10,decf11,decf12,decf13,decf14
  53.     public    dechelp,decdo,decf17,decf18,decf19,decf20, udkclear
  54.     public    decfind, decinsert, decremove, decselect, decprev
  55.     public    decnext, setudk
  56.  
  57.     public    vtemu, crt_mode, scbattr, refresh, low_rgt    ; data
  58.         public  savescr, restscr, pntchr, pntchk, pntflsh    ; code
  59.     public    setpos, getpos, getatch, setatch, putchar, yflags
  60.     public    getbold, setbold, clrbold, getblink, setblink, clrblink
  61.     public    getunder, setunder, clrunder, revideo, revscn, setcolor
  62.     public    setrev, clrrev, insdecom
  63.     public    vts, vtstat, termtb            ; terminal emulation
  64.  
  65. ; some definitions
  66. ; hardware
  67. crt_status equ    3dah            ; CGA crt status port
  68. disp_enb equ    8            ; CGA display enable bit
  69. crtmset    equ    3D8H            ; CGA CRT mode set port
  70. screen    equ    10h            ; Bios screen interrupt
  71. biostty    equ    0eh            ; Bios screen tty write mode
  72.  
  73. modfrm    struc                ; format of mode (status) line
  74.     db    'Esc-chr: '        ; do not write in last column
  75. m_echr    db    2 dup (?)
  76.     db    '  help: '
  77. m_hlp    db    2 dup (?)
  78.     db    '?  port:'
  79. m_prt    db    1 dup (?)
  80.     db    ' speed:'
  81. m_baud    db    5 dup (?)
  82.     db    ' parity:'
  83. m_par    db    4 dup (?)
  84.     db    ' echo:'
  85. m_echo    db    3 dup (?)
  86. m_term    db    13 dup (' ')        ; 13 bytes for term type
  87. m_prn    db    3 dup (' ')        ; show PRN when printer is on
  88.     db    '$'            ; terminator
  89. modfrm    ends
  90.  
  91. ; structure for status information table sttab.
  92. stent    struc
  93. sttyp    dw    ?        ; type (actually routine to call)
  94. msg    dw    ?        ; message to print
  95. val2    dw    ?        ; needed value: another message, or tbl addr
  96. tstcel    dw    ?        ; address of cell to test, in data segment
  97. basval    dw    0        ; base value, if non-zero
  98. stent    ends
  99.  
  100.  
  101. data    segment    public 'data'
  102.     extrn    flags:byte, mar_top:byte, mar_bot:byte, portval:word
  103.     extrn    filtst:byte, dmpname:byte, kbdflg:byte, rxtable:byte
  104.     extrn    anspflg:byte, tekflg:byte, scroll:byte, ttyact:byte
  105.     extrn    holdscr:byte, taklev:byte, takadr:word, mcctab:byte
  106.     extrn    video_state:byte, trans:byte, npages:word, comand:byte
  107.     extrn    denyflg:word, tekgraf:byte, rdbuf:byte, dupflg:byte
  108.     extrn    chcontrol:byte, kbcodes:byte
  109.  
  110. ; stuff for screen routines
  111. yflags    db    0            ; status flags
  112. flags1    db    0            ; internal flags (but used in mszibm)
  113. prtscr    equ    1            ; print screen pressed
  114. inited    equ    08h            ; been here before
  115. vtinited db    0            ; flag for emulator having been inited
  116. vtclear    db    0            ; nonzero to redo emulator screen
  117. cursor    dw    0
  118. parmsk    db    0            ; 8/7 bit parity mask, for reception
  119. argadr    dw    ?            ; address of arg blk
  120. skip    dw    0
  121.  
  122. vid7id    db    'VEGA BIOS Code, '    ; Video 7 Vega version string subset
  123. vid7len    equ    $-vid7id        ; length of string
  124. vid7id2    db    'Video Seven BIOS Code, ' ; Video 7 VGA board
  125. vid7len2 equ    $-vid7id2
  126. atiwid    db    'ATI EGA Wonder Bios,'    ; ATI EGA wonder version string subset
  127. atilen    equ    $-atiwid        ; length of string, inc terminator
  128. tsngid    db    'Tseng'            ; Tseng Labs EVA (& Orchid Designer)
  129. tsnglen    equ    $-tsngid
  130. stbvid    db    'TVGA'            ; STB VGA/EM (also Tseng TVGA)
  131. stbvlen    equ    $-stbvid        ;
  132. evrxid  db      'Everex'                ; Everex Micro Enhancer Deluxe EGA
  133. evrxlen equ     $-evrxid
  134. evgid    db    'VGA EV673'        ; Everex EVGA EV-673
  135. evglen    equ    $-evgid
  136. attvdc6    db    '003116'        ; AT&T video board, at c000:35h
  137. attvdlen equ    $-attvdc6
  138. attvdc7    db    'C02000'        ; AT&T video board, at e000:10h
  139. cols80    db    'COLS80.BAT',0        ; to 80 column mode batch file
  140. cols132    db    'COLS132.BAT',0        ; to 132 column mode batch file
  141. ega_mode db    0            ; non-zero if IBM EGA is in use
  142. tvhere    equ    0feh            ; Topview active query
  143. tvsynch    equ    0ffh            ; Topview resynch request
  144. tv_segs    dw    0            ; Topview virtual screen, segment
  145. tv_sego    dw    0            ; and offset
  146. tv_mode    db    0            ; flag, 0 = no Topview
  147. savadr    dw    2 dup (0)        ; offset then segment of saved screen
  148. savflg    dw    0            ; low_rgt at time of screen save
  149. att_low_mask    equ    06H        ; Various attribute-related equates
  150. att_underline    equ    01H
  151. att_intensity    equ    08H
  152. att_blink    equ    80H
  153. att_normal    equ    07h
  154.  
  155. ; The following are used to turn the display back on (after scrolling etc.)
  156. msets    db    2CH,28H,2DH,29H,2AH,2EH,1EH,29H
  157.  
  158.  
  159. vtemu    emulst    <>            ; emulator flags
  160. trmtyp    db    0            ; most recent terminal type
  161. mtty    db    '  TTY   '        ; no terminal type (mode line)
  162. belltype db    0            ; 0 = aural bell, 1 = visual
  163. fairness dw    0
  164. fairprn    dw    0
  165. lincur    dw    ?            ; cursor type save area
  166. scbattr db    ?            ; screen background attribute
  167. dosattr    db    ?            ; screen attributes at init time
  168. userbold db    0            ; screen bold attribute at start up
  169. savattr    db    ?            ; current emulator attributes
  170. oldsp    dw    0            ; offset to longjmp to for i/o failure
  171. ten    db    10            ; byte constant for key defines
  172. temp    dw    0            ; scratch storage
  173. captrtn    dw    0            ; routine to call for captured output
  174. dmphand    dw    -1            ; screen dump file handle
  175. dumplen    equ    132
  176. dumpbuf    db    dumplen dup (?), cr, lf    ; 134 byte dump work buffer
  177. dumpsep    db    FF,cr,lf        ; screen image separators
  178. dmperr    db    ' Cannot open file to save screen to disk $'
  179. memerr    db    cr,lf,'Not enough memory for terminal emulator$'
  180. crlf    db    cr,lf,'$'
  181. flowon    db    0            ; flow control chars xon
  182. flowoff    db    0            ;  and xoff (or both null if none)
  183. pntmsg    db    'Printer not ready, printing request skipped$'
  184. pntptr    dw    dumpbuf            ; pointer to next free byte in buffer
  185.  
  186. ; some static data for mode line
  187. modbuf    modfrm    <>            ; mode line buffer
  188. unkbaud    db    'unkwn'            ; must be 5 chars
  189. baudn    db    ' 45.5',' 50  ',' 75  ',' 110 ','134.5',' 150 ',' 300 ',' 600 '
  190.     db    ' 1200',' 1800',' 2000',' 2400',' 4800',' 9600','19200','38400'
  191.     db    '57.6K','115 K'
  192. baudnsiz  equ    18            ; # of baud rates known (tbl size / 4)
  193. parnams    db    'even','mark','none','odd ','spc '
  194. lclmsg    db    'loc'
  195. remmsg    db    'rem'
  196. portno    db    0
  197.  
  198. ; storage for multi-window stuff
  199. swidth    equ    80            ; max screen width
  200. slen    equ    24            ; and length of text
  201. crt_norm db    3            ; video mode for normal screen
  202. crt_mode db    3            ; video mode (typ 3, must be text)
  203. crt_cols db    80            ; number of screen columns (typ 80)
  204. crt_lins db    24            ; number of screen rows - 1 (typ 24)
  205. low_rgt    dw    174fh            ; lower right corner of text window
  206.                     ; high = row address (typ 23)
  207.                     ; low = column address (typ 79)
  208. inipara    dw    0            ; initial paragraphs of scroll memory
  209. refresh    db    0            ; screen refresh (0=wait for retrace)
  210. vtroll    db    0            ; auto roll back allowed (0 = no)
  211.  
  212. vtrname    db    'TERMINALR'        ; a macro name, must be Upper Case
  213. vtrlen    equ    $-vtrname
  214. vtsname    db    'TERMINALS'        ; a macro name, must be Upper Case
  215. vtslen    equ    $-vtsname
  216.  
  217. vtmacname dw    vtrname            ; pointer to selected macro name
  218. vtmaclen db    vtrlen
  219. udkseg    dw    18 dup (0)        ; segment of user definable key defs
  220.     even                ; screen rollback material
  221. iniseg    dw    ?            ; (BDT) initial seg of scroll memory
  222. ppl    dw    0            ; (BDT) paragraphs per line
  223. lcnt    dw    0            ; (BDT) number of "filled" buffer lines
  224. linef    dw    0            ; (BDT) "first" filled line is here
  225. linec    dw    0            ; (BDT) "current" screen line number
  226. linee    dw    0            ; (BDT) total # of lines in the buffer
  227. lmax    dw    0            ; (BDT) max lines in buff (less 1 scrn)
  228. lxtra    dw    0            ; (BDT) "extra" lines rqd for screen
  229.  
  230.  
  231.                     ; begin Terminal emulator data set
  232. termtb    db    tttypes            ; entries for Status, not Set
  233.     mkeyw    'Heath-19',ttheath
  234.     mkeyw    'none',ttgenrc
  235.     mkeyw    'Tek4010',tttek
  236.     mkeyw    'VT320',ttvt320
  237.     mkeyw    'VT102',ttvt100        
  238.     mkeyw    'VT52',ttvt52
  239.  
  240. vttbl    db    23            ; number of entries
  241.     mkeyw    'Bell',8800h        ; note 8800 flag for decoding
  242.     mkeyw    'Character-set',chaval+8300h
  243.     mkeyw    'Clear-screen',8500h    ; 8500h = marker here
  244.     mkeyw    'Color',8200H        ; screen fore/back colors; 200H=marker
  245.     mkeyw    'Controls',cntlval
  246.     mkeyw    'Cursor-style',curval
  247.     mkeyw    'Direction',dirval
  248.     mkeyw    'Graphics',8600h    ; Tek graphics board, 800h=marker
  249.     mkeyw    'Heath-19',ttheath+8100H; note 8100H flag for decoding here
  250.     mkeyw    'Keyclick',keyval
  251.     mkeyw    'Keypad',kpamval
  252.     mkeyw    'Margin-bell',marval
  253.     mkeyw    'None',ttgenrc+8100H
  254.     mkeyw    'Newline',newval
  255.     mkeyw    'Replay',8700h        ; note 8700H flag for file replaying
  256.     mkeyw    'Rollback',8400h    ; note 8400H flag for decoding
  257.     mkeyw    'Screen-background',scrval
  258.     mkeyw    'Tabstops',tabval
  259.     mkeyw    'Tek4010',tttek+8100H
  260.     mkeyw    'VT320',ttvt320+8100H
  261.     mkeyw    'VT102',ttvt100+8100H
  262.     mkeyw    'VT52',ttvt52+8100H
  263.     mkeyw    'Wrap',wraval
  264.  
  265. ontab    db    2            ; two entries
  266.     mkeyw    'off',0
  267.     mkeyw    'on',1
  268.  
  269. beltab    db    2            ; bell type
  270.     mkeyw    'audible',0
  271.     mkeyw    'visual',1
  272.  
  273. scrtab    db    2            ; screen attributes
  274.     mkeyw    'normal',0
  275.     mkeyw    'reverse',1
  276.  
  277. dirtab    db    2            ; writing direction
  278.     mkeyw    'left-to-right',0
  279.     mkeyw    'right-to-left',1
  280.  
  281. curtab    db    2            ; cursor attributes
  282.     mkeyw    'block',0
  283.     mkeyw    'underline',1
  284.      
  285. chatab    db    17            ; National Replacement Character sets
  286.     mkeyw    'ASCII',0        ; ASCII is default (0, no NRC)
  287.     mkeyw    'British',1        ; start NRC set (1-12)
  288.     mkeyw    'Dutch',2
  289.     mkeyw    'Finnish',3
  290.     mkeyw    'French',4
  291.     mkeyw    'Fr-Canadian',5
  292.     mkeyw    'German',6
  293.     mkeyw    'Italian',7
  294.     mkeyw    'Norwegian/Danish',8
  295.     mkeyw    'Portuguese',9
  296.     mkeyw    'Spanish',10
  297.     mkeyw    'Swedish',11
  298.     mkeyw    'Swiss',12        ; end of NRC proper
  299.     mkeyw    'Alternate-ROM',13    ; Alternate-ROM character set
  300.     mkeyw    'Transparent',14    ; use native display adapter hardware
  301.     mkeyw    'Latin-1',15        ; Latin-1 in GR
  302.     mkeyw    'DEC-MCS',16        ; DEC Supplemental Graphics in GR
  303.  
  304. graftab    db    10
  305.     mkeyw    'auto-sensing',0    ; autosensing
  306.     mkeyw    'CGA',1
  307.     mkeyw    'EGA',2
  308.     mkeyw    'VGA',3
  309.     mkeyw    'Hercules',4
  310.     mkeyw    'ATT',5
  311.     mkeyw    'WyseA(1280x800)',6    ; Wyse-700 1280 x 800 mode
  312.     mkeyw    'WyseH(1280x780)',7    ; Wyse-700 1280 x 780 mode
  313.     mkeyw    'WyseT(1024x780)',8    ; Wyse-700 1024 x 780 mode
  314.     mkeyw    'character-writing',101h
  315.  
  316. gchrtab    db    2            ; set term graphics char-writing
  317.     mkeyw    'opaque',1
  318.     mkeyw    'transparent',0
  319.  
  320. disatab    db    2            ; Tek disable/enable table
  321.     mkeyw    'disable',1
  322.     mkeyw    'enable',0
  323.  
  324. tabtab    db    2            ; label says it all!
  325.     mkeyw    'at',0FFH        ; For setting tab stops
  326.     mkeyw    'Clear',0        ; For clearing tab stops
  327.      
  328. alltab    db    2            ; more tab command decoding
  329.     mkeyw    'all',0
  330.     mkeyw    'at',1
  331.  
  332. cntltab    db    2            ; 8-bit controls
  333.     mkeyw    '7-bit',0
  334.     mkeyw    '8-bit',1
  335.  
  336. kpamtab    db    2            ; keypad, application
  337.     mkeyw    'Numeric',0
  338.     mkeyw    'Application',1
  339.  
  340. vtable    dw    ontab, ontab, chatab, dirtab ,ontab, ontab, curtab, scrtab
  341.     dw    cntltab, kpamtab, 0
  342. ; which are     newline  wrap   char   direct  key   margin  cursor  screen  
  343. ;        controls key-app
  344.  
  345. vtsflg equ    this word        ; define small digits xxxval
  346. newval    equ    $-vtsflg        ; 0   and mask for bit in byte
  347.     dw    vsnewline        ;  1
  348. wraval    equ    $-vtsflg        ; 2
  349.     dw    vswrap            ;  2
  350. chaval    equ    $-vtsflg        ; 4
  351.     dw    vsnrcm            ;  4
  352. dirval    equ    $-vtsflg        ; 6
  353.     dw    vswdir            ;  8
  354. keyval    equ    $-vtsflg        ; 8
  355.     dw    vskeyclick        ;  10h
  356. marval    equ    $-vtsflg        ; 10
  357.     dw    vsmarginbell        ;  20h
  358. curval    equ    $-vtsflg        ; 12
  359.     dw    vscursor        ;  40h
  360. scrval    equ    $-vtsflg        ; 14
  361.     dw    vsscreen        ;  80h
  362. cntlval    equ    $-vtsflg        ; 16
  363.     dw    vscntl            ;  100h
  364. kpamval    equ    $-vtsflg        ; 18
  365.     dw    deckpam            ;  400h
  366. numflgs equ    ($-vtsflg)/2        ;  10
  367. tabval    equ    $-vtsflg        ; 20
  368.     dw    0
  369. vtrtns    dw    numflgs dup (flgset), tabmod ; dispatch table for vtsflg
  370.  
  371. colortb    db    0,4,2,6,1,5,3,7        ; color reversed-bit setting bytes
  372. clrset    db    ?            ; Temp for SET Term Tabstops xxx
  373.  
  374. erms41    db    cr,lf,'?More parameters are needed$'
  375. vthlp    db    ' one of the following:',cr,lf
  376.     db '  terminal types of: None, Heath-19, VT52, VT102, VT320,'
  377.     db    ' or Tek4010',cr,lf
  378.     db '  Newline-mode    Cursor-style        Character-set'
  379.     db     cr,lf
  380.     db '  Keyclick        Margin-bell         Screen-background'
  381.     db    ' (normal, reverse)',cr,lf
  382.     db '  Tabstops        Wrap (long lines)   Color (fore & background)'
  383.     db    cr,lf,'  Bell  audible or visual'
  384.     db    cr,lf,'  Clear-screen  (clears old startup screen)'
  385.     db    cr,lf,'  Controls 7-bit or 8-bit  (permits VT320 to use'
  386.     db    ' 8-bit control sequences (C1))'
  387.     db    cr,lf,'  Direction Left-to-right or Right-to-left'
  388.     db    ' (screen writing direction)'
  389.     db    cr,lf,'  Graphics  (type of display adapter when in Tek4010'
  390.     db    ' mode)'
  391.     db    cr,lf,'  Keypad numeric (normal) or application mode'
  392.     db     cr,lf,'  Replay filespec (display a file through the emulator)'
  393.     db    cr,lf,'  Rollback  (undo screen roll back before writing new'
  394.     db    ' chars, default=off)'
  395.     db    cr,lf,'  TEK ENABLE or DISABLE (activation by host command)$'
  396. clrhlp    db    ' one of the following:'
  397.     db    cr,lf,'  AT #s  (to set tabs at column #s)    or'
  398.     db    ' AT start-column:spacing'
  399.     db    cr,lf,'  Clear AT #s (clears individual tabs) or'
  400.     db    ' AT start-column:spacing'
  401.     db    cr,lf,'  Clear ALL  (to clear all tabstops)'
  402.     db    cr,lf,'  Ex: Set term tab at 10, 20, 34        sets tabs'
  403.     db    cr,lf,'  Ex: Set term tab at 1:8        sets tabs at 1, 9,'
  404.     db    cr,lf,'  Ex: Set term tab clear at 9, 17, 65   clears tabs'
  405.     db    cr,lf,'  Ex: Set term tab clear at 1:8  clears tabs at 1, 9,'
  406.     db    ' 17,...$'
  407. tbserr    db    cr,lf,'?Column number is not in range 1 to screen width-1$'
  408. colhlp    db    cr,lf,'  Set Term Color  value, value, value, ...'
  409.     db    cr,lf,'   0 no-snow mode on an IBM CGA and white on black'
  410.     db    cr,lf,'   1 for high intensity foreground'
  411.     db    cr,lf,'  10 for fast CGA screen updating (may cause snow)'
  412.     db    cr,lf,'  Foreground color (30-37) = 30 + sum of colors'
  413.     db    cr,lf,'  Background color (40-47) = 40 + sum of colors'
  414.     db    cr,lf,'    where colors are  1 = red, 2 = green, 4 = blue'
  415.     db    cr,lf,'  Ex: 0, 1, 37, 44   IBM CGA(0), bright(1) white(37)'
  416.     db    ' chars on a blue(44) field'
  417.     db    cr,lf,'  Attributes are applied in order of appearance.$'
  418. colerr    db    cr,lf,'?Value not in range of 0, 1, 10, 30-37, or 40-47$'
  419. vtwrap    db    'Term wrap-lines: $'
  420. vtbellm    db    'Term margin-bell: $'
  421. vtnewln db    'Term newline: $'
  422. vtcur    db    'Term cursor-style: $'
  423. vtcset    db    'Term character-set: $'
  424. vtclik    db    'Term key-click: $'
  425. vtscrn    db    'Term screen-background: $'
  426. colst1    db    'Term color  foregnd:3$'
  427. colst2    db    ' backgnd:4$'
  428. vtgraf    db    'Term graphics: $'
  429. vtrolst    db    'Term rollback: $'
  430. vtdir    db    'Term direction: $'
  431. vtcntst    db    'Term controls: $'
  432. vtkpst    db    'Term keypad: $'
  433. vtbset    db    'Term bell: $'
  434. vtgchst    db    'Term graph char: $'
  435.                         ; terminal emulator
  436. vtstbl    stent    <srchkw,vtcset,chatab,vtemu.vtchset>        ; char set
  437.     stent    <srchkb,vtclik,ontab,vskeyclick,vtemu.vtflgop>    ; keyclick
  438.     stent    <colstat>                    ; colors
  439.     stent    <srchkb,vtwrap,ontab,vswrap,vtemu.vtflgop>    ; line wrap
  440.     stent    <srchkb,vtcntst,cntltab,vscntl,vtemu.vtflgop>    ; controls
  441.     stent    <srchkb,vtbellm,ontab,vsmarginbell,vtemu.vtflgop>;margin bell
  442.     stent    <srchkb,vtcur,curtab,vscursor,vtemu.vtflgop>    ; cursor type
  443.     stent    <srchkw,vtbset,beltab,belltype>            ; bell
  444.     stent    <srchkb,vtdir,dirtab,vswdir,vtemu.vtflgop>    ; write direct
  445.     stent    <srchkb,vtnewln,ontab,vsnewline,vtemu.vtflgop>    ; newline
  446.     stent    <srchkw,vtgraf,graftab,tekgraf>            ; graphics
  447.     stent    <srchkw,vtrolst,ontab,vtroll>            ; rollback
  448.     stent    <srchkw,vtgchst,gchrtab,chcontrol>        ; chr cntrl
  449.     stent    <srchkb,vtkpst,kpamtab,deckpam,vtemu.vtflgop>    ; keypad
  450.     stent    <srchkb,vtscrn,scrtab,vsscreen,vtemu.vtflgop>    ; screen 
  451.     stent    <tabstat>    ; VT320 tab status - needs one whole line
  452.     dw    0        ; end of table
  453.                         ; end of Terminal data set
  454. data    ends
  455.  
  456. code2    segment    public    'code2'
  457.     extrn   tekini:far,tekemu:far,tekend:far,tekrint:far ;in msgibm
  458. code2    ends
  459.  
  460. code    segment    public 'code'
  461.     extrn    prtchr:near, outchr:near, sbrk:near, pcwait:near
  462.     extrn    isfile:near                ; in mssfil
  463.     extrn    anstty:near,ansini:near,ansrei:near    ; in mszibm
  464.     extrn    anskbi:near,ansdsl:near            ; in mszibm
  465.     extrn    ans52t:near, vsinit:near        ; in mszibm
  466.     extrn    msuinit:near, keybd:near, kbhold:near    ; in msuibm
  467.     extrn    clrmod:near, putmod:near
  468.     extrn    telnet:near, tabset:near, tabclr:near, istabs:near
  469.     extrn    atoi:near, strlen:near, srchkb:near, srchkw:near
  470.     extrn    prompt:near, comnd:near, statc:near, replay:near
  471.     extrn    crun:near, serini:near, spath:near, strcpy:near, tekdmp:near
  472.  
  473.     assume    cs:code, ds:data, es:nothing
  474.  
  475. ; do initialization local to this module
  476. ; Dynamically allocates 4000 bytes for screen save/restore buffer plus
  477. ;  320 to 38400 bytes for screen scroll back buffers. Tries to leave space
  478. ;  for Command.com before enlarging buffers. [jrd]
  479. lclyini    proc    near
  480.     call    msuinit            ; initialize keyboard module msuxxx
  481.     mov    ah,conout        ; write a space to determine
  482.     mov    dl,' '            ; DOS's default cursor coloring
  483.     int    dos
  484.     call    getpos            ; get current cursor position into dx
  485.     mov    lincur,cx        ; save cursor type (scan line #'s)
  486.     dec    dl            ; backup to last char
  487.     or    dl,dl
  488.     jns    lclyin5            ; ns = no problem
  489.     xor    dl,dl            ; else set cursor back to left margin
  490. lclyin5:call    setpos            ; set cursor position
  491.     call    getatch            ; read current attributes into AH
  492.     mov    scbattr,ah        ; save video attributes
  493.     mov    dosattr,ah        ; and here too
  494.     and    ah,att_intensity    ; select intensity bit
  495.     mov    userbold,ah        ; save bit for user Bold control
  496.     mov    ega_mode,0        ; assume no EGA
  497.     mov    ax,1200H        ; EGA: Bios alternate select
  498.     mov    bl,10H            ; Ask for EGA info
  499.     mov    bh,0ffH            ; Bad info, for testing
  500.     mov    cl,0fH            ; Reserved switch settings
  501.     int    screen            ; EGA, are you there?
  502.     cmp    cl,0cH            ; Test reserved switch settings
  503.     jge    lclyin1            ; ge = no EGA in use
  504.     push    es
  505.     mov    ax,40h            ; check Bios 40:87h for ega being
  506.     mov    es,ax            ;  the active display adapter
  507.     test    byte ptr es:[87h],8    ; is ega active?
  508.     pop    es
  509.     jnz    lclyin1            ; nz = no
  510.     mov    ega_mode,1        ; yes, set flag to say so
  511.     mov    crt_norm,3        ; assume color monitor is attached
  512.     cmp    bh,0            ; is color mode in effect?
  513.     je    lclyin1            ; e = yes
  514.     mov    crt_norm,7        ; else use mode 7 for mono
  515. lclyin1:call    scrseg            ; test running in an Environment
  516.     call    scrmod            ; read video state, get crt_mode
  517.     mov    ax,low_rgt        ; lower right corner of screen
  518.     mov    al,crt_mode
  519.     mov    crt_norm,al        ; save as normal mode
  520.     mov    savflg,ax
  521.                     ; screen roll back buffers
  522.     mov    al,crt_lins        ; physical length of user area
  523.     mul    crt_cols        ; physical width
  524.     add    ax,7            ; round up
  525.     mov    cl,3
  526.     shr    ax,cl            ; bytes/screen to paragraphs/screen
  527.     mov    si,ax            ; save a copy in si
  528.     mov    bx,npages        ; number of roll back screens wanted
  529.     inc    bx            ; include current screen in count
  530.     mul    bx            ; total number of screens wanted
  531.     mov    cx,ax            ; save total wanted paragraphs in cx
  532.     mov    bx,0ffffh        ; ask for all of memory, to get size
  533.     mov    ah,alloc        ; allocate all of memory (must fail)
  534.     int    dos            ; bx has # free paragraphs
  535.     mov    ax,bx            ; ax has copy of number free paragraphs
  536.     sub    bx,26000D/16        ; space for Command.com copy #2
  537.     jc    lclyin2            ; c = not enough for it
  538.     cmp    bx,si            ; minimum roll back space left over?
  539.     jle    lclyin2            ; le = not even that much
  540.     cmp    bx,cx            ; got vs wanted paras for roll back
  541.     jle    lclyin3            ; le = enough but not more than needed
  542.     mov    bx,cx            ; limit to our actual needs
  543.     jmp    short lclyin3        ; ask for all we really want
  544. lclyin2:xor    bx,bx            ; use no space at all
  545.     mov    cx,bx            ; remember this new request
  546. lclyin3:mov    ah,alloc
  547.     int    dos
  548.     mov    iniseg,ax        ; (BDT) memory segment, window area
  549.     mov    inipara,bx        ; save for later resizing of buffers
  550.     cmp    cx,bx            ; paragraphs wanted vs delivered
  551.     jae    lclyin4            ; ae = enough
  552.     mov    ah,prstr
  553.     mov    dx,offset memerr    ; say not enough memory to operate
  554.     int    dos
  555.     mov    flags.extflg,1        ; set Kermit exit flag
  556. lclyin4:call    bufadj             ; set roll back buffer parameters
  557.     call    vsinit            ; init terminal emulator module MSZ
  558.     mov    bx,vtemu.att_ptr    ; attributes pointer
  559.     mov    ah,dosattr        ; startup video attributes
  560.     and    ah,not att_intensity    ; emulation intensity to normal
  561.     or    ah,userbold
  562.     mov    [bx],ah            ; set initial emulation attributes
  563.     ret
  564. lclyini    endp
  565.  
  566. ; Determine screen roll back buffer parameters depending on current screen
  567. ; dimensions and available memory. Each rollback screen line has its own
  568. ; segment (lines start on segment boundaries for rollback).
  569.  
  570. bufadj    proc    near
  571.     push    bx
  572.     push    cx
  573.     push    dx
  574.     mov    lxtra,0            ; assume no storage for "extra" lines
  575.     xor    bh,bh            ; (BDT) get bytes / line
  576.     mov    bl,crt_cols        ; (BDT) physical line width
  577.     add    bx,7            ; (BDT) round up to paragraph boundary
  578.     mov    cl,3            ; (BDT) now convert to
  579.     shr    bx,cl            ; (BDT) paragraphs / line
  580.     mov    ppl,bx            ; (BDT) save this in buffer area
  581.     mov    ax,inipara        ; (BDT) compute the number of lines
  582.     xor    dx,dx
  583.     div    bx            ; (BDT)  in the buffer
  584.     mov    lmax,ax            ; max line capacity of the buffer
  585.     mov    linee,ax        ; (BDT) save as number of total lines
  586.     or    ax,ax            ; is this zero?
  587.     je    bufadj1            ; e = yes, no space at all
  588.     xor    bh,bh            ; (BDT) get lines / screen
  589.     mov    bl,byte ptr low_rgt+1    ; (BDT) rows on user/host screen
  590.     inc    bx            ; (BDT) adjust for counting from 0
  591.     mov    lxtra,bx        ; (BDT) save as "extra" lines
  592.     sub    lmax,bx            ; (BDT) deduct "extra" lines req'd
  593.     cmp    lmax,0            ; down to no rollback space?
  594.     jg    bufadj1            ; g = no, have some
  595.     mov    lmax,0            ; say none
  596.     mov    lxtra,0            ; say none of these too
  597. bufadj1:mov     lcnt,0                  ; (BDT) # of lines filled in buffer
  598.     mov    linef,0            ; (BDT) first filled in line
  599.     mov    linec,0            ; (BDT) last  filled in line
  600.     pop    dx
  601.     pop    cx
  602.     pop    bx
  603.     ret
  604. bufadj    endp
  605.  
  606.  
  607.                     ; begin Terminal set & status code
  608. ; SET Term parameters, especially for use with VT100 emulator. [jrd]
  609. ; Taken from work done originally by James Harvey IUPUI.
  610. ; VTS is called only by mssset to set terminal type and characteristics.
  611. ; Enter via direct jmp. Exit rskp for success, ret for failure.
  612. VTS    proc    near            ; SET TERM whatever
  613.     mov    ah,cmkey        ; Parse another keyword
  614.     mov    bx,offset vthlp        ; Use this help
  615.     mov    dx,offset vttbl        ; Use this table
  616.     call    comnd
  617.     jnc    vset1            ; nc = success
  618.     ret                ; failure
  619. vset1:    cmp    bh,81H            ; marker for terminal type?
  620.     je    vsetu0            ; e = yes
  621.     cmp    bh,82h            ; marker for set term color?
  622.     jne    vset1a            ; ne = no
  623.     jmp    vsetu2            ; e = yes
  624. vset1a:    cmp    bh,83h            ; marker for character set?
  625.     jne    vset1f            ; ne = no
  626.     jmp    vsetu3            ; e = yes
  627. vset1f:    cmp    bh,84h            ; marker for roll back control?
  628.     jne    vset1g            ; ne = no
  629.     jmp    vsetu4            ; e = yes
  630. vset1g:    cmp    bh,85h            ; marker for clear-screen?
  631.     jne    vset1b            ; ne = no
  632.     mov    ah,cmeol        ; yes
  633.     call    comnd
  634.     jc    vset1h            ; c = failure
  635.     mov    vtclear,2        ; set trigger for emulator clear scn
  636.     clc                ; success
  637. vset1h:    ret
  638.  
  639. vset1b:    cmp    bh,86h            ; marker for graphics type?
  640.     jne    vset1c            ; ne = no
  641.     jmp    vsetu8            ; yes
  642.  
  643. vset1c:    cmp    bh,87h            ; marker for REPLAY?
  644.     jne    vset1d            ; ne = no
  645.     jmp    REPLAY            ; yes, do REPLAY
  646. vset1d:    cmp    bh,88h            ; marker for BELL?
  647.     jne    vset1e            ; ne = no
  648.     jmp    vsetu10            ; yes, do BELL setup
  649. vset1e:    jmp    vsetu1            ; ne = no, dispatch on bl
  650.  
  651. vsetu0:    mov    byte ptr temp,bl    ; set terminal type
  652.     mov    byte ptr temp+1,-1    ; assume no enable/disable Tek
  653.     cmp    bl,tttek        ; set term tek?
  654.     jne    vsetu0a            ; ne = no
  655.     mov    dx,offset disatab    ; disable/enable keyword table
  656.     mov    bx,0            ; help is the table
  657.     mov    comand.cmcr,1        ; allow bare CR's
  658.         mov    ah,cmkey        ; get enable/disable keyword
  659.     call    comnd
  660.     mov    comand.cmcr,0        ; no more bare CR's
  661.     jc    vsetu0e            ; c = no such keyword
  662.     mov    byte ptr temp+1,bl    ; save enable/disable keyword value
  663.     mov    bl,flags.vtflg        ; get current terminal type
  664.     mov    byte ptr temp,bl    ; and force it here
  665.  
  666. vsetu0a:mov    ah,cmeol
  667.     call    comnd            ; get a confirm
  668.     jc    vsetu0d            ; c = failure
  669. vsetu0e:mov    bx,temp
  670.     mov    flags.vtflg,bl        ; Set the terminal emulation type
  671.     mov    tekflg,0        ; clear Tek sub mode
  672.     cmp    bl,tttek        ; adjusting Tek?
  673.     je    vsetu0b            ; e = yes
  674.     cmp    bh,-1            ; just enable/disable tek?
  675.     je    vsetu0c            ; e = no
  676. vsetu0b:and    denyflg,not tekxflg    ; enable Tek
  677.     cmp    bh,1            ; ought we disable?
  678.     jne    vsetu0c            ; ne = no
  679.     or    denyflg,tekxflg        ; disable Tek
  680. vsetu0c:clc                ; success
  681. vsetu0d:ret
  682.  
  683.  
  684. vsetu1:    ;;;xor    bh,bh            ; remove marker bits in bh
  685.     jmp    vtrtns[bx]        ; Dispatch
  686.  
  687. vsetu3: mov    ah,cmkey        ; Set Term character set
  688.     xor    bx,bx            ; Use character set table for help 
  689.     mov    dx,offset chatab    ; Use character set table
  690.     call    comnd
  691.     jc    vsetu3a            ; c = failure
  692.     mov    temp,bx
  693.     mov    ah,cmeol        ; get a confirm
  694.     call    comnd
  695.     jc    vsetu3a            ; failure
  696.     mov    ax,temp            ; recover value
  697.     mov    vtemu.vtchset,al    ; set default character set
  698.     clc
  699. vsetu3a:ret
  700.  
  701. vsetu4:    mov    ah,cmkey        ; Set Term Roll On/Off, auto roll back
  702.     xor    bx,bx            ; Use on/off table as help
  703.     mov    dx,offset ontab        ; Use on/off table
  704.     call    comnd
  705.     jc    vsetu4a            ; c = failure
  706.     mov    temp,bx
  707.     mov    ah,cmeol        ; get a confirm
  708.     call    comnd
  709.     jc    vsetu4a            ; c = failure
  710.     mov    bx,temp
  711.     mov    vtroll,bl        ; set roll state (0=no auto rollback)
  712.     clc
  713. vsetu4a:ret
  714.  
  715.                      ; Set Term Color foreground, background
  716. vsetu2:    mov    ah,cmline        ; get number(s) after set term color
  717.     mov    dx,offset colhlp    ; use this help
  718.     mov    bx,offset rdbuf        ; temp buffer
  719.     mov    rdbuf,0            ; clear the buffer
  720.     call    comnd
  721.     jc    vsetu2b            ; c = failure
  722.     cmp    ah,0            ; text given?
  723.     jne    vsetu2a            ; ne = yes
  724.     mov    ah,prstr
  725.     mov    dx,offset erms41    ; say need more parameters
  726.     int    dos
  727.     stc                ; failure
  728.     ret
  729. vsetu2a:mov    bx,vtemu.att_ptr    ; get address of attributes byte
  730.     mov    bl,[bx]            ; get attributes
  731.     mov    byte ptr temp,bl    ; save in work temp
  732.     mov    si,offset rdbuf        ; si = place where atoi wants text
  733.     jmp    vsetu2b            ; analyze
  734.  
  735. colbad:    mov    ah,prstr        ; not in range - complain and exit
  736.     mov    dx,offset colerr
  737.     int    dos
  738.     stc
  739.     ret
  740.  
  741. vsetu2x:mov    al,byte ptr temp    ; get current attributes
  742.     mov    bx,vtemu.att_ptr    ; get address of attributes byte
  743.     mov    [bx],al            ; store attributes
  744.     clc                ; success
  745.     ret
  746.  
  747. vsetu2b:mov    dx,si            ; analyze values
  748.     call    strlen            ; current length of text to cx
  749.     jcxz    vsetu2x            ; z = nothing left
  750. vsetu2c:cmp    byte ptr[si],' '    ; scan off leading spaces
  751.     jne    vsetu2d            ; ne = non-blank text found
  752.     inc    si            ; look at next char
  753.     loop    vsetu2c            ; cx characters to examine
  754.     jcxz    vsetu2x            ; z = nothing left
  755. vsetu2d:mov    ah,cl            ; put length where atoi wants it
  756.     call    atoi            ; convert text to numeric in ax
  757.     jc    colbad            ; c = no value available
  758.     cmp    ax,0            ; reset all? regular IBM CGA refresh
  759.     je    vsetu2j            ; e = yes
  760.     cmp    ax,1            ; high intensity?
  761.     je    vsetu2k            ; e = yes
  762.     cmp    ax,10            ; fast refresh?
  763.     je    vsetu2l            ; e = yes
  764.     cmp    ax,30            ; check range
  765.     jb    colbad            ; b = too small. complain
  766.     cmp    ax,37
  767.     jna    vsetu2f            ; 30-37 is foreground color
  768.     cmp    ax,40
  769.     jb    colbad
  770.     cmp    ax,47            ; compare as unsigned
  771.     jna    vsetu2g            ; 40-47 is background
  772.     jmp    colbad            ; else error
  773.          
  774. vsetu2h:inc    si            ; skip separator
  775.     cmp    byte ptr[si-1],0    ; ended on null?
  776.     jne    vsetu2b            ; ne = no, do more
  777.     jmp    vsetu2x            ; e = yes, exit
  778.  
  779. vsetu2f:sub    al,30            ; remove foreground bias
  780.     and    byte ptr temp,not 07H    ; clear foreground bits
  781.     mov    bx,ax
  782.     mov    al,colortb[bx]        ; get reversed bit pattern
  783.     or    byte ptr temp,al    ; load new bits
  784.     mov    vtclear,2        ; set trigger for emulator clear scn
  785.     jmp    vsetu2h
  786.  
  787. vsetu2g:sub    al,40            ; remove background bias
  788.     and    byte ptr temp,not 70H    ; clear background bits
  789.     mov    bx,ax
  790.     mov    al,colortb[bx]        ; get reversed bit pattern
  791.     mov    cl,4            ; rotate 4 positions
  792.     rol    al,cl
  793.     or    byte ptr temp,al    ; load new bits
  794.     mov    vtclear,2        ; set trigger for emulator clear scn
  795.     jmp    vsetu2h
  796.     
  797. vsetu2j:mov    refresh,0        ; Regular (slow) screen refresh
  798.     mov    byte ptr temp,07h    ; clear all, set white on black
  799.     mov    vtclear,2        ; set trigger for emulator clear scn
  800.     jmp    vsetu2h            ; get next value
  801. vsetu2k:or    byte ptr temp,08h    ; set high intensity
  802.     mov    vtclear,1        ; set trigger for emulator keep screen
  803.     jmp    vsetu2h            ; get next value
  804. vsetu2l:mov    refresh,1        ; Fast screen refresh
  805.     jmp    vsetu2h
  806.  
  807. vsetu8:    mov    ah,cmkey        ; Set Term graphics
  808.     xor    bx,bx            ; Use graphics table as help
  809.     mov    dx,offset graftab    ; Use graphics table
  810.     call    comnd
  811.     jc    vsetu8a            ; c = failure
  812.     mov    temp,bx
  813.     cmp    bx,100h            ; in the special options area?
  814.     ja    vsetu8b            ; a = yes
  815.     mov    ah,cmeol        ; get a confirm
  816.     call    comnd
  817.     jc    vsetu8a            ; c = failure
  818.     mov    bx,temp
  819.     mov    tekgraf,bl        ; set Tek graphics board type
  820.     clc
  821. vsetu8a:ret
  822. vsetu8b:mov    ah,cmkey        ; Set Term graphics char-writing
  823.     xor    bx,bx            ; no help
  824.     mov    dx,offset gchrtab    ; opaque/transparent table
  825.     call    comnd
  826.     jc    vsetu8a            ; c = failure
  827.     push    bx
  828.     mov    ah,cmeol        ; get a confirm
  829.     call    comnd
  830.     pop    bx
  831.     jc    vsetu8a
  832.     mov    chcontrol,bl        ; set/reset opaque char control
  833.     clc
  834.     ret
  835.     
  836. vsetu10:mov    ah,cmkey        ; SET TERM BELL
  837.     xor    bx,bx            ; use table as help
  838.     mov    dx,offset beltab    ; use Bell table
  839.     call    comnd
  840.     jc    vsetu10a        ; c = failure
  841.     mov    temp,bx
  842.     mov    ah,cmeol        ; get a confirm
  843.     call    comnd
  844.     jc    vsetu10a        ; c = failure
  845.     mov    bx,temp
  846.     mov    belltype,bl        ; set bell type
  847. vsetu10a:ret                ; return carry clear or set
  848.  
  849. ; SET Term flags. These are the (near) equivalent of VT100 Setup mode values.
  850.      
  851. flgset:    push    bx            ; save index (newval etc)
  852.     mov    ah,cmkey        ; Another keyword
  853.     mov    dx,vtable[bx]        ; The table to use
  854.     xor    bx,bx            ; Use default help
  855.     call    comnd
  856.     mov    temp,bx            ; save switch value
  857.     pop    bx            ; recover index
  858.     jc    flgse0            ; c = failure
  859.     push    bx
  860.     mov    ah,cmeol        ; get confirm
  861.     call    comnd
  862.     pop    bx
  863.     jc    flgse0            ; c = failure
  864.     mov    dx,temp            ; Restore switch value
  865.     mov    ax,vtsflg[bx]        ; get the flag
  866.     or    dx,dx            ; set or clear?
  867.     je    flgse1            ; e = clear it
  868.     or    vtemu.vtflgst,ax    ; set the flag
  869.     or    vtemu.vtflgop,ax    ; in runtime flags too
  870.     clc                ; success
  871. flgse0:    ret     
  872. flgse1: not    ax            ; Complement
  873.     and    vtemu.vtflgst,ax    ; clear the indicated setup flag
  874.     and    vtemu.vtflgop,ax    ; clear the indicated runtime flag
  875.     clc                ; success
  876.     ret
  877.      
  878. ;    SET Term Tabstops Clear ALL
  879. ;    SET Term Tabstops Clear AT n1, n2, ..., nx
  880. ;    SET Term Tabstops At n1, n2, ..., nx
  881.      
  882. tabmod:    mov    ah,cmkey        ; parse keyword
  883.     mov    bx,offset clrhlp    ; help text
  884.     mov    dx,offset tabtab    ; table
  885.     call    comnd
  886.     jc    tabmo2            ; c = failure
  887.     mov    clrset,2        ; 2 = code for set a tab
  888.     cmp    bl,0            ; clear?
  889.     jne    tabmo3            ; ne = no, SET. parse column number(s)
  890.     mov    clrset,1        ; code for clear at/all tab(s)
  891.     mov    ah,cmkey        ; CLEAR, parse ALL or AT
  892.     mov    bx,offset clrhlp    ; help text
  893.     mov    dx,offset alltab    ; parse ALL or AT
  894.     call    comnd
  895.     jc    tabmo2            ; c = failure
  896.     cmp    bx,0            ; ALL?
  897.     jne    tabmo3            ; ne = AT, clear at specific places
  898.     mov    ah,cmeol        ; confirm the ALL
  899.     call    comnd
  900.     jc    tabmo2            ; c = failure
  901.     mov    cx,132            ; ALL, means clear all tab stops
  902. tabmo1:    mov    dx,cx
  903.     dec    dl            ; column number, starting with 0
  904.     push    si
  905.     mov    si,vtemu.vttbs        ; the cold-start buffer
  906.     call    tabclr            ; clear the tab
  907.     pop    si
  908.     loop    tabmo1            ; do all columns
  909.     jmp    tabcpy            ; update active tabs
  910. tabmo2:    ret
  911.  
  912. tabmo3:    mov    dx,offset clrhlp    ; tell them we want a column number
  913.     mov    ah,cmline        ; get line of text
  914.     mov    bx,offset rdbuf        ; temp buffer
  915.     call    comnd
  916.     jc    tabmo2            ; c = failure
  917.     cmp    ah,0            ; anything given?
  918.     jne    tabmo4            ; ne = yes
  919.     mov    ah,prstr
  920.     mov    dx,offset erms41    ; say need more parameters
  921.     int    dos
  922.     clc
  923.     ret
  924. tabmo4:    mov    si,offset rdbuf        ; si = place where atoi wants text
  925. tabmo5:    mov    dx,si
  926.     call    strlen            ; cx = current length of text
  927.     jcxz    tabcpy            ; z = nothing left
  928.     mov    ah,cl            ; put length where atoi wants it
  929.     call    atoi            ; convert text to numeric in ax
  930.     jc    tabcpy            ; c = no number available
  931.     mov    dx,ax            ; column (1-132 style)
  932.     dec    dx            ; put column in range 0-131
  933.     cmp    dx,0            ; check range (1-132 --> 0-131)
  934.     jl    tbsbad            ; l = too small. complain
  935.     cmp    dl,132-1        ; more than the right most column?
  936.     jna    tabmo6            ; na = no, is ok
  937. tbsbad:    mov    ah,prstr        ; not in range - complain and exit
  938.     mov    dx,offset tbserr
  939.     int    dos
  940.     jmp    short tabmo5        ; get next command value
  941.      
  942. tabmo6:    cmp    byte ptr [si],':'    ; "start-column:spacing" notation?
  943.     jne    tabmo9            ; ne = no, do individual tabstops
  944.     inc    si            ; skip colon, do start:space analysis
  945.     mov    temp,dx            ; save reg around atoi call
  946.     mov    dx,si            ; string address for strlen
  947.     call    strlen            ; get remaining string length into cx
  948.     jcxz    tabcpy            ; z = no space value, all done here
  949.     mov    ah,cl            ; ah = string length for atoi
  950.     call    atoi            ; get space value into ax
  951.     jc    tabcpy            ; c = no number available
  952.     mov    dx,temp
  953.     mov    cx,ax            ; "space" value
  954.     cmp    cx,0            ; zero spacing?
  955.     jne    tabmo7            ; ne = no
  956.     inc    cx            ; don't get caught with zero spacing
  957. tabmo7:    cmp    dx,132-1        ; largest tab stop
  958.     ja    tabcpy            ; a = done largest tab stop
  959.     push    si
  960.     mov    si,vtemu.vttbs        ; the cold-start buffer
  961.     cmp    clrset,2        ; set?
  962.     jne    tabmo8            ; ne = no, clear
  963.     call    tabset            ; set tabstop in column DL
  964.     jmp    short tabmo8a
  965. tabmo8:    call    tabclr            ; clear tabstop in column DL
  966. tabmo8a:pop    si
  967.     add    dx,cx            ; new column value
  968.     jmp    short tabmo7        ; finish spacing loop
  969.                     ; individual tabstops
  970. tabmo9:    push    si
  971.     mov    si,vtemu.vttbs        ; the cold-start buffer
  972.     cmp    clrset,2        ; set?
  973.     jne    tabmo10            ; ne = no, clear
  974.     call    tabset            ; set tabstop in column DL
  975.     pop    si
  976.     jmp    short tabmo5        ; get next command value
  977. tabmo10:call    tabclr            ; clear tabstop in column DL
  978.     pop    si
  979.     jmp    tabmo5            ; get next command value
  980.  
  981. tabcpy: mov    cx,(132+7)/8        ; update all active tab stops
  982.     mov    di,vtemu.vttbst        ; in terminal emulator's active buffer
  983.     mov    si,vtemu.vttbs        ; from the cold-start buffer
  984.     push    es
  985.     push    ds
  986.     pop    es
  987.     cld
  988.     rep    movsb
  989.     pop    es
  990.     clc                ; success
  991.     ret
  992. VTS    endp                ; end of Set Term things
  993.  
  994.           ; Terminal Status display, called within STAT0: in MSSSET
  995. VTSTAT    proc    near            ; enter with di within sttbuf, save bx
  996.     mov    bx,offset vtstbl    ; table of things to show
  997.     jmp    statc            ; status common code, in mssset
  998.  
  999. colstat    proc    near            ; foreground/background color status
  1000.     push    si
  1001.     mov    si,offset colst1
  1002.     cld
  1003. colstd1:lodsb
  1004.     cmp    al,'$'            ; end of string?
  1005.     je    colstd2            ; e = yes
  1006.     stosb
  1007.     jmp    short colstd1
  1008. colstd2:mov    bx,vtemu.att_ptr    ; pointer to attributes byte
  1009.     mov    bl,byte ptr[bx]
  1010.     xor    bh,bh
  1011.     push    bx
  1012.     and    bx,7            ; get foreground set
  1013.     mov    al,colortb[bx]        ; get reversed bit pattern
  1014.     add    al,'0'            ; add ascii bias
  1015.     stosb
  1016.     pop    bx
  1017.     mov    si,offset colst2
  1018. colstd3:lodsb
  1019.     cmp    al,'$'
  1020.     je    colstd4
  1021.     stosb
  1022.     jmp    short colstd3
  1023. colstd4:mov    cl,4            ; rotate 4 positions
  1024.     shr    bl,cl
  1025.     and    bx,7            ; get background set
  1026.     mov    al,colortb[bx]        ; get reversed bit pattern
  1027.     add    al,'0'            ; add ascii bias
  1028.     stosb
  1029.     pop    si
  1030.     ret    
  1031. colstat    endp
  1032.                     ; Tabs Status display
  1033. tabstat    proc    near            ; display tabs ruler for Status
  1034.     push    dx
  1035.     cld
  1036.     mov    al,cr
  1037.     stosb
  1038.     cmp    cl,10            ; are we on a new line?
  1039.     jb    tabsta0            ; b = no, do a lf now
  1040.     mov    al,lf
  1041.     stosb
  1042. tabsta0:xor    cl,cl            ; column index
  1043.     xor    ax,ax            ; ah = tens, al = units counter
  1044. tabsta1:mov    dl,'.'            ; default position symbol
  1045.     inc    al
  1046.     cmp    al,10            ; time to roll over?
  1047.     jb    tabsta2            ; b = not yet
  1048.     xor    al,al            ; modulo 10
  1049.     inc    ah
  1050.     mov    dl,ah            ; display a tens-digit
  1051.     add    dl,'0'
  1052.     cmp    dl,'9'            ; larger than 90?
  1053.     jbe    tabsta2            ; be = no
  1054.     sub    dl,10            ; roll over to 0, 1, etc
  1055. tabsta2:push    dx
  1056.     push    si
  1057.     mov    dl,cl            ; column number, counted from 0
  1058.     mov    si,vtemu.vttbst        ; the active buffer
  1059.     call    istabs            ; is tab set here?
  1060.     pop    si
  1061.     pop    dx
  1062.     jnc    tabsta3            ; nc = no
  1063.     mov    dl,'T'            ; yes, display a 'T'
  1064. tabsta3:push    ax
  1065.     mov    al,dl
  1066.     stosb
  1067.     pop    ax
  1068.     inc    cl
  1069.     cmp    cl,byte ptr low_rgt    ; done yet?
  1070.     jb    tabsta1            ; b = not yet
  1071.     pop    dx
  1072.     ret
  1073. tabstat    endp
  1074.  
  1075. filler    proc    near            ; use space
  1076.     mov    cx,20
  1077.     mov    al,' '
  1078.     cld
  1079.     rep    stosb
  1080.     ret
  1081. filler    endp
  1082. VTSTAT    endp                ; end of Terminal set & status code
  1083.  
  1084.  
  1085. scrini    proc    near            ; init screen stuff
  1086.     mov    ega_mode,0        ; assume no EGA
  1087.     mov    ax,1200H        ; EGA: Bios alternate select
  1088.     mov    bl,10H            ; Ask for EGA info
  1089.     mov    bh,0ffH            ; Bad info, for testing
  1090.     mov    cl,0fH            ; Reserved switch settings
  1091.     int    screen            ; EGA, are you there?
  1092.     cmp    cl,0cH            ; Test reserved switch settings
  1093.     jge    scrin1            ; ge = no EGA in use
  1094.     push    es
  1095.     mov    ax,40h            ; check Bios 40:87h for ega being
  1096.     mov    es,ax            ;  the active display adapter
  1097.     test    byte ptr es:[87h],8    ; is ega active?
  1098.     pop    es
  1099.     jnz    scrin1            ; nz = no
  1100.     mov    ega_mode,1        ; yes, set flag to say so
  1101.     mov    crt_norm,3        ; assume color monitor is attached
  1102.     cmp    bh,0            ; is color mode in effect?
  1103.     je    scrin1            ; e = yes
  1104.     mov    crt_norm,7        ; else use mode 7 for mono
  1105. scrin1:    call    scrseg            ; update screen segment tv_seg(s/o)
  1106.     call    scrmod            ; get screen mode, low_rgt
  1107.     call    getpos            ; get cursor position and type
  1108.     jcxz    scrin2            ; z = nothing there, skip this
  1109.     mov    lincur,cx        ; save cursor type (scan line #'s)
  1110. scrin2:    mov    bx,vtemu.att_ptr
  1111.     mov    ah,[bx]
  1112.     and    ah,att_intensity
  1113.     mov    userbold,ah
  1114.  
  1115.     mov    ax,low_rgt        ; present screen text size
  1116.     cmp    ax,savflg        ;  vs size of saved screen
  1117.     je    scrin3            ; e = same, do not re-initialize
  1118.                     ;
  1119.     call    bufadj            ; re-initialize screen buffers
  1120.     mov    cursor,0        ; cursor to upper left corner
  1121.     cmp    flags.vtflg,0        ; terminal type of None?
  1122.     ja    scrin3            ; a = no, emulating
  1123.     mov    dh,byte ptr low_rgt+1
  1124.     inc    dh            ; bottom
  1125.     xor    dl,dl            ;  left corner
  1126.     mov    cursor,dx        ; non-emulating cursor
  1127.                     ; Common finish code
  1128. scrin3:    mov    ah,savattr        ; saved emulator attributes
  1129.     mov    scbattr,ah        ; restore active value
  1130.     mov    dx,cursor        ; use old cursor, if any
  1131.     call    setpos            ; set cursor position
  1132.     call    restscr            ; restore screen, if any saved
  1133.     or    flags1,inited        ; remember we've run already
  1134.     cmp    flags.vtflg,0        ; current terminal type = None?
  1135.     je    scrin13            ; e = yes, nothing to init
  1136.     cmp    vtclear,2        ; screen need clearing?
  1137.     jae    scrin10            ; ae = yes, do emulator reinit now
  1138.     cmp    vtinited,inited        ; inited emulator yet?
  1139.     je    scrin11            ; e = yes
  1140. scrin10:call    vtinit            ; init it now
  1141.     jmp    short scrin13
  1142. scrin11:call    ansrei            ; reinit the emulator
  1143.     cmp    flags.vtflg,tttek    ; Tek mode?
  1144.     je    scrin12            ; e = yes
  1145.     test    tekflg,1        ; Tek mode?
  1146.     jz    scrin13            ; z = no
  1147. scrin12:call    tekini
  1148. scrin13:mov    al,flags.vtflg        ; current terminal type
  1149.     mov    trmtyp,al        ; place to remember it til next time
  1150.     mov    vtclear,0        ; say screen is updated
  1151.     ret
  1152. scrini    endp
  1153.  
  1154. ; Routine to initialize VT102/52/Heath-19 terminal emulator.
  1155.      
  1156. vtinit    proc    near
  1157.     mov    holdscr,0        ; clear holdscreen
  1158.     call    kbhold            ; tell DEC LK250 the state, in msuibm
  1159.     or    vtinited,inited
  1160.     cmp    flags.vtflg,0        ; doing emulation?
  1161.     je    vtinix            ; e = no
  1162.     cmp    flags.vtflg,tttek    ; doing full Tek mode?
  1163.     je    vtini2            ; e = yes, skip text emulator
  1164.     mov    bx,argadr        ; address of argument block
  1165.     mov    dl,[bx].flgs
  1166.     and    dl,lclecho        ; local echo flag
  1167.     and    yflags,not lclecho
  1168.     or    yflags,dl
  1169.     mov    dl,[bx].baudb        ; baud rate code in dl
  1170.     mov    dh,[bx].parity        ; parity code in bits
  1171.     mov    cl,4            ; 0-3 of dh
  1172.     shl    dh,cl
  1173.     or    dh,07H            ; just say 7 data bits
  1174.     test    flags.remflg,d8bit    ; eight bit display?
  1175.     jz    vtini1            ; z = no
  1176.     inc    dh            ; set low four bits to value 8
  1177. vtini1:    test    tekflg,1        ; Tek sub-mode active?
  1178.     jnz    vtini2            ; nz = yes, do it's reinit
  1179.     call    ansini            ; call startup routine in mszibm
  1180.     cmp    flags.vtflg,tttek    ; full Tek mode?
  1181.     je    vtini2            ; e = yes
  1182. vtinix:    clc
  1183.     ret
  1184. vtini2:    call    tekrint            ; reinitialize Tek emulator
  1185.     clc
  1186.     ret
  1187. vtinit    endp
  1188.  
  1189. argini    proc    near            ; read passed arguments
  1190.     mov    bx,argadr        ; base of argument block
  1191.     mov    al,[bx].flgs        ; get flags
  1192.     and    al,capt+emheath+trnctl+lclecho+modoff
  1193.     mov    yflags,al        ; mask for allowable and save
  1194.     mov    al,[bx].prt
  1195.     mov    portno,al        ; update port number
  1196.     mov    crt_lins,24        ; init # of rows
  1197.     mov    ax,[bx].captr
  1198.     mov    captrtn,ax        ; buffer capture routine
  1199.     mov    parmsk,0ffh        ; parity mask, assume parity = None
  1200.     cmp    [bx].parity,parnon    ; is parity None?
  1201.     je    argini1            ; e = yes, keep all 8 bits
  1202.     mov    parmsk,07fh        ; else keep lower 7 bits
  1203. argini1:ret                ; that's it
  1204. argini    endp
  1205.  
  1206. term    proc    near            ; terminal mode entry point
  1207.     mov    argadr,ax        ; save argument ptr
  1208.     call    argini            ; init options from arg address
  1209.     call    scrini            ; init screen stuff
  1210.     or    kbcodes,80h        ; set need-to-init flg for kbd xtlator
  1211.     mov    bx,portval        ; port data structure address
  1212.     mov    bx,[bx].flowc        ; get flow control chars (bl=xoff)
  1213.     mov    flowon,bh
  1214.     mov    flowoff,bl        ; save for later
  1215.     mov    oldsp,sp        ; remember stack for i/o failure,
  1216.                     ;  used by procedure  endcon
  1217.     mov    fairprn,0        ; set printer buffer flush counter
  1218. lp:    call    prtchr            ; char at port?
  1219.     jnc    short lpinp        ; nc = yes, go handle
  1220.     push    bx
  1221.     mov    bx,portval        ; port structure address
  1222.     cmp    [bx].portrdy,0        ; is port ready for business?
  1223.     pop    bx
  1224.     jne    lpkbd            ; ne = ready
  1225.     jmp    endcon            ; end the communications now
  1226. lpkbd:    mov    fairness,0        ; say kbd was examined
  1227.     inc    fairprn            ; inc printer dump counter
  1228.     cmp    fairprn,1000        ; been here enough times now?
  1229.     jb    lpkbd1            ; b = no
  1230.     call    pntflsh            ; flush printer buffer
  1231.     mov    fairprn,0        ; reset for next time
  1232. lpkbd1:    call    keybd            ; call keyboard translator in msu
  1233.     jnc    lp            ; nc = no char or have processed it
  1234.     jmp    short quit        ; carry set = quit connect mode
  1235. lpinp:    and    al,parmsk        ; apply 8/7 bit parity mask
  1236.     call    outtty            ; print on terminal
  1237.     inc    fairness        ; say read port but not kbd, again
  1238.     cmp    fairness,100        ; this many port reads before kbd?
  1239.     jb    lp            ; b = no, read port again
  1240.     jmp    short lpkbd        ; yes, let user have a chance too
  1241.  
  1242. quit:    mov    ah,scbattr        ; current emulator attributes
  1243.     mov    savattr,ah        ; save them here
  1244.     call    pntflsh            ; flush printer buffer
  1245.     call    tekend            ; cleanup Tektronix mode [bjh]
  1246.     call    getpos            ; get cursor position into dx
  1247.     mov    cursor,dx        ; save position
  1248.     mov    al,1
  1249.     call    csrtype            ; turn on underline cursor
  1250.     cmp    flags.vtflg,0        ; terminal type of none?
  1251.     je    quit1            ; e = yes
  1252.     cmp    flags.modflg,2        ; is modeline owned by remote host?
  1253.     je    quit1            ; e = yes
  1254.     call    clrmod            ; clear it before storing screen
  1255. quit1:    call    savescr            ; save screen
  1256.     mov    ah,dosattr        ; attributes at init time
  1257.     mov    scbattr,ah        ; background = original state
  1258.     call    clrmod            ; clear mode line with old attributes
  1259.                     ; for ega in non-standard # lines
  1260.     cmp    ega_mode,0        ; ega board active?
  1261.     je    quit2            ; e = no
  1262.     cmp    byte ptr low_rgt+1,23    ; is screen standard length?
  1263.     je    quit2            ; e = yes, so regular cursor set is ok
  1264.     push    es            ; turn off ega cursor emulation
  1265.     mov    ax,40h            ; byte 40:87H is ega Info byte
  1266.     mov    es,ax
  1267.     push    es:[87h]        ; save info byte around call
  1268.     or    byte ptr es:[87h],1    ; set emulation off (low bit = 1)
  1269.     mov    cx,lincur        ; cursor shape to set
  1270.     mov    ah,1            ; set the shape
  1271.     int    screen            ;   back to starting value
  1272.     pop    es:[87h]        ; recover original Info byte
  1273.     pop    es            ; and our work reg
  1274.     jmp    short quit3        ; skip regular mode cursor setting
  1275. quit2:                    ; for regular sized screen
  1276.     mov    cx,lincur        ; cursor type at startup
  1277.     mov    ah,1
  1278.     int    screen            ; restore cursor type
  1279. quit3:    mov    dh,byte ptr low_rgt+1    ; bottom line
  1280.     inc    dh            ; status line position
  1281.     xor    dl,dl            ; left most column
  1282.     call    setpos            ; set cursor position
  1283.     mov    al,yflags
  1284.     and    al,not lclecho        ; don't copy host's echo flag
  1285.     mov    bx,argadr
  1286.     mov    ah,[bx].flgs        ; get user's flag settings
  1287.     and    ah,lclecho        ; clear all but local echo bit
  1288.     or    [bx].flgs,al        ; update flags in arg block
  1289.     ret
  1290. term    endp
  1291.  
  1292. ; put the character in al to the screen
  1293. outtty    proc    near
  1294.     test    flags.remflg,d8bit    ; keep 8 bits for displays?
  1295.     jnz    outtt1            ; nz = yes, 8 bits if possible
  1296.     and    al,7fh            ; remove high bit
  1297. outtt1:    cmp    flags.vtflg,0        ; emulating a terminal?
  1298.     je    outnp10            ; e = no
  1299.     cmp    vtroll,0        ; auto roll back allowed?
  1300.     je    outem1            ; e = no, leave screen as is
  1301.     cmp    tekflg,0        ; Tek mode active?
  1302.     jne    outem1            ; ne = yes, skip screen rolling
  1303.     cmp    flags.vtflg,tttek    ; doing Tektronix emulation?
  1304.     je    outem2            ; e = yes, use Tek emulator
  1305.     push    ax            ; (BDT) save this for a tad
  1306.     mov    ax,linec        ; (BDT) are we at the buffer end?
  1307.     cmp    ax,lcnt            ; (BDT)  ...
  1308.     pop    ax            ; (BDT) restore the register
  1309.         je      outem1            ; (BDT) e = yes
  1310.     push    ax            ; (BDT) save AX again
  1311.         call    endwnd                  ; (BDT) restore screen [dlk]
  1312.     pop    ax            ; (BDT) restore the register
  1313. outem1:    cmp    flags.vtflg,tttek    ; doing Tektronix emulation?
  1314.     je    outem2            ; e = yes, use Tek emulator
  1315.     cmp    tekflg,0        ; Tek submode active for input?
  1316.     jne    outem2            ; ne = yes, use Tek emulator
  1317.     jmp    anstty            ; call terminal emulator routine & ret
  1318. outem2:    call    tekemu            ; use Tek emulator and return
  1319.     ret
  1320.                          ; use DOS for screen output
  1321. outnp10:test    flags.remflg,d8bit    ; keep 8 bits for displays?
  1322.     jnz    outnp9            ; nz = yes, 8 bits if possible
  1323.     and    al,7fh            ; remove high bit
  1324. outnp9:    cmp    rxtable+256,0        ; translation turned off?
  1325.     je    outnp7            ; e = yes, no translation
  1326.     push    bx
  1327.     mov    bx,offset rxtable    ; address of translate table
  1328.     xlatb                ; new char is in al
  1329.     pop    bx
  1330. outnp7:    test    anspflg,prtscr        ; should we be printing?
  1331.     jz    outnp8            ; no, keep going
  1332.     call    pntchr            ; queue char for printer
  1333.     jnc    outnp8            ; nc = successful print
  1334.     push    ax
  1335.     call    vtbell            ; else make a noise and
  1336.     call    trnprs            ;  turn off printing
  1337.     pop    ax
  1338. outnp8:    test    yflags,capt        ; capturing output?
  1339.     jz    outnp6            ; no, forget this part
  1340.     push    ax            ; save char
  1341.     call    captrtn            ; give it captured character
  1342.     pop    ax            ; restore character and keep going
  1343. outnp6:    test    yflags,trnctl        ; debug? if so use Bios tty mode
  1344.     jz    outnp4            ; z = no
  1345.     mov    ah,conout        ; DOS screen write
  1346.     cmp    al,7fh            ; Ascii Del char or greater?
  1347.     jb    outnp1            ; b = no
  1348.     je    outnp0            ; e = Del char
  1349.     push    ax            ; save the char
  1350.     mov    dl,7eh            ; output a tilde for 8th bit
  1351.     int    dos
  1352.     pop    ax            ; restore char
  1353.     and    al,7fh            ; strip high bit
  1354. outnp0:    cmp    al,7fh            ; is char now a DEL?
  1355.     jne    outnp1            ; ne = no
  1356.     and    al,3fH            ; strip next highest bit (Del --> '?')
  1357.     jmp    outnp2            ; send, preceded by caret
  1358. outnp1:    cmp    al,' '            ; control char?
  1359.     jae    outnp3            ; ae = no
  1360.     add    al,'A'-1        ; make visible
  1361. outnp2:    push    ax            ; save char
  1362.     mov    dl,5eh            ; caret
  1363.     int    dos            ; display it
  1364.     pop    ax            ; recover the non-printable char
  1365. outnp3:    push    ax
  1366.     mov    dl,al
  1367.     int    dos
  1368.     pop    ax
  1369.     ret
  1370. outnp4:    cmp    al,bell            ; bell (Control G)?
  1371.     jne    outnp5            ; ne = no
  1372.     jmp    vtbell            ; use short beep, avoid char loss
  1373. outnp5:    mov    dl,al            ; write without intervention
  1374.     mov    ah,conout
  1375.     int    dos            ; else let dos display char
  1376.     ret
  1377. outtty    endp
  1378.      
  1379. ;[IU2] Here to output an unsigned 8-bit number (in al) to the port without
  1380. ; echoing. Used by terminal emulator escape sequence output.
  1381.      
  1382. prtnout proc    near
  1383.     mov    bl,10            ; Output in base 10
  1384.     jmp    prtno2            ; Ensure at least a zero
  1385.      
  1386. prtno1: cmp    al,0
  1387.     jne    prtno2            ; ne = yes, do more digits
  1388.     ret                ; no, return from recursive call
  1389. prtno2: xor    ah,ah            ; clear previous remainder
  1390.     div    bl            ; divide off a digit
  1391.     push    ax            ; push remainder (in ah) on stack
  1392.     call    prtno1            ; recurse
  1393.     pop    ax            ; pop off a digit
  1394.     add    ah,'0'            ; make it ASCII
  1395.     mov    al,ah            ; send to port, in ah
  1396.     call    outprt
  1397.     jc    prtno3            ; failure, end connection
  1398.     ret
  1399. prtno3:    jmp    endcon
  1400. prtnout endp
  1401.  
  1402. ; send the character in al out to the serial port; handle echoing.
  1403. ; Can send an 8 bit char while displaying only 7 bits locally.
  1404. outprt    proc    near
  1405. prtbout    label    near            ; label used in msz
  1406.     test    yflags,lclecho        ; echoing?
  1407.     jz    outpr3            ; z = no, forget it
  1408.     push    ax            ; save char
  1409.     call    outtty            ; print it
  1410.     pop    ax            ; restore
  1411. outpr3:    mov    ah,al            ; this is where outchr expects it
  1412.     call    outchr            ; output to the port
  1413.     jc    outpr4            ; c = failure
  1414.     ret
  1415. outpr4:    jmp    endcon            ; failure, end connection
  1416. outprt    endp
  1417.  
  1418. ; Jump here to exit Connect mode and execute macros 'TERMINALR' (vtrmac) or
  1419. ; 'TERMINALS' (vtsmac). Does nothing if macro does not exist.
  1420. ; Preserves registers except ax. Returns to TELNET caller with 'C' in kbdflg.
  1421. vtrmac    proc    near            ; RESET macro
  1422.     mov    ax,offset vtrname    ; select macro name
  1423.     mov    vtmacname,ax
  1424.     mov    vtmaclen,vtrlen        ; and its length
  1425.     jmp    short vtmacro        ; finish in common code
  1426. vtrmac    endp
  1427.  
  1428. vtsmac    proc    near            ; SET macro
  1429.     mov    ax,offset vtsname
  1430.     mov    vtmacname,ax
  1431.     mov    vtmaclen,vtslen
  1432.     jmp    short vtmacro
  1433. vtsmac    endp
  1434.  
  1435. ;
  1436. ; Reference    Macro structure for    db    number of entries (mac names)
  1437. ;  is file     table mcctab       |->    db    length of macroname, excl '$'
  1438. ;  mssset.asm        each entry |->     db    'macroname','$'
  1439. ;  where these               |->    dw    segment:0 of definition string
  1440. ;  are stored.                      (offset part is always 0)    
  1441. ;        Definition string in     db    length of <string with null>
  1442. ;         buffer macbuf          db    'string with trailing null'
  1443. ;
  1444. vtmacro    proc    near            ; common code for macros vtsmac,vtrmac
  1445.     push    bx
  1446.     push    cx
  1447.     push    si
  1448.     mov    bx,offset mcctab    ; table of macro names
  1449.     mov    cl,[bx]            ; number of names in table
  1450.     xor    ch,ch
  1451.     jcxz    vtmacx            ; z = empty table, do nothing
  1452.     inc    bx            ; point to length of first name
  1453. vtmac2:    mov    al,[bx]            ; length of this name
  1454.     xor    ah,ah
  1455.     cmp    al,vtmaclen        ; length same as desired keyword?
  1456.     jne    vtmac3            ; ne = no, search again
  1457.     mov    si,bx
  1458.     inc    si            ; point at first char of name
  1459.     push    cx            ; save name counter
  1460.     push    di            ; save reg
  1461.     mov    cl,vtmaclen        ; length of name, excluding '$'
  1462.     xor    ch,ch
  1463.     mov    di,vtmacname        ; point at desired macro name
  1464.     push    es            ; save reg
  1465.     push    ds
  1466.     pop    es            ; make es use data segment
  1467.     cld
  1468.     repe    cmpsb            ; match strings
  1469.     pop    es            ; need current si below
  1470.     pop    cx
  1471.     pop    di            ; recover saved regs
  1472.     je    vtmac4            ; e = matched
  1473. vtmac3:    add    bx,ax            ; step to next name, add name length
  1474.     add    bx,4            ; + count, dollar sign, def word ptr
  1475.     loop    vtmac2            ; try next name
  1476. vtmacx:    pop    si            ; no macro, return to Connect mode
  1477.     pop    cx
  1478.     pop    bx
  1479.     ret
  1480.  
  1481. vtmac4:    cmp    taklev,maxtak        ; room in Take level?
  1482.     jge    vtmacx            ; ge = no, exit with no action
  1483.     inc    taklev            ; increment take level
  1484.     add    takadr,size takinfo    ; make a new Take entry/macro
  1485.     mov    bx,takadr        ; point to current macro structure
  1486.     inc    si            ; skip dollar sign after name
  1487.     mov    si,[si]            ; get definition address (segment)
  1488.     mov    [bx].takbuf,si        ; address of definition string struc
  1489.     push    es
  1490.     mov    es,si            ; segment of definition string struc
  1491.     xor    si,si
  1492.     mov    cl,es:[si]        ; length byte of definition
  1493.     xor    ch,ch
  1494.     mov    [bx].takcnt,cx        ; number of chars in definition
  1495.     pop    es
  1496.     inc    si            ; offset of definition text proper
  1497.     mov    [bx].takptr,si        ; where to read next command char
  1498.     mov    [bx].taktyp,0ffh    ; flag as a macro
  1499.     pop    si
  1500.     pop    cx
  1501.     pop    bx
  1502.     jmp    endcon            ; exit Connect mode
  1503. vtmacro    endp
  1504.  
  1505. ; Error recovery routine used when outchr reports unable to send character
  1506. ;  or when vtmacro requests exiting Connect mode.
  1507. ; Exit Connect mode cleanly, despite layers of intermediate calls.
  1508. endcon    proc    near
  1509.     mov    kbdflg,'C'        ; report 'C' to TERM's caller
  1510.     mov    sp,oldsp        ; recover startup stack pointer
  1511.                     ; TERM caller's return address is now
  1512.                     ; on the top of stack. A longjmp.
  1513.     jmp    quit            ; exit Connect mode cleanly
  1514. endcon    endp
  1515.  
  1516. ;;; Action routines (verbs) for keyboard translator KEYBD in msuibm.
  1517. ; These are invoked by a jump instruction. Return carry clear for normal
  1518. ; processing, return carry set for invoking Quit (kbdflg has transfer char).
  1519. uparrw:    mov    al,'A'            ; cursor keys
  1520.     jmp    short comarr
  1521. dnarrw:    mov    al,'B'
  1522.     jmp    short comarr
  1523. rtarr:    mov    al,'C'
  1524.     test    vtemu.vtflgop,vswdir    ; writing left to right?
  1525.     jz    comarr            ; z = yes
  1526.     mov    al,'D'            ; reverse sense of keys
  1527.     jmp    short comarr
  1528. lfarr:    mov    al,'D'
  1529.     test    vtemu.vtflgop,vswdir    ; writing left to right?
  1530.     jz    comarr            ; z = yes
  1531.     mov    al,'C'            ; reverse sense of keys
  1532. comarr:    push    ax            ; save final char
  1533.     mov    ttyact,0        ; network, group chars for packet
  1534.     test    vtemu.vtflgop,decanm    ; ANSI mode?
  1535.     jz    comar2            ; z = no
  1536.     mov    al,CSI            ; CSI character
  1537.     test    vtemu.vtflgop,decckm    ; cursor key mode reset?
  1538.     jz    comar1            ; z = yes
  1539.     mov    al,SS3            ; SS3 character
  1540. comar1:    call    out8bit            ; send in 7 or 8 bit form
  1541.     jmp    short comar3
  1542.  
  1543. comar2:    mov    al,escape        ; do Heath/VT52 mode "ESC char"
  1544.     call    prtbout
  1545. comar3: pop    ax            ; recover final char
  1546.     mov    ttyact,1        ; network, restore tty active flag
  1547.     call    prtbout
  1548.     ret
  1549.  
  1550. pf1:    mov    al,'P'            ; keypad function keys PF1-4
  1551.     jmp    short compf
  1552. pf2:    mov    al,'Q'
  1553.     jmp    short compf
  1554. pf3:    mov    al,'R'
  1555.     jmp    short compf
  1556. pf4:    mov    al,'S'
  1557. compf:    push    ax            ; save final char
  1558.     mov    ttyact,0        ; network, group chars for packet
  1559.     test    vtemu.vtflgop,decanm    ; ansi mode?
  1560.     jz    short compf1        ; z = no
  1561.     mov    al,SS3
  1562.     call    out8bit            ; send 7 or 8 bit version
  1563.     jmp    short compf2
  1564. compf1:    mov    al,escape        ; output ESC
  1565.     call    prtbout
  1566. compf2: pop    ax            ; get the saved char
  1567.     mov    ttyact,1        ; network, restore tty active flag
  1568.     call    prtbout
  1569.     ret
  1570.  
  1571. kp0:    mov    al,'p'            ; keypad numeric keys
  1572.     jmp    short comkp
  1573. kp1:    mov    al,'q'
  1574.     jmp    short comkp
  1575. kp2:    mov    al,'r'
  1576.     jmp    short comkp
  1577. kp3:    mov    al,'s'
  1578.     jmp    short comkp
  1579. kp4:    mov    al,'t'
  1580.     jmp    short comkp
  1581. kp5:    mov    al,'u'
  1582.     jmp    short comkp
  1583. kp6:    mov    al,'v'
  1584.     jmp    short comkp
  1585. kp7:    mov    al,'w'
  1586.     jmp    short comkp
  1587. kp8:    mov    al,'x'
  1588.     jmp    short comkp
  1589. kp9:    mov    al,'y'
  1590.     jmp    short comkp
  1591. kpminus:mov    al,'m'
  1592.     jmp    short comkp
  1593. kpcoma:    mov    al,'l'
  1594.     jmp    short comkp
  1595. kpenter:mov    al,'M'
  1596.     jmp    short comkp
  1597. kpdot:    mov    al,'n'
  1598. comkp:    test    vtemu.vtflgop,deckpam    ; keypad application mode active?
  1599.     jnz    comkp1            ; nz = yes, use escape sequences
  1600.     sub    al,40h            ; deduct offset to numeric symbols
  1601.     push    ax            ; save final char
  1602.     jmp    comkp3            ; and send that single char
  1603. comkp1:    push    ax
  1604.     mov    ttyact,0        ; network, group chars for packet
  1605.     test    vtemu.vtflgop,decanm    ; ANSI mode?
  1606.     jz    comkp2            ; z = no
  1607.     mov    al,SS3            ; SS3 character
  1608.     call    out8bit            ; send 7 or 8 bit version
  1609.     jmp    comkp3
  1610. comkp2:    mov    al,escape        ; output "ESC ?"
  1611.     call    prtbout
  1612.     mov    al,'?'
  1613.     call    prtbout
  1614. comkp3:    pop    ax            ; recover final char
  1615.     mov    ttyact,1        ; network, restore tty active flag
  1616.     call    prtbout            ; send it
  1617.     ret
  1618.  
  1619. klogon    proc    near            ; resume logging (if any)
  1620.     test    flags.capflg,logses    ; session logging enabled?
  1621.     jz    klogn            ; z = no, forget it
  1622.     or    argadr.flgs,capt    ; turn on capture flag
  1623.     or    yflags,capt        ; set local msy flag as well
  1624. klogn:    clc
  1625.     ret
  1626. klogon    endp
  1627.  
  1628. klogof    proc    near            ; suspend logging (if any)
  1629.     and    argadr.flgs,not capt    ; stop capturing
  1630.     and    yflags,not capt        ; reset local msy flag as well
  1631.     clc
  1632.     ret
  1633. klogof    endp
  1634.  
  1635. snull    proc    near            ; send a null byte
  1636.     xor    al,al            ; the null
  1637.     jmp    prtbout            ; send without logging and local echo
  1638. snull    endp
  1639.  
  1640. khold:    xor    holdscr,1        ; toggle Hold screen byte for msx
  1641.     call    kbhold            ; tell DEC LK250 the hold kbd state
  1642.     clc                ;  kbhold is in file msuibm.asm
  1643.     ret
  1644.  
  1645. ; DEC LK201 keyboard keys and "User Definable Keys" in VT3xx mode
  1646. decfind:mov    al,1            ; Find
  1647.     jmp    udkout
  1648. decinsert:mov    al,2            ; Insert
  1649.     jmp    udkout
  1650. decremove:mov    al,3            ; Remove
  1651.     jmp    udkout
  1652. decselect:mov    al,4            ; Select
  1653.     jmp    udkout
  1654. decprev:mov    al,5            ; Previous screen
  1655.     jmp    udkout
  1656. decnext:mov    al,6            ; Next screen
  1657.     jmp    udkout
  1658. decf6:    mov    al,17            ; key ident for DEC F6
  1659.     jmp    udkout            ; process it
  1660. decf7:    mov    al,18            ; key ident for DEC F7
  1661.     jmp    udkout            ; process it
  1662. decf8:    mov    al,19            ; key ident for DEC F8
  1663.     jmp    udkout            ; process it
  1664. decf9:    mov    al,20            ; key ident for DEC F9
  1665.     jmp    udkout            ; process it
  1666. decf10:    mov    al,21            ; key ident for DEC F10
  1667.     jmp    udkout            ; process it
  1668. decf11:    mov    al,23            ; key ident for DEC F11
  1669.     jmp    udkout            ; process it
  1670. decf12:    mov    al,24            ; key ident for DEC F12
  1671.     jmp    udkout            ; process it
  1672. decf13:    mov    al,25            ; key ident for DEC F13
  1673.     jmp    udkout            ; process it
  1674. decf14:    mov    al,26            ; key ident for DEC F14
  1675.     jmp    udkout            ; process it
  1676. dechelp:mov    al,28            ; key ident for DEC HELP
  1677.     jmp    udkout            ; process it
  1678. decdo:    mov    al,29            ; key ident for DEC DO
  1679.     jmp    udkout            ; process it
  1680. decf17:    mov    al,31            ; key ident for DEC F17
  1681.     jmp    udkout            ; process it
  1682. decf18:    mov    al,32            ; key ident for DEC F18
  1683.     jmp    udkout            ; process it
  1684. decf19:    mov    al,33            ; key ident for DEC F19
  1685.     jmp    udkout            ; process it
  1686. decf20:    mov    al,34            ; key ident for DEC F20
  1687.     jmp    udkout            ; process it
  1688.  
  1689. ; common worker to output contents of User Definable Key definition strings
  1690. ; Enter with al = key ident (17 - 34)
  1691. udkout    proc    near
  1692.     push    ax
  1693.     push    bx
  1694.     push    cx
  1695.     push    es
  1696.     cmp    flags.vtflg,ttvt320    ; VT320?
  1697.     je    udkout3            ; e = yes, else use VT100/VT52 default
  1698.     cmp    flags.vtflg,tttek    ; Tek?
  1699.     je    udkout3            ; try this
  1700.     cmp    al,23            ; F11 sends ESC
  1701.     jne    udkou1a            ; ne = not F11
  1702.     mov    al,escape
  1703.     call    prtbout
  1704.     jmp    udkoutx
  1705. udkou1a:cmp    al,24            ; F12 sends BS
  1706.     jne    udkou1b            ; ne = not F12
  1707.     mov    al,BS
  1708.     call    prtbout
  1709.     jmp    udkoutx
  1710. udkou1b:cmp    al,25            ; F13 sends LF
  1711.     jne    udkou1c            ; ne = not F13, ignore
  1712.     mov    al,LF
  1713.     call    prtbout
  1714. udkou1c:jmp    udkoutx
  1715.  
  1716. udkout3:mov    bl,al            ; VT3XX key ident, UDK style (17-34)
  1717.     cmp    al,6            ; is this the CSI 1-6 set?
  1718.     jbe    udkout4            ; be = yes, do separately
  1719.     sub    bl,17            ; minus starting offset of 17
  1720.     xor    bh,bh
  1721.     cmp    bl,17            ; out of range?
  1722.     ja    udkoutx            ; a = yes, ignore
  1723.     shl    bx,1            ; index words
  1724.     mov    bx,udkseg[bx]        ; segment of definition
  1725.     cmp    bx,0            ; anything there?
  1726.     je    udkout4            ; e = no, use DEC defaults below
  1727.     mov    es,bx            ; definition segment
  1728.     xor    bx,bx            ;  and offset
  1729.     mov    cl,es:[bx]        ; get string length byte
  1730.     xor    ch,ch            ; use cx as a counter
  1731.     jcxz    udkout4            ; z = empty, use defaults
  1732. udkou3a:inc    bx            ; es:bx is now the string text
  1733.     mov    al,es:[bx]        ; get a char
  1734.     push    bx
  1735.     push    cx
  1736.     push    es
  1737.     call    prtbout            ; output, no echo, no log
  1738.     pop    es
  1739.     pop    cx
  1740.     pop    bx
  1741.     loop    udkou3a
  1742.     jmp    short udkoutx        ; done
  1743.  
  1744. udkout4:push    ax            ; VT320, use default definitions
  1745.     mov    al,CSI            ; char to send
  1746.     call    out8bit            ; send lead-in char in 7/8-bit form
  1747.     pop    ax
  1748.     call    prtnout            ; key ident (17-34) as ascii digits
  1749.     mov    al,7eh            ; tilde terminator
  1750.     call    prtbout
  1751. udkoutx:pop    es
  1752.     pop    cx
  1753.     pop    bx
  1754.     pop    ax
  1755.     clc
  1756.     ret
  1757. udkout    endp
  1758.  
  1759. ; Set (define) the DEC "User Definable Keys". Inserts text definitions for
  1760. ; keyboard verbs \KdecF6 ...\KdecF14, \KdecHELP, \KdecDO, \KdecF17...\KdecF20.
  1761. ; Enter with the DCS definition string as key-number/hex-chars. UDK key number
  1762. ; is 17 for \KdecF6, et seq, the definition are pairs of hex digits converted
  1763. ; here to a single byte per pair. The DCS definition string is pointed at by
  1764. ; DS:SI, and the byte count is in CX.
  1765. ; Example:  17/54657374204636   means key \KdecF6 sends string "Test F6"
  1766. setudk    proc    near
  1767.     push    ax
  1768.     push    bx
  1769.     push    cx
  1770.     push    si
  1771.     push    di
  1772.     push    es
  1773.     cld
  1774.     lodsb                ; get key ident first byte
  1775.     sub    al,'0'            ; ascii to binary
  1776.     mul    ten            ; times 10
  1777.     xchg    ah,al            ; to ah
  1778.     lodsb                ; get key ident second byte
  1779.     sub    al,'0'            ; ascii to binary
  1780.     add    al,ah            ; plus high order part
  1781.     xor    ah,ah
  1782.     mov    bx,ax            ; key ident, 17 - 34
  1783.     lodsb                ; skip slash separator
  1784.     sub    cx,3            ; three less bytes in the string
  1785.     sub    bx,17            ; remove key ident bias of 17
  1786.     cmp    bx,17            ; out of range?
  1787.     ja    setudkx            ; a = yes, ignore
  1788.     shl    bx,1            ; index words
  1789.     cmp    udkseg[bx],0        ; has a segment been allocated for it?
  1790.     je    setudk1            ; e = no
  1791.     mov    ax,udkseg[bx]        ; get segment to es
  1792.     mov    es,ax
  1793.     mov    ah,freemem        ; deallocate old memory block, es:0
  1794.     int    dos
  1795.     mov    udkseg[bx],0        ; clear table entry too
  1796. setudk1:jcxz    setudkx            ; z = no definition, clear entry
  1797.     push    bx            ; save index BX
  1798.     mov    bx,cx            ; get string length
  1799.     shr    bx,1            ; two hex digits per final byte
  1800.     add    bx,15+1            ; round up plus length byte
  1801.     shr    bx,1            ; convert to paragraphs
  1802.     shr    bx,1
  1803.     shr    bx,1
  1804.     shr    bx,1
  1805.     mov    di,bx            ; remember request
  1806.     mov    ah,alloc        ; allocate BX paragraphs
  1807.     int    dos
  1808.     jc    setudkx            ; c = failure
  1809.     cmp    di,bx            ; requested vs allocated
  1810.     pop    bx            ; recover bx
  1811.     je    setudk2            ; e = enough
  1812.     mov    ah,freemem        ; return the memory, es is ptr
  1813.     int    dos
  1814.     jmp    short setudkx        ; exit failure
  1815.  
  1816. setudk2:mov    es,ax            ; segment of allocated memory
  1817.     mov    udkseg[bx],es        ; segment:0 of definition string
  1818.     xor    di,di
  1819.     cld
  1820.     mov    al,cl            ; length of string
  1821.     shr    al,1            ; two hex bytes per stored byte
  1822.     xor    ch,ch
  1823.     stosb                ; store length byte
  1824.     jcxz    setudkx            ; z = empty string
  1825. setukd3:lodsb                ; get first hex digit
  1826.     dec    cx            ; adjust count remaining
  1827.     or    al,20h            ; to lower case
  1828.     cmp    al,'9'            ; digit?
  1829.     jbe    setudk4            ; be = yes
  1830.     sub    al,'a'-'9'-10        ; hex letter to column three
  1831. setudk4:sub    al,'0'            ; ascii to binary
  1832.     shl    al,1            ; times 16
  1833.     shl    al,1
  1834.     shl    al,1
  1835.     shl    al,1
  1836.     mov    ah,al            ; save in ah
  1837.     lodsb                ; get second hex digit
  1838.     or    al,20h            ; to lower case
  1839.     cmp    al,'9'            ; digit?
  1840.     jbe    setudk5            ; be = yes
  1841.     sub    al,'a'-'9'-10        ; hex letter to column three
  1842. setudk5:sub    al,'0'            ; ascii to binary
  1843.     add    al,ah            ; join both parts
  1844.     stosb                ; store final byte
  1845.     loop    setukd3
  1846. setudkx:pop    es
  1847.     pop    di
  1848.     pop    si
  1849.     pop    cx
  1850.     pop    bx
  1851.     pop    ax
  1852.     clc
  1853.     ret
  1854. setudk    endp
  1855.  
  1856. ; Clear all User Definable Keys, deallocate memory for their definitions
  1857. udkclear proc    near
  1858.     push    ax
  1859.     push    bx
  1860.     push    cx
  1861.     push    es
  1862.     mov    cx,17            ; 17 entries
  1863.     xor    bx,bx
  1864. udkcle1:mov    ax,udkseg[bx]        ; segment of definition
  1865.     or    ax,ax            ; segment defined?
  1866.     jz    udkcle2            ; z = no, try next key
  1867.     mov    es,ax
  1868.     mov    udkseg[bx],0        ; clear the entry
  1869.     mov    ah,freemem        ; release the memory
  1870.     int    dos
  1871. udkcle2:add    bx,2            ; word index
  1872.     loop    udkcle1            ; do all
  1873.     pop    es
  1874.     pop    cx
  1875.     pop    bx
  1876.     pop    ax
  1877.     clc
  1878.     ret
  1879. udkclear endp
  1880.  
  1881.                     ; general character out for emulator
  1882. chrout:    cmp    flags.vtflg,0        ; emulating?
  1883.     je    chrou5            ; e = no
  1884.     call    anskbi            ; say we had keyboard input
  1885.     cmp    al,cr            ; CR?
  1886.     jne    chrou5            ; ne = no, just output it and return
  1887.     test    vtemu.vtflgop,anslnm    ; ANSI new-line mode set?
  1888.     jz    chrou5            ; z = no, just send the cr
  1889.     cmp    dupflg,0        ; full duplex?
  1890.     je    chrou4            ; e = yes
  1891.     cmp    al,trans.seol        ; End of Line char?
  1892.     jne    chrou5            ; ne = no
  1893. chrou4:    mov    ah,trans.seol        ; save eol char
  1894.     push    ax            ; save on stack
  1895.     mov    trans.seol,lf        ; make LF the eol char
  1896.     call    outprt            ; output a carriage-return
  1897.     mov    al,lf            ; followed by a line feed
  1898.     call    outprt            ; send the LF
  1899.     pop    ax
  1900.     mov    trans.seol,ah        ; restore eol char
  1901.     ret
  1902. chrou5:    jmp    outprt
  1903.  
  1904. ; output, no echo, 8-bit control chars as literals or "ESC char" form
  1905. out8bit    proc    near
  1906.     mov    ttyact,0        ; network, group chars for packet
  1907.     cmp    flags.vtflg,ttvt320    ; VT320?
  1908.     jne    out8bi1            ; ne = no
  1909.     cmp    parmsk,7fh        ; using parity?
  1910.     je    out8bi1            ; e = yes
  1911.     test    vtemu.vtflgop,vscntl    ; doing 8-bit controls?
  1912.     jnz    out8bi2            ; nz = yes, send 8-bit control char
  1913. out8bi1:test    al,80h            ; in range for C1 controls?
  1914.     jz    out8bi2            ; z = no
  1915.     cmp    al,9fh
  1916.     ja    out8bi2            ; a = no
  1917.     push    ax
  1918.     mov    al,escape        ; send ESCAPE
  1919.     call    prtbout
  1920.     pop    ax
  1921.     sub    al,40h            ; compose second char
  1922. out8bi2:mov    ttyact,1        ; network, restore single char mode
  1923.     jmp    prtbout            ; send final char
  1924. out8bit    endp
  1925.                     ; these commands invoke Quit
  1926. cdos:    mov    al,'P'            ; Push to DOS
  1927.     jmp    short cmdcom
  1928. cstatus:mov    al,'S'            ; Status
  1929.     jmp    short cmdcom
  1930. cquit:    mov    al,'C'            ; Exit Connect mode
  1931.     jmp    short cmdcom
  1932. cquery:    mov    al,'?'            ; Help
  1933.     jmp    short cmdcom
  1934. chang:    mov    al,'H'            ; Hangup, drop DTR & RTS
  1935.     jmp    short cmdcom
  1936. cmdcom:    mov    kbdflg,al        ; pass char to msster.asm via kbdflg
  1937.     stc                ; signal that Quit is needed
  1938.     ret
  1939.                        ; Screen dump entry from keyboad xlat
  1940. dmpscn    proc    near            ; dump screen to file
  1941.     cmp    flags.vtflg,tttek    ; doing Tektronix emulation?
  1942.     je    dmpscn2            ; e = yes, use Tek emulator
  1943.     test    tekflg,1        ; emulation a Tektronix?
  1944.     jz    dmpscn1            ; z = no
  1945. dmpscn2:call    tekdmp            ; near-call Tek screen dump utility
  1946.     clc
  1947.     ret
  1948. dmpscn1:call    savescr            ; save screen to buffer
  1949.     call    dumpscr            ; do buffer to file
  1950.     clc                ; do not exit Connect mode
  1951.     ret
  1952. dmpscn    endp
  1953.  
  1954.      
  1955. ;[IU2] Routine to toggle VT100/VT52/Heath-19 modes in VT100 emulator.
  1956.      
  1957. vtans52 proc    near
  1958.     cmp    flags.vtflg,0        ; emulating?
  1959.     je    vtans5            ; e = no
  1960.     call    ans52t            ; call MSZ toggle-it routine
  1961.     clc                ; clear c bit so don't exit Connect
  1962. vtans5:    ret
  1963. vtans52 endp
  1964.                     ; Toggle Mode Line
  1965. trnmod    proc    near
  1966.     cmp    flags.modflg,1        ; mode line enabled and owned by us?
  1967.     jne    trnm1            ; ne = no, don't touch it
  1968.     cmp    flags.vtflg,tttek    ; Tek mode?
  1969.     je    trnm3            ; e = yes
  1970.     cmp    tekflg,0        ; Tek submode?
  1971.     jne    trnm3            ; ne = yes, no mode line changes
  1972.     test    yflags,modoff        ; mode line already off?
  1973.     jnz    trnm2            ; nz = yes, go turn on
  1974.     or    yflags,modoff        ; say modeline is toggled off
  1975.     call    clrmod            ; clear mode line
  1976. trnm1:    clc                ; clear c bit so don't exit Connect
  1977.     ret
  1978. trnm2:    cmp    flags.vtflg,0        ; emulating a terminal?
  1979.     jne    trnm3            ; ne = yes
  1980.     push    dx            ; scroll screen to save bottom line
  1981.     mov    ah,prstr        ; for terminal type none
  1982.     mov    dx,offset crlf
  1983.     int    dos
  1984.     pop    dx
  1985. trnm3:    call    modlin            ; turn on modeline
  1986.     and    yflags,not modoff    ; say modeline is not toggled off
  1987.     clc
  1988.     ret
  1989. trnmod    endp
  1990.  
  1991. modlin    proc    near            ; turn on mode line
  1992.     mov    al,trans.escchr        ; Connect mode escape character
  1993.     mov    modbuf.m_echr,' '    ; first char is initial space
  1994.     mov    modbuf.m_hlp,' '    ; goes here too
  1995.     cmp    al,32            ; printable?
  1996.     jnb    modl1            ; yes, keep going
  1997.     add    al,40h            ; made printable
  1998.     mov    modbuf.m_echr,5eh    ; caret, note control char
  1999.     mov    modbuf.m_hlp,5eh
  2000. modl1:    mov    modbuf.m_echr+1,al    ; fill in character
  2001.     mov    modbuf.m_hlp+1,al
  2002.     mov    bx,argadr        ; get argument block
  2003.     mov    al,[bx].baudb        ; get baud bits
  2004.     mov    si,offset unkbaud    ; assume unknown baud
  2005.     mov    cx,size m_baud        ; length of baud space
  2006.     cmp    al,baudnsiz        ; too big?
  2007.     jnb    modl2            ; nb = yes, use default
  2008.     mul    cl
  2009.     xor    ah,ah
  2010.     add    ax,offset baudn
  2011.     mov    si,ax
  2012. modl2:    mov    di,offset modbuf.m_baud
  2013.     push    es            ; save es
  2014.     push    ds
  2015.     pop    es            ; set es to data segment
  2016.     cld
  2017.     rep    movsb            ; copy in baud rate
  2018.     mov    al,[bx].parity        ; get parity code
  2019.     shl    al,1            ; each is 4 bytes long
  2020.     shl    al,1
  2021.     xor    ah,ah
  2022.     add    ax,offset parnams    ; names of parity settings
  2023.     mov    si,ax
  2024.     mov    cx,4            ; each is 4 long
  2025.     mov    di,offset modbuf.m_par
  2026.     rep    movsb
  2027.     mov    si,offset remmsg    ; assume remote echoing
  2028.     test    yflags,lclecho        ; local echo on?
  2029.     jz    modl4            ; z = no
  2030.     mov    si,offset lclmsg    ; say echo is local
  2031. modl4:    mov    cx,3            ; size of on/off
  2032.     mov    di,offset modbuf.m_echo
  2033.     rep    movsb
  2034.     mov    al,portno        ; communications port
  2035.     cmp    al,' '            ; binary (non-printable)?
  2036.     jae    modl5            ; ae = no, ascii
  2037.     add    al,'0'            ; convert to ascii
  2038. modl5:    mov    modbuf.m_prt,al        ; fill in port number
  2039.     mov    cx,8            ; blank out terminal id field
  2040.     mov    si,offset mtty        ; assume no terminal emulation
  2041.     mov    di,offset modbuf.m_term ; destination
  2042.     rep    movsb            ; copy it in
  2043.     pop    es
  2044.     mov    word ptr modbuf.m_prn,'  '; assume not printing the screen
  2045.     mov    modbuf.m_prn+2,' '
  2046.     test    anspflg,prtscr+2    ; print the screen? (msz uses 1 & 2)
  2047.     jz    modl5a            ; z = no
  2048.     mov    word ptr modbuf.m_prn,'RP' ; yes. display PRN at end of line
  2049.     mov    modbuf.m_prn+2,'N'
  2050. modl5a:    call    getpos            ; get cursor position
  2051.     mov    cursor,dx        ; save cursor position
  2052.     mov    dx,offset modbuf    ; mode line image ptr for putmod
  2053.     call    putmod            ; display mode line
  2054.     cmp    flags.vtflg,0        ; emulating?
  2055.     je    modl7            ; e = no
  2056.     and    yflags,not modoff    ; update local flags (mode line on)
  2057.     call    ansdsl            ; get extras from emulator
  2058. modl7:    mov    dx,cursor
  2059.     jmp    setpos            ; reposition cursor
  2060. modlin    endp
  2061.  
  2062. trnprs:    push    ax            ; toggle ^ PrtSc screen to printer
  2063.     test    anspflg,prtscr        ; are we currently printing?
  2064.     jnz    trnpr2            ; nz = yes, its on and going off
  2065.     mov    ah,ioctl
  2066.     mov    al,7            ; get output status of printer
  2067.     push    bx
  2068.     mov    bx,4            ; file handle for system printer
  2069.     int    dos
  2070.     pop    bx
  2071.     jc    trnpr1            ; c = printer not ready
  2072.     cmp    al,0ffh            ; Ready status?
  2073.     je    trnpr2            ; e = Ready    
  2074. trnpr1:    call    vtbell            ; Not Ready, complain
  2075.     jmp    trnpr3            ; and ignore request
  2076. trnpr2:    xor    anspflg,prtscr        ; flip the flag
  2077.     test    yflags,modoff        ; mode line off?
  2078.     jnz    trnpr3            ; nz = yes
  2079.     call    modlin            ; else rewrite mode line
  2080. trnpr3:    pop    ax
  2081.     clc                ; return carry clear (don't quit)
  2082.     ret
  2083.  
  2084. ; Print on PRN the char in register al. On success return with C bit clear.
  2085. ; On failure do procedure pntchk and return its C bit (typically C set).
  2086. ; Uses buffer dumpbuf (screen dump).
  2087. pntchr    proc    near
  2088.     push    bx            ; buffer the character
  2089.     mov    bx,pntptr        ; offset of next free byte in buffer
  2090.     mov    [bx],al            ; store the character
  2091.     inc    bx            ; update pointer
  2092.     mov    pntptr,bx        ; save pointer
  2093.     cmp    bx,offset dumpbuf+dumplen ; buffer full yet?
  2094.     pop    bx
  2095.     jb    pntchrx            ; b = no, just return
  2096.     jmp    pntflsh            ; go flush the buffer
  2097. pntchrx:clc                ; clear carry bit
  2098.     ret
  2099. pntchr    endp
  2100.  
  2101. ; Flush printer buffer. Return carry clear if success.
  2102. ; On failure do procedure pntchk and return its C bit (typically C set).
  2103. ; Uses buffer dumpbuf (screen dump).
  2104. pntflsh    proc    near
  2105.     cmp    pntptr,offset dumpbuf    ; any text in buffer?
  2106.     jne    pntfls1            ; ne = yes
  2107.     ret                ; else nothing to do
  2108. pntfls1:push    ax
  2109.     push    bx
  2110.     push    cx
  2111.     push    dx
  2112.     mov    bx,portval
  2113.     mov    bx,[bx].flowc        ; get flow control chars (bl=xoff)
  2114.     mov    flowon,bh
  2115.     mov    flowoff,bl        ; save for later
  2116.     mov    al,bl            ; get flow control char
  2117.     cmp    al,0            ; flow control active?
  2118.     je    pntfls2            ; e = no, not using xoff
  2119.     call    prtbout            ; output xoff (al), no echo
  2120. pntfls2:mov    ah,write2
  2121.     mov    bx,4            ; file handle for DOS printer PRN
  2122.     mov    cx,pntptr        ; next free byte in buffer
  2123.     mov    dx,offset dumpbuf    ; start of buffer
  2124.     mov    pntptr,dx        ; reset buffer pointer
  2125.     sub    cx,dx            ; cx = current byte count
  2126.     jcxz    pntfls3            ; z = empty, do nothing
  2127.     int    dos            ; write buffer to printer
  2128. pntfls3:pushf                ; save carry status bit
  2129.     mov    al,flowon
  2130.     cmp    al,0            ; flow control active?
  2131.     je    pntfls4            ; e = no, not using xon
  2132.     call    prtbout            ; output xon (al), no echo
  2133. pntfls4:popf
  2134.     pop    dx
  2135.     pop    cx
  2136.     pop    bx
  2137.     pop    ax
  2138.     jc    pntchk            ; c = error (printer not ready)
  2139.     ret                ; nc = success
  2140. pntflsh    endp
  2141.  
  2142. ; Check for PRN (DOS's printer) being ready. If ready, return with C clear
  2143. ; Otherwise, write Not Ready msg on mode line and return with C bit set.
  2144. ; N.B. DOS Critical Error will occur here if PRN is not ready.  [jrd]
  2145. pntchk    proc    near
  2146.     push    dx
  2147.     push    cx
  2148.     push    ax
  2149.     mov    cx,10            ; ten retries before declaring error
  2150. pntchk0:mov    ah,ioctl        ; get printer status, via DOS
  2151.     mov    al,7            ; status for output
  2152.     push    bx
  2153.     mov    bx,4            ; std handle for DOS system printer
  2154.     int    dos
  2155.     pop    bx
  2156.     jc    pntchk1            ; c = call failed
  2157.     cmp    al,0ffh            ; code for Ready?
  2158.     je    pntchk3            ; e = yes, assume printer is ready
  2159. pntchk1:push    cx            ; save counter, just in case
  2160.     mov    ax,100            ; wait 100 millisec
  2161.     call    pcwait
  2162.     pop    cx
  2163.     loop    pntchk0            ; and try a few more times
  2164.                     ; get here when printer is not ready
  2165.     test    yflags,modoff        ; is mode line off?
  2166.     jnz    pntchk2            ; nz = off, skip msg
  2167.     push    bx
  2168.     mov    dx,offset pntmsg    ; say printer not ready
  2169.     call    putmod            ; write on mode line
  2170.     pop    bx
  2171. pntchk2:pop    ax
  2172.     pop    cx
  2173.     pop    dx
  2174.     stc                ; say printer not ready
  2175.     ret
  2176. pntchk3:pop    ax
  2177.     pop    cx
  2178.     pop    dx
  2179.     clc                ; say printer is ready
  2180.     ret
  2181. pntchk    endp
  2182.  
  2183. ;;;;; General screen management routines for IBM PC
  2184.  
  2185. ; computes screen location to ax, given row and col in [dh,dl], resp.
  2186.  
  2187. scrloc    proc    near
  2188.     mov    al,dh            ; get row
  2189.     mul    crt_cols        ; multiply by number of columns
  2190.     add    al,dl            ; plus current column number
  2191.     adc    ah,0            ; ripple carry
  2192.     shl    ax,1            ; double for attributes
  2193.     ret
  2194. scrloc    endp
  2195.      
  2196. ; Routine to set cursor type.  Pass cursor type in al: 0 = No cursor,
  2197. ; 1 = Underline cursor, 2 = Block cursor.   All cursors blink due to hardware.
  2198. ; Routine frags any ac that video ints frag.
  2199. ; For EGA boards running in non-25 line mode the cursor emulation is turned
  2200. ; off during cursor shape changing and restored afterward. It's another
  2201. ; ega Feature. [jrd]
  2202. ; Sense crt_mode 18h as Tseng Labs UltraPAK mono board in 132 column mode.
  2203. csrtype proc    near
  2204.     push    cx            ; save the reg
  2205.     mov    cx,0F00H        ; assume no cursor
  2206.     or    al,al            ; no cursor?
  2207.     jz    csrty2            ; z = yes, no cursor
  2208.     cmp    crt_mode,7        ; B&W card?
  2209.     je    csrty3            ; e = yes, different sizes
  2210.     cmp    crt_mode,18h        ; Tseng UltraPAK mono board?
  2211.      je    csrty3            ; e = yes, use mono cursor
  2212.     mov    cx,0607H        ; No, use CGA underline cursor
  2213.     cmp    al,2            ; Block?
  2214.     jne    csrty2            ; ne = no, set it now
  2215. csrty1: xor    ch,ch            ; make cursor a block
  2216. csrty2:    cmp    ega_mode,0        ; ega board active?
  2217.     je    csrty4            ; e = no
  2218.     cmp    byte ptr low_rgt+1,23    ; standard screen length?
  2219.     je    csrty4            ; e = yes, use regular cursor setting
  2220.     push    es            ; EGA. turn off cursor emulation
  2221.     mov    ax,40h            ; 40:87h is ega Info byte
  2222.     mov    es,ax
  2223.     push    es:[87h]        ; save Info byte around call
  2224.     or    byte ptr es:[87h],1    ; set emulation off (low bit = 1)
  2225.     mov    ah,1            ; video function for set cursor type
  2226.     int    screen
  2227.     pop    es:[87h]        ; restore Info byte
  2228.     pop    es            ;  and our work register
  2229.     pop    cx
  2230.     ret
  2231. csrty4:    mov    ah,1            ; video function for set cursor type
  2232.     int    screen            ; regular cursor shape setting
  2233.     pop    cx
  2234.     ret     
  2235. csrty3: mov    cx,0B0CH        ; assume B&W underline cursor
  2236.     cmp    al,2            ; Block?
  2237.     jne    csrty2            ; ne = no, set it now
  2238.     jmp    short csrty1        ; make it a block
  2239. csrtype endp
  2240.  
  2241.  
  2242. ; Save the entire screen in a buffer so we can restore and/or dump it.
  2243. ; Saves regular (80x25) screens to memory buffer allocated dynamically from
  2244. ; DOS or if insufficient space then to video memory page 1. Save address is
  2245. ; savadr+2:savadr (seg:offset). A memory buffer is deallocated and reallocated
  2246. ; if it's size needs to change, otherwise it is reused as is.
  2247. ; Current low_rgt size info is saved in savflg for restscr. Note, some
  2248. ; Environments (TopView/Windows etc) may not permit use of page 1 and we
  2249. ; will not save the screen if video page 1 is required under Environments.
  2250. savescr    proc    near
  2251.     push    es
  2252.     push    ds
  2253.     push    ax
  2254.     push    cx
  2255.     push    dx
  2256.     push    si
  2257.     push    di
  2258.     call    scrmod            ; ascertain video mode and screen
  2259.     call    scrseg            ; get screen segment in ax and es:di
  2260.     mov    di,ax            ; save screen seg in di
  2261.     mov    ax,low_rgt        ; text screen lower right (typ 23,79)
  2262.     inc    al            ; number of columns
  2263.     add    ah,2            ;  plus status line = number of rows
  2264.     mul    ah            ; times rows = characters on screen
  2265.     shl    ax,1            ; times two for attributes = page 1
  2266.     mov    dx,ax            ; save number of screen bytes in dx
  2267.     mov    ax,savadr+2        ; seg of saved memory, if any
  2268.     or    ax,ax            ; none?
  2269.     jz    savsc1            ; z = yes, none
  2270.     cmp    ax,0a000h        ; in video memory?
  2271.     jae    savsc1            ; ae = yes
  2272.     mov    ax,low_rgt        ; text screen lower right (typ 23,79)
  2273.     cmp    ax,savflg        ; same as saved screen?
  2274.     je    savsc4            ; e = yes, no allocation needed
  2275.     mov    ax,savadr+2        ; get old allocation
  2276.     mov    es,ax
  2277.     mov    ah,freemem        ; free old memory
  2278.     int    dos
  2279.     mov    savadr+2,0        ; clear old segment
  2280.                     ; allocate and use DOS memory for save
  2281. savsc1:    mov    bx,dx            ; bytes to do
  2282.     add    bx,15            ; round up
  2283.     mov    cl,4
  2284.     shr    bx,cl            ; bytes/screen to paragraphs/screen
  2285.     mov    ah,alloc        ; allocate memory
  2286.     int    dos            ; bx has # free paragraphs
  2287.     jc    savsc2            ; c = not enough for it, use video
  2288.     mov    savadr+2,ax        ; working seg address for restore
  2289.     mov    savadr,0        ; and no offset for memory buffer
  2290.     jmp    short savsc4
  2291.                     ; use video page 1 as save area
  2292. savsc2:    cmp    di,0a000h        ; screen segment is in DOS (Environ)?
  2293.     jae    savsc3            ; ae = no
  2294.     mov    savadr+2,0        ; then say no seg because no save
  2295.     jmp    savsc5            ; exit without saving screen
  2296. savsc3:    mov    cx,dx            ; number of screen bytes
  2297.     and    cx,000fh        ; get lower four bits for offset part
  2298.     mov    savadr,cx        ; save offset in this word
  2299.     mov    ax,dx            ; number of screen bytes
  2300.     mov    cl,4
  2301.     shr    ax,cl            ; compute number of paragraphs 
  2302.     add    ax,di            ; add paragraphs, point ax to page 1
  2303.     mov    savadr+2,ax        ; and save segment in this word
  2304.                     ; save the screen
  2305. savsc4:    push    low_rgt            ; current screen dimensions
  2306.     pop    savflg            ; save it for screen restore
  2307.     mov    cx,dx            ; number of screen bytes
  2308.     shr    cx,1            ; do as words
  2309.     push    di            ; preserve di around call
  2310.     call    scroff            ; turn off screen [dt]
  2311.     pop    di
  2312.     mov    ax,savadr+2        ; destination segment
  2313.     mov    es,ax            ; segment of storage area
  2314.     push    di            ; screen memory segment from di
  2315.     mov    di,savadr        ;  offset of storage
  2316.     pop    ds            ; put into ds
  2317.     xor    si,si
  2318.     cld
  2319.     rep    movsw            ; save the screen
  2320. savsc5:    pop    di
  2321.     pop    si
  2322.     pop    dx
  2323.     pop    cx
  2324.     pop    ax
  2325.     pop    ds
  2326.     call    scron            ; turn on screen
  2327.     pop    es
  2328.     ret
  2329. savescr    endp
  2330.  
  2331. ; Restore screen from buffer (savadr+2:savadr, with screen size in savflg).
  2332. ; Restores all screen lines.
  2333. restscr    proc    near
  2334.     push    es
  2335.     push    si
  2336.     push    di
  2337.     cmp    savadr+2,0        ; saved anything yet?
  2338.     jne    restsc1            ; ne = yes
  2339.     xor    ax,ax
  2340.     mov    bx,low_rgt        ; clear the screen to current colors
  2341.     call    atsclr
  2342.     jmp    restsc2
  2343.  
  2344. restsc1:mov    ax,savflg        ; saved low_rgt text screen coord
  2345.     add    ah,2            ; number of screen lines
  2346.     inc    al            ; number of screen columns
  2347.     mul    ah            ; columns time lines = # characters
  2348.     mov    cx,ax            ; save this in counter cx
  2349.     push    cx            ; save count
  2350.     call    scrseg            ; get address of screen in es:di
  2351.     call    scroff            ; turn off screen [dt]
  2352.     push    ds            ; save original data segment
  2353.     mov    si,savadr        ; offset of storage area
  2354.     push    savadr+2        ; segment of same
  2355.     pop    ds            ; put storage segment into ds
  2356.     cld
  2357.     rep    movsw             ; restore data to screen
  2358.     pop    ds            ; recover original data segment
  2359.     call    scron            ; turn on screen [dt]
  2360.     pop    cx            ; recover count
  2361.     call    scrsync            ; synch Topview with new screen
  2362. restsc2:pop    di
  2363.     pop    si
  2364.     pop    es
  2365.     ret
  2366. restscr    endp
  2367.  
  2368. ; Save the screen to a buffer and then append buffer to a disk file. [jrd]
  2369. ; Default filename is Kermit.scn; actual file can be a device too. Filename
  2370. ; is determined by mssset and is passed as pointer dmpname.
  2371. ; Dumpscr reads the screen image saved by savescr so call savescr call first.
  2372.  
  2373. dumpscr    proc    near
  2374.     cmp    savadr+2,0        ; any save area?
  2375.     jne    dmp6            ; ne = yes
  2376.     clc                ; else ignore and return success
  2377.     ret
  2378. dmp6:    push    ax
  2379.     push    bx
  2380.     push    cx
  2381.     push    dx
  2382.     mov    dmphand,-1        ; preset illegal handle
  2383.     mov    dx,offset dmpname    ; name of disk file, from mssset
  2384.     mov    ax,dx            ; where isfile wants name ptr
  2385.     call    isfile            ; what kind of file is this?
  2386.     jc    dmp5            ; c = no such file, create it
  2387.     test    byte ptr filtst.dta+21,1fh ; file attributes, ok to write?
  2388.     jnz    dmp0            ; nz = no.    
  2389.     mov    al,1            ; writing
  2390.     mov    ah,open2        ; open existing file
  2391.     int    dos
  2392.     jc    dmp0            ; c = failure
  2393.     mov    dmphand,ax        ; save file handle
  2394.     mov    bx,ax            ; need handle here
  2395.     mov    cx,0ffffh        ; setup file pointer
  2396.     mov    dx,-1            ; and offset
  2397.     mov    al,2            ; move to eof minus one byte
  2398.     mov    ah,lseek        ; seek the end
  2399.     int    dos
  2400.     jmp    dmp1
  2401.  
  2402. dmp5:    test    filtst.fstat,80h    ; access problem?
  2403.     jnz    dmp0            ; nz = yes
  2404.     mov    ah,creat2        ; file did not exist
  2405.     mov    cx,20h            ; attributes, archive bit
  2406.     int    dos
  2407.     mov    dmphand,ax        ; save file handle
  2408.     jnc    dmp1            ; nc = ok
  2409.  
  2410. dmp0:    call    getpos            ; get cursor position
  2411.     push    dx            ; save it
  2412.     mov    dh,byte ptr low_rgt+1    ; go to status line
  2413.     inc    dh
  2414.     xor    dl,dl            ; left most column
  2415.     call    setpos            ; position cursor
  2416.     mov    dx,offset dmperr    ; say no can do
  2417.     mov    ah,prstr
  2418.     int    dos
  2419.     pop    dx            ; get original cursor position
  2420.     call    setpos            ; position cursor
  2421.     pop    dx
  2422.     pop    cx
  2423.     pop    bx
  2424.     pop    ax
  2425.     clc
  2426.     ret
  2427.  
  2428. dmp1:    mov    ah,ioctl        ; is destination ready for output?
  2429.     mov    al,7            ; test output status
  2430.     mov    bx,dmphand        ; handle
  2431.     int    dos
  2432.     jc    dmp0            ; c = error
  2433.     cmp    al,0ffh            ; ready?
  2434.     jne    dmp0            ; ne = not ready
  2435.     push    di            ; read screen buffer, write lines
  2436.     push    si
  2437.     push    es
  2438.     mov    cl,byte ptr low_rgt+1    ; number of lines - 2
  2439.     add    cl,2            ; number of line on screen
  2440.     xor    ch,ch
  2441.     mov    si,savadr        ; offset in storage area
  2442. dmp2:    push    cx            ; save outer loop counter
  2443.     mov    es,savadr+2        ; get storage segment
  2444.     mov    di,offset dumpbuf    ; data segment memory
  2445.     mov    cl,byte ptr savflg    ; number of columns on screen - 1
  2446.     inc    cl            ; number of columns on screen
  2447.     xor    ch,ch
  2448. dmp3:    mov    ax,word ptr es:[si]    ; read char + attribute
  2449.     or    al,al            ; is it a null?
  2450.     jnz    dmp3c            ; nz = no
  2451.     mov    al,' '            ; replace null with space
  2452. dmp3c:    mov    byte ptr [di],al    ; store just char, don't use es:
  2453.     inc    si            ; update pointers
  2454.     inc    si
  2455.     inc    di
  2456.     loop    dmp3            ; do for each column
  2457.     std                ; set scan backward
  2458.     mov    cl,byte ptr savflg    ; number of columns on screen - 1
  2459.     inc    cl            ; number of columns on screen
  2460.     xor    ch,ch
  2461.     push    es
  2462.     mov    ax,ds
  2463.     mov    es,ax            ; set es to data segment for es:di
  2464.     mov    di,offset dumpbuf    ; start of line
  2465.     add    di,cx            ; plus length of line
  2466.     dec    di            ; minus 1 equals end of line
  2467.     mov    al,' '            ; thing to scan over
  2468.     repe    scasb            ; scan until non-space
  2469.     cld                ; set direction forward
  2470.     pop    es
  2471.     jz    dmp3a            ; z = all spaces
  2472.     inc    cx
  2473.     inc    di
  2474. dmp3a:    mov    word ptr [di+1],0A0Dh    ; append cr/lf
  2475.     add    cx,2            ; line count + cr/lf
  2476.     mov    dx,offset dumpbuf    ; array to be written
  2477.     mov    bx,dmphand        ; need file handle
  2478.     mov    ah,write2        ; write the line
  2479.     int    dos
  2480.     pop    cx            ; get line counter again
  2481.     jc    dmp3b            ; c = error
  2482.     loop    dmp2            ; do next line
  2483.     mov    dx,offset dumpsep    ; put in formfeed/cr/lf
  2484.     mov    cx,3            ; three bytes overall
  2485.     mov    ah,write2        ; write them
  2486. dmp3b:    mov    bx,dmphand        ; file handle
  2487.     int    dos
  2488.     mov    ah,close2        ; close the file now
  2489.     int    dos
  2490.     pop    es
  2491.     pop    si
  2492.     pop    di
  2493.     pop    dx
  2494.     pop    cx
  2495.     pop    bx
  2496.     pop    ax
  2497.     clc
  2498.     ret
  2499. dumpscr    endp
  2500.  
  2501.  
  2502. ; Get CRT mode - returns mode in variable crt_mode,
  2503. ; updates crt_cols and low_rgt.
  2504. ; For EGA active it looks in Bios work memory 40:84H for number of rows
  2505. scrmod    proc    near
  2506.     push    ax
  2507.     push    dx
  2508.     mov    ah,15            ; get current video state
  2509.     int    screen
  2510.     mov    crt_mode,al        ; store CRT mode value
  2511.     mov    crt_cols,ah        ; store # of cols
  2512.     mov    dl,ah            ; # of cols again
  2513.     mov    dh,crt_lins        ; and # of rows (constant from msster)
  2514.     cmp    ega_mode,0        ; ega active?
  2515.     je    scrmod4            ; e = no
  2516.     push    es            ; yes, permit different lengths
  2517.     mov    ax,40h            ; refer to 40:84h for # ega rows
  2518.     mov    es,ax
  2519.     mov    ah,es:[84h]        ; get number of rows - 1 (typ 24)
  2520.     cmp    ah,20            ; less than 20 rows?
  2521.     jb    scrmod3            ; b = yes, ignore this length
  2522.     cmp    ah,80            ; more than 80 rows?
  2523.     ja    scrmod3            ; a = yes, ignore this length
  2524.     mov    dh,ah            ; use this length
  2525.     mov    crt_lins,dh        ; update our working constant
  2526. scrmod3:pop    es
  2527. scrmod4:dec    dl            ; max text column, count from zero
  2528.     dec    dh            ; max text row, count from zero
  2529.     mov    low_rgt,dx        ; save away window address
  2530.     pop    dx
  2531.     pop    ax
  2532.     ret
  2533. scrmod    endp
  2534.  
  2535.  
  2536. ; Get screen segment - returns screen segment in ax, and full address in es:di
  2537.  
  2538. scrseg    proc    near
  2539.     xor    di,di            ; start at beginning of screen (0,0)
  2540.     mov    ax,0B000H        ; Assume B&W card
  2541.     cmp    crt_mode,7        ; Is it?
  2542.     je    scrse1            ; e = yes
  2543.     cmp    crt_mode,18h        ; Tseng UltraPAK mono in 132 col?
  2544.     je    scrse1            ; e = yes, use seg B000H
  2545.     mov    ax,0B800H        ; No - video memory is here on color
  2546.     cmp    crt_mode,12        ; graphics set?
  2547.     jb    scrse1            ; b = no
  2548.     cmp    crt_mode,18        ; end of ordinary 640x480 graphics
  2549.     ja    scrse1            ; a = no, assume CGA segment
  2550.     mov    ax,0A000H        ; graphics
  2551. scrse1:    mov    es,ax        ; tell Topview our hardware address needs
  2552.     mov    tv_segs,es        ; save our hardware screen address
  2553.     mov    tv_sego,di        ; segment and offset form
  2554.     mov    tv_mode,1        ; assume we're running under Topview
  2555.     mov    ah,tvhere        ; query Topview for its presence
  2556.     int    screen
  2557.     mov    ax,es            ; get its new segment for screen work
  2558.     cmp    ax,tv_segs        ; same as hardware?
  2559.     jne    scrse2            ; ne = no, we are being mapped
  2560.     cmp    di,tv_sego        ; check this too
  2561.     jne    scrse2        ; ne = no too. Use TV's work buf as screen
  2562.     mov    tv_mode,0        ; else no Topview or no mapping
  2563. scrse2:    mov    tv_segs,es        ; save segment
  2564.     mov    tv_sego,di        ; and offset
  2565.     ret
  2566. scrseg    endp
  2567.  
  2568. ; Synchronize a Topview provided virtual screen buffer with the image
  2569. ; seen by the user. Requires cx = number of words written to screen
  2570. ; (char & attribute bytes) and es:di = ENDING address of screen write.
  2571. ; Changes ax and di.
  2572. scrsync    proc    near
  2573.     cmp    tv_mode,0        ; Topview mode active?
  2574.     je    scrsyn1            ; e = no, skip DOS call below
  2575.     sub    di,cx            ; backup to start byte (cx = words)
  2576.     sub    di,cx            ;  after storing words to screen
  2577.     mov    ah,tvsynch        ; tell Topview we have changed screen
  2578.     int    screen            ;  so user sees updated screen
  2579. scrsyn1:ret
  2580. scrsync    endp
  2581.  
  2582. ; The following two routines are used to turn off the display while we
  2583. ; are reading or writing the screen in one of the color card modes.
  2584. ; Turn screen off for (known) color card modes only. All regs preserved.
  2585. ; Includes code for old procedure scrwait. 16 June 1987 [jrd]
  2586. scroff    proc    near
  2587.     cmp    ega_mode,0        ; Extended Graphics Adapter in use?
  2588.     jne    scrofx            ; ne = yes, no waiting
  2589.     cmp    tv_mode,0        ; Topview mode?
  2590.     jne    scrofx            ; ne = yes, no waiting
  2591.     cmp    crt_mode,7        ; B&W card?
  2592.     jnb    scrofx            ; nb = yes - just return
  2593.     cmp    refresh,0        ; slow refresh?
  2594.     jne    scrofx            ; ne = no wait
  2595.     push    ax            ; save ax and dx
  2596.     push    dx
  2597.     mov    dx,crt_status        ; CGA: Wait for vertical retrace
  2598. scrof1:    in    al,dx
  2599.     test    al,disp_enb        ; display enabled?
  2600.     jnz    scrof1            ; yes, keep waiting
  2601. scrof2:    in    al,dx
  2602.     test    al,disp_enb        ; now wait for it to go off
  2603.     jz    scrof2            ; so can have whole cycle
  2604.     mov    dx,crtmset        ; output to CRT mode set port
  2605.     mov    al,25H            ; this shuts down the display
  2606.     out    dx,al
  2607.     pop    dx            ; restore regs
  2608.     pop    ax
  2609. scrofx: ret
  2610. scroff    endp
  2611.  
  2612.  
  2613. ; Turn screen on for (known) color card modes only
  2614. ; All registers are preserved.
  2615.  
  2616. scron    proc    near
  2617.     cmp    ega_mode,0        ; Extended Graphics Adapter in use?
  2618.     jne    scronx            ; ne = yes, no waiting
  2619.     cmp    tv_mode,0        ; Topview mode?
  2620.     jne    scronx            ; ne = yes, no waiting
  2621.     cmp    crt_mode,7        ; B&W card?
  2622.     jnb    scronx            ; nb = yes - just return
  2623.     cmp    refresh,0        ; slow refresh?
  2624.     jne    scronx            ; ne = no wait
  2625.     push    ax            ; save ax, dx, and si
  2626.     push    dx
  2627.     push    si
  2628.     mov    al,crt_mode        ; convert crt_mode to a word
  2629.     xor    ah,ah
  2630.     mov    si,ax            ; get it in a usable register
  2631.     mov    al,msets[si]        ; fetch the modeset byte
  2632.     mov    dx,crtmset        ; this port
  2633.     out    dx,al            ; flash it back on
  2634.     pop    si
  2635.     pop    dx
  2636.     pop    ax
  2637. scronx: ret
  2638. scron    endp
  2639.  
  2640.  
  2641. ; Screen clearing routine. [IU]
  2642. ;
  2643. ; Call:        ax/    coordinates of first screen location to be cleared.
  2644. ;        bx/    coordinates of last location to be cleared.
  2645. ; Coord: ah = row [0-24], al = column [0-79]. Preserves all registers. [jrd]
  2646.  
  2647. atsclr:    push    ax            ; save regs 
  2648.     push    cx
  2649.     push    dx
  2650.     mov    dx,bx            ; compute last screen offset in ax
  2651.     push    ax
  2652.     call    scrmod            ; update column length
  2653.     pop    ax            ; scrmod zaps ax
  2654.     push    ax
  2655.     call    scrloc            ; get screen start address in ax
  2656.     mov    cx,ax            ; save it in cx for a minute
  2657.     pop    dx            ; compute first screen offset in ax
  2658.     call    scrloc
  2659.     sub    cx,ax            ; compute number of locs to clear
  2660.     add    cx,2
  2661.     sar    cx,1            ; make byte count a word count
  2662.     jle    atscl2            ; If nothing to clear, then vamos
  2663.     push    di            ; save regs
  2664.     push    es            ; save es
  2665.     push    ax            ; save displacement
  2666.     call    scrseg            ; get address of screen into es:di
  2667.     pop    di            ; displacement memory address into di
  2668.     mov    ah,scbattr        ; use current screen background attr
  2669.     mov    al,' '            ; use space for fill
  2670.     call    scroff            ; turn screen off if color card
  2671. atscl1:    push    cx            ; save word count for Topview
  2672.     cld
  2673.     rep    stosw            ; Blit... (excuse PDP-10ese please)
  2674.     pop    cx            ; recover word count
  2675.     call    scrsync            ; synch Topview
  2676.     call    scron            ; Turn screen back on if color card
  2677.     pop    es            ; Restore segment register
  2678.     pop    di            ; And destination index
  2679. atscl2:    pop    dx            ; restore regs
  2680.     pop    cx
  2681.     pop    ax
  2682.     ret
  2683.  
  2684. ; Scrolling routines.  vtscru scrolls up, vtscrd scrolls down 'scroll'
  2685. ; rows. Top lines are saved in the circular buffer before scrolling up.
  2686. ; When running under an Environment control number of line positions moved
  2687. ; to be less than scrolling region.
  2688. ; All registers are preserved.
  2689. ;
  2690. ; Screen-roll down. Move text down one line, for terminal emulator only.
  2691. ;
  2692. vtscrd: push    ax
  2693.     push    bx
  2694.     push    cx
  2695.     push    dx
  2696.     mov    ax,0700h        ; scroll down whole region
  2697.     mov    ch,mar_top        ; top margin line
  2698.     xor    cl,cl            ; left most column
  2699.     mov    dh,mar_bot        ; bottom margin line
  2700.     mov    dl,byte ptr low_rgt    ; right most column
  2701.     mov    bh,scbattr        ; attributes
  2702.     mov    bl,dh
  2703.     sub    bl,ch            ; region size - 1 line
  2704.     jz    vscrd1             ; z = region is 1 line, do one scroll
  2705.     mov    al,scroll        ; number of lines to scroll, from msz
  2706. vscrd1:    cmp    al,bl            ; want to scroll more that than?
  2707.     jbe    vscrd2            ; be = no
  2708.     push    ax
  2709.     mov    al,bl            ; limit to region-1 for Windows
  2710.     int    screen            ;  and do in parts
  2711.     pop    ax
  2712.     sub    al,bl            ; get remainder
  2713.     jmp    short vscrd1        ; do next part
  2714. vscrd2:    int    screen            ; scroll it down
  2715.     pop    dx
  2716.     pop    cx
  2717.     pop    bx
  2718.     pop    ax
  2719.     ret
  2720.      
  2721. ; Screen scroll up one line (text moves up) for terminal emulator use.
  2722. ; When running under an Environment control number of line positions moved
  2723. ; to be less than scrolling region.
  2724.      
  2725. vtscru: push    ax
  2726.     push    bx
  2727.     push    cx
  2728.     push    dx
  2729.     xor    ch,ch
  2730.     mov    cl,scroll        ; number of lines to scroll
  2731.     or    cl,cl
  2732.     jnz    vscru5
  2733.     jmp    vscru3            ; z = nothing to do
  2734. vscru5:    cmp    mar_top,0        ; scrolling the top screen line?
  2735.     ja    vscru2            ; a = no. don't save anything
  2736.     push    si
  2737.     push    di
  2738.     push    cx            ; (BDT) save this around the call
  2739.     call    putcirc            ; put screen lines in circular buffer
  2740.     pop    cx            ; (BDT) restore the register
  2741.     add    linec,cx        ; (BDT) increment the current line
  2742.     mov    cx,linec        ; new current line number
  2743.     sub    cx,lcnt            ; minus # in buf = qty new lines added
  2744.     jc    vscru4            ; c = not extending buffer
  2745.     add    lcnt,cx            ; (BDT) increment the line counter
  2746. vscru4:
  2747.     mov    cx,lcnt            ; (BDT) check: are we
  2748.     cmp    cx,lmax            ; (BDT) beyond the end?
  2749.     jbe    vscru1b            ; (BDT) be = no
  2750.     sub    cx,lmax            ; (BDT) compute overflow count
  2751.     add    linef,cx        ; (BDT) adjust the "first" line
  2752.     mov    cx,linef        ; (BDT) check: time to wrap?
  2753.     cmp    cx,linee        ; (BDT) ...
  2754.     jb    vscru1            ; (BDT) b = no
  2755.     sub    cx,linee        ; (BDT) yup
  2756.     mov    linef,cx        ; (BDT) adjust it
  2757. vscru1:    mov    cx,lmax            ; (BDT) get the maximum line count
  2758.     mov    lcnt,cx            ; (BDT) reset the line counter
  2759.     mov    linec,cx        ; (BDT) reset the current line
  2760. vscru1b:
  2761.     pop    di
  2762.     pop    si            ; now scroll the visible screen
  2763. vscru2: mov    ax,0600h        ; scroll up whole region
  2764.     mov    dh,mar_bot        ; bottom row
  2765.     mov    dl,byte ptr low_rgt    ; right most column
  2766.     mov    ch,mar_top        ; top row of scrolling region
  2767.     xor    cl,cl            ; left most column
  2768.     mov    bh,scbattr        ; attributes
  2769.     mov    bl,dh
  2770.     sub    bl,ch            ; region size - 1 line
  2771.     jz    vscru2b            ; z = region is 1 line, do one scroll
  2772.     mov    al,scroll        ; number of lines to scroll, from msz
  2773. vscru2a:cmp    al,bl            ; want to scroll more that than?
  2774.     jbe    vscru2b            ; be = no
  2775.     push    ax
  2776.     mov    al,bl            ; limit to region - 1 for Windows
  2777.     int    screen            ;  and do in parts
  2778.     pop    ax
  2779.     sub    al,bl
  2780.     jmp    short vscru2a        ; do next part
  2781. vscru2b:int    screen            ; scroll up that region
  2782. vscru3:    pop    dx            ; restore the rest of the regs
  2783.     pop    cx
  2784.     pop    bx
  2785.     pop    ax
  2786.     ret
  2787.  
  2788. ; (BDT) new screen-scrolling routines.  Single, circular buffer
  2789.      
  2790. homwnd    proc    near            ; "home" to start of the buffer
  2791.     push    cx            ; save registers
  2792.     mov    cx,lxtra        ; save this many lines
  2793.     call    putcirc            ; save them
  2794.     mov    linec,0            ; reset the current pointer
  2795.     call    getcirc            ; now get the new screen
  2796.     pop    cx            ; restore registers
  2797.     clc
  2798.     ret
  2799. homwnd    endp
  2800.      
  2801. endwnd    proc    near            ; "end" to end of the buffer
  2802.     push    cx            ; save registers
  2803.     mov    cx,lxtra        ; save this many lines
  2804.     call    putcirc            ; save them
  2805.     mov    cx,lcnt            ; reset the current pointer
  2806.     mov    linec,cx        ; save the results
  2807.     call    getcirc            ; now get the new screen
  2808.     pop    cx            ; restore registers
  2809.     clc
  2810.     ret
  2811. endwnd    endp
  2812.      
  2813. dnwpg    proc    near            ; scroll down 1 page
  2814.     push    cx            ; save registers
  2815.     mov    cx,lxtra        ; save this many lines
  2816.     call    putcirc            ; save them
  2817.     mov    cx,linec        ; reset the current pointer
  2818.     add    cx,lxtra        ;  to the next page
  2819.     cmp    cx,lcnt            ; did we go past the end?
  2820.     jbe    dnwpg1            ; be = no, we're OK
  2821.     mov    cx,lcnt            ; yup, back up
  2822. dnwpg1:
  2823.     mov    linec,cx        ; save the results
  2824.     call    getcirc            ; now get the new screen
  2825.     pop    cx            ; restore registers
  2826.     clc
  2827.     ret
  2828. dnwpg    endp
  2829.      
  2830. dnone    proc    near            ; scroll down 1 line
  2831.     push    cx            ; save registers
  2832.     mov    cx,lxtra        ; save this many lines
  2833.     call    putcirc            ; save them
  2834.     mov    cx,linec        ; reset the current pointer
  2835.     inc    cx            ;  to the next line
  2836.     cmp    cx,lcnt            ; oops, did we go past the end?
  2837.     jbe    dnone1            ; be = no, we're OK
  2838.     mov    cx,lcnt            ; yup, back up
  2839. dnone1:
  2840.     mov    linec,cx        ; save the results
  2841.     call    getcirc            ; now get the new screen
  2842.     pop    cx            ; restore registers
  2843.     clc
  2844.     ret
  2845. dnone    endp
  2846.      
  2847. upwpg    proc    near            ; scroll up 1 page
  2848.     push    cx            ; save registers
  2849.     mov    cx,lxtra        ; save this many lines
  2850.     call    putcirc            ; save them
  2851.     mov    cx,linec        ; reset the current pointer
  2852.     sub    cx,lxtra        ;  to the previous page
  2853.     cmp    cx,0            ; oops, did we go past the end?
  2854.     jge    upwpg1            ; ge = no, we're OK
  2855.     xor    cx,cx            ; yup, back up
  2856. upwpg1:
  2857.     mov    linec,cx        ; save the results
  2858.     call    getcirc            ; now get the new screen
  2859.     pop    cx            ; restore registers
  2860.     clc
  2861.     ret
  2862. upwpg    endp
  2863.      
  2864. upone    proc    near            ; scroll up 1 line
  2865.     push    cx            ; save registers
  2866.     mov    cx,lxtra        ; save this many lines
  2867.     call    putcirc            ; save them
  2868.     mov    cx,linec        ; reset the current pointer
  2869.     dec    cx            ;  to the previous line
  2870.     cmp    cx,0            ; oops, did we go past the end?
  2871.     jge    upone1            ; ge = no, we're OK
  2872.     xor    cx,cx            ; yup, back up
  2873. upone1:
  2874.     mov    linec,cx        ; save the results
  2875.     call    getcirc            ; now get the new screen
  2876.     pop    cx            ; restore registers
  2877.     clc
  2878.     ret
  2879. upone    endp
  2880.      
  2881. ; Put cx lines into the circular buffer.
  2882. ; Source is tv_segs:si which is the current screen address.
  2883. putcirc    proc    near            ; put lines in the circular buffer
  2884.     jcxz    putcir9            ; z = no lines to save
  2885.     push    es            ; save ES for a tad
  2886.     call    scroff            ; turn off the screen
  2887.     mov    si,tv_sego        ; initial screen offset
  2888.     mov    ax,linef        ; get the first line pointer
  2889.     add    ax,linec        ; add the current line counter
  2890.     dec    ax            ; get a running start
  2891. putcir1:inc    ax            ; increment the current line pointer
  2892.     cmp    ax,linee        ; fallen off the end of the buffer?
  2893.     jb    putcir2            ; b = no, proceed
  2894.     sub    ax,linee        ; back up to the buffer start
  2895. putcir2:push    ax            ; save the current line pointer
  2896.     mul    ppl            ; compute the paragraph offset
  2897.     add    ax,iniseg        ; add the initial segment
  2898.     mov    es,ax            ; now we have the segment pointer
  2899.     xor    di,di            ; initial buffer offset is 0
  2900.     push    cx            ; save the number of lines
  2901.     xor    ch,ch            ; get the number of characters to move
  2902.     mov    cl,crt_cols
  2903.     push    ds            ; get the offset of the screen
  2904.     mov    ds,tv_segs        ; get the segment of the screen
  2905.     rep    movsw            ; move them
  2906.     pop    ds            ; restore DS
  2907.     pop    cx            ; restore the line count
  2908.     pop    ax            ; restore the buffer counter
  2909.     loop    putcir1            ; go back for more
  2910.     call    scron            ; turn the screen back on
  2911.     pop    es            ; restore ES
  2912. putcir9:ret
  2913. putcirc    endp
  2914.      
  2915. ; Get CX lines from the circular buffer, non destructivly.
  2916. ; Destination preset in es:di which is the current screen address.
  2917. getcirc    proc    near            ; get lines from the circular buffer
  2918.     mov    cx,lxtra        ; restore this many lines
  2919.     jcxz    getcir3            ; z = nothing to do
  2920.     call    scroff            ; turn off the screen
  2921.     push    es            ; save ES for a tad
  2922.     mov    es,tv_segs        ; get the segment of the screen
  2923.     mov    di,tv_sego        ; initial screen offset
  2924.     mov    ax,linef        ; get the first line pointer
  2925.     add    ax,linec        ; add the current line counter
  2926.     dec    ax            ; get a running start
  2927. getcir1:inc    ax            ; increment the current line pointer
  2928.     cmp    ax,linee        ; fallen off the end of the buffer?
  2929.     jb    getcir2            ; b = no, proceed
  2930.     sub    ax,linee        ; back up to the buffer start
  2931. getcir2:push    ax            ; save the current line pointer
  2932.     mul    ppl            ; compute the paragraph offset
  2933.     add    ax,iniseg        ; add the initial segment
  2934.     xor    si,si            ; initial offset is 0
  2935.     push    cx            ; save the number of lines
  2936.     xor    ch,ch            ; get the number of characters to move
  2937.     mov    cl,crt_cols        ;  ...
  2938.     push    ds            ; save DS for a tad
  2939.     mov    ds,ax            ; now we have the segment pointer
  2940.     rep    movsw            ; move them
  2941.     pop    ds            ; restore DS
  2942.     pop    cx            ; restore the line count
  2943.     push    di            ; save around update call
  2944.     call    scrsync            ; synch Topview
  2945.     pop    di
  2946.     pop    ax            ; restore the buffer counter
  2947.     loop    getcir1            ; go back for more
  2948.     call    scron            ; turn the screen back on
  2949.     pop    es            ; restore ES
  2950. getcir3:ret
  2951. getcirc    endp
  2952.  
  2953. ;
  2954. ; CHKDSP - procedure to check for hardware support of 132 cols [dlk]
  2955. ;
  2956. ;  Supported hardware: EVA board from Tseng Labs w/132-col kit installed
  2957. ;        Tseng Labs UltraPAK mono/Herc board w/132 column modes.
  2958. ;        Video 7 Vega Deluxe w/ 132X25.COM driver installed [tmk]
  2959. ;        and VGA board, ATI EGA Wonder, Everex ev-659 and fvga-673.
  2960. ; The routine checks for the presence of a 132-column-capable adapter. If
  2961. ; one is found its handler executes the desired mode setting and returns
  2962. ; carry clear; it returns carry set otherwise.
  2963. ; Adding new boards - place an identification string in the data segment,
  2964. ; construct a mode setting routine and insert it in the call list below
  2965. ; (setting 132 column mode is byte ptr temp non-zero).
  2966. ;
  2967. chgdsp    proc    near
  2968.     push    es            ; save all we use
  2969.     push    ax
  2970.     push    bx
  2971.     push    cx
  2972.     push    dx
  2973.     push    si
  2974.     push    di
  2975.     mov    temp,ax            ; save set/reset flag from msz
  2976.     cmp    crt_cols,80        ; are we narrow?
  2977.     jbe    chgds3            ; be = narrow width now
  2978.     cmp    al,0            ; resetting to narrow width?
  2979.     je    chgds4            ; e = yes, do it
  2980.     jmp    chgdsx1            ; else we are there now
  2981. chgds3:    cmp    al,0            ; resetting to narrow width?
  2982.     je    chgdsx1            ; e = yes, we are there now
  2983. chgds4:    mov    ah,flowoff        ; get xoff
  2984.     cmp    ah,0            ; flow control?
  2985.     je    chgds0            ; e = none
  2986.     call    outchr            ; send it
  2987.     call    savescr            ; save current screen
  2988.     mov    ax,500            ; wait 500 millisec before video tests
  2989.     call    pcwait            ; so don't mix screen and port intrpts
  2990.  
  2991. chgds0:    call    ckteva            ; try Tseng Labs EVA
  2992.     jnc    chgds1            ; nc = found
  2993.     call    ckstbv            ; try STB VEGA/EM
  2994.     jnc    chgds1            ; nc = found
  2995.     call    ckv7vd            ; try Video 7 EGA Deluxe and VGA
  2996.     jnc    chgds1            ; nc = found
  2997.     call    ckatiw            ; try ATI EGA Wonder
  2998.     jnc    chgds1            ; nc = found
  2999.     call    ckevrx                  ; try Everex Micro Enhancer Deluxe
  3000.     jnc     chgds1                  ; nc = found
  3001.     call    ckevga            ; try Everex EVGA-673
  3002.     jnc     chgds1                  ; nc = found
  3003.     call    ckatt            ; ATT boards
  3004.     jnc    chgds1            ; nc = not found
  3005.     mov    si,offset cols80    ; name of 80 column file
  3006.     cmp    byte ptr temp,0        ; setting 80 cols?
  3007.     je    chgdsx2            ; e = yes
  3008.     mov    si,offset cols132    ; use 132 column file
  3009. chgdsx2:mov    di,offset dumpbuf    ; a temp buffer for path= usage
  3010.     call    strcpy
  3011.     mov    ax,di            ; spath wants ptr in ax
  3012.     call    spath
  3013.     jc    chgdsx            ; c = file not found
  3014.     mov    si,ax            ; crun wants ptr in si
  3015.     call    crun            ; run the batch file, si = filespec
  3016.     call    serini            ; reengage serial port, mode changes
  3017.                     ; Perform mode change
  3018. chgds1:    cmp    flags.modflg,1        ; is mode line enabled?
  3019.     jbe    chgds2            ; be = yes, and off or locally owned
  3020.     mov    flags.modflg,1        ; remove foreign ownership
  3021. chgds2:    call    scrini            ; reset parameters
  3022. chgdsx:    mov    ah,flowon        ; get flowon byte
  3023.     cmp    ah,0            ; using flow control?
  3024.     je    chgdsx1            ; e = no
  3025.     call    outchr            ; send it
  3026. chgdsx1:pop    di            ; restore what we saved
  3027.     pop    si
  3028.     pop    dx
  3029.     pop    cx
  3030.     pop    bx
  3031.     pop    ax
  3032.     pop    es
  3033.     ret                ; return to caller
  3034.      
  3035. ; Individual tests for various 132-column boards
  3036.                     ; Tseng LABS EVA and UltraPAK
  3037. ckteva: mov    ax,0c000h        ; seg addr for EVA
  3038.     mov    es,ax            ; set into es register
  3039.     mov    di,76h            ; offset of board's string
  3040.     lea    si,tsngid        ; validation string
  3041.     mov    cx,tsnglen        ; length of validiation string
  3042.     cld
  3043.     repe    cmpsb            ; compare strings
  3044.     je    ckteva2            ; e = strings match
  3045.     mov    ax,4d00h        ; check for UltraPAK mono driver
  3046.     int    screen
  3047.     cmp    ax,5aa5h        ; driver signature?
  3048.      jne    ckteva3            ; ne = no
  3049.     mov    ax,7            ; default to mono (7) for this board
  3050.     cmp    byte ptr temp,0        ; setting 132 columns?
  3051.     je    ckteva1            ; e = resetting to normal
  3052.     mov    ax,18h            ; set to 132 cols (Set Mode 18H)
  3053. ckteva1:int    screen
  3054.     clc                ; carry clear means success
  3055.     ret
  3056.                     ; an EVA board - check for 132 col kit
  3057. ckteva2:cmp    byte ptr es:099h,0    ; check 132 col kit installed
  3058.     jne    catfnd            ; ne = installed, do the mode change
  3059. ckteva3:stc                ; indicate adapter not present
  3060.     ret                ; and exit
  3061.                     ;
  3062. ckstbv:    mov    ax,0c000h        ; STB's VGA/EM and VGA/EM-16
  3063.     mov    es,ax            ;
  3064.     mov    di,70h            ; where to look for signature
  3065.     lea    si,stbvid        ; the signature
  3066.     mov    cx,stbvlen        ;
  3067.     cld                ;
  3068.     repe    cmpsb            ; test
  3069.     je    catfnd            ; e = found
  3070.     stc                ; else say not there
  3071.     ret                ;
  3072.                     ; ATI EGA Wonder
  3073. ckatiw:    mov    ax,0c000h        ; seg addr for EGA Wonder
  3074.     mov    es,ax            ; set into es register
  3075.     mov    di,012fh        ; offset of message in ROM
  3076.     lea    si,atiwid        ; offset of message here
  3077.     mov    cx,atilen        ; length of validation string
  3078.     cld
  3079.     repe    cmpsb            ; compare strings
  3080.     je    catfnd            ; e = they match
  3081.     stc                ; strings differ
  3082.     ret
  3083. catfnd:    mov    ax,0003h        ; prepare to reset video mode
  3084.     cmp    byte ptr temp,0        ; are we setting or resetting?
  3085.     je    catfnd1            ; e is reset, exit
  3086.     mov    ax,0023h        ; set to 132 cols (Set Mode 23H)
  3087. catfnd1:int    screen
  3088.     clc                ; carry clear means success
  3089.     ret
  3090.                     ; Video 7 Vega Deluxe
  3091. ckv7vd:    mov    ax,0c000h        ; seg addr for Vega rom bios
  3092.     mov    es,ax            ; set into es register
  3093.     mov    di,002ah        ; offset of message in ROM
  3094.     lea    si,vid7id        ; offset of message here
  3095.     mov    cx,vid7len
  3096.     cld
  3097.     repe    cmpsb            ; compare strings
  3098.     je    cnv7fn1            ; e = same
  3099.     mov    di,002ah        ; offset of ident string
  3100.     mov    si,offset vid7id2    ; Video 7 VGA board
  3101.     mov    cx,vid7len2
  3102.     repe    cmpsb
  3103.     je    cnv7fn2            ; e = found
  3104. cnv7fx:    stc                ; strings are different
  3105.     ret
  3106.                     ;
  3107. cnv7fn1:test    byte ptr es:[03ffeh],1    ; is this a 'Deluxe' Vega?
  3108.     jz    cnv7fx            ; z = nope, can't do it
  3109.     mov    ah,35h            ; DOS Get Vector
  3110.     mov    al,10h            ; Bios video interrupt
  3111.     int    dos            ; get it into es:bx
  3112.     mov    di,bx            ; es:bx is returned int 10h entry pnt
  3113.     sub    di,5ah            ; back offset to msg in 132X25.COM
  3114.     lea    si,vid7id        ; offset of validation message
  3115.     mov    cx,vid7len        ; length of validation string
  3116.     cld
  3117.     repe    cmpsb            ; Look for repeat of msg by 132X25.COM
  3118.     jne    cnv7fn2            ; if different
  3119.     mov    al,crt_mode        ; prepare to reset video mode
  3120.     xor    ah,ah
  3121.     cmp    byte ptr temp,0        ; are we setting or resetting?
  3122.     je    cnv7fn2a        ; e is reset
  3123.     mov    ax,0000h        ; set to 132 cols (old 40x25)
  3124. cnv7fn1a:int    screen
  3125.     clc
  3126.     ret
  3127.  
  3128. cnv7fn2:mov    ax,6f00h        ; check for VegaBios driver
  3129.     int    screen
  3130.     cmp    bx,'V7'            ; Video 7 Bios presence response
  3131.     jne    cnv7fx            ; ne = not there
  3132.     mov    ax,6f01h        ; al gets monitor type (mono,color,ega)
  3133.     int    screen
  3134.     mov    bx,51h            ; presume mono 132x25, page 0
  3135.     cmp    crt_lins,42        ; 43 lines active?
  3136.     jb    cnv7fn2a        ; b = no
  3137.     inc    bx            ; use bx = 52h for 132x43
  3138. cnv7fn2a:
  3139.     cmp    al,10h            ; analogue fixed freq (IBM 85xx)?
  3140.     je    cnv7fx            ; e = yes, no 132 columns
  3141.     cmp    al,2            ; 1 = mono, 2 = color, above = ega
  3142.     jb    cnv7fn3            ; b = mono or unknown
  3143.     mov    bx,4fh            ; presume med res color 132x25
  3144.     je    cnv7fn3            ; e = med res color, al = 2
  3145.     mov    bx,41h            ; ega high res 132x25, enhanced mons
  3146.     cmp    crt_lins,42        ; 43 lines active?
  3147.     jb    cnv7fn3            ; b = no
  3148.     inc    bx            ; use bx = 42h for 132x43
  3149. cnv7fn3:mov    ax,6f05h        ; set special mode found in bl
  3150.     cmp    byte ptr temp,0        ; resetting to 80 column mode?
  3151.     jne    cnv7fn4            ; ne = no, setting 132x25
  3152.     mov    al,crt_norm        ; get normal mode
  3153.     xor    ah,ah            ; set mode
  3154.     cmp    crt_lins,42        ; 43 lines active?
  3155.     jb    cnv7fn4            ; b = no
  3156.     mov    bl,40h            ; use Video 7 mode 40h 80x43 for color
  3157.     mov    ax,6f05h        ; and do special mode set
  3158. cnv7fn4:int    screen            ; special mode is in bl
  3159.     mov    ax,0f00h        ; a nop screen bios command
  3160.     int    screen
  3161.     clc
  3162.     ret
  3163.  
  3164. ckevrx: mov     ax,0c000h               ; seg addr for Everex EV-659
  3165.         mov     es,ax                   ; set into es register
  3166.         mov     di,0047h                ; offset of message in ROM
  3167.         lea     si,evrxid               ; offset of message here
  3168.         mov     cx,evrxlen              ; length of validation string
  3169.         cld
  3170.         repe    cmpsb                   ; compare strings
  3171.         jne     ckfnr2                  ; ne = strings differ
  3172.         mov     ah,crt_lins             ; we recognize either 44 or 25 rows
  3173.         cmp     ah,43                   ; equal to 44-1 rows?
  3174.         jne     ckfnr1                  ; ne = no
  3175.         mov     ax,0070h                ; Everex extended mode ident
  3176.         mov     bl,09h                  ; prepare to reset video mode to 80x44
  3177.         cmp     byte ptr temp,0         ; are we setting or resetting?
  3178.         je      ckfnr4                  ; e is reset, exit
  3179.         mov     bl,0bh                  ; 132x44
  3180.     int    screen
  3181.     clc
  3182.     ret
  3183. ckfnr1: cmp     ah,24                   ; equal to 25-1 rows?
  3184.     je    ckfnr3            ; e = yes
  3185. ckfnr2:    stc                ; return failure
  3186.     ret
  3187. ckfnr3:    mov     ax,0003h                ; prepare to reset video mode
  3188.         cmp     byte ptr temp,0         ; are we setting or resetting?
  3189.         je      ckfnr4                  ; e is reset, exit
  3190.         mov     ax,0070h                ; Everex extended mode ident
  3191.         mov     bl,0ah                  ; 132x25
  3192. ckfnr4:    int    screen
  3193.     clc
  3194.     ret
  3195. ckevga:    mov    ax,0c000h        ; Everex FVGA-673, rom segment
  3196.     mov    es,ax
  3197.     mov    di,76h            ; offset in rom for board's id string
  3198.     lea    si,evgid        ; id string
  3199.     mov    cx,evglen        ; length of id string
  3200.     cld
  3201.     repe    cmpsb            ; do they match?
  3202.     jne    ckevg2            ; ne = no
  3203.     mov    ax,3            ; prepare to reset video mode
  3204.     cmp    byte ptr temp,0        ; setting or resetting mode?
  3205.     je    ckevg1            ; e = resetting, exit
  3206.     mov    ax,0070h        ; mode for 132x25
  3207.     mov    bl,0ah            ; Everex mode 0ah
  3208. ckevg1:    int    screen
  3209.     clc
  3210.     ret
  3211. ckevg2:    stc                ; say board not found
  3212.     ret
  3213.                     ; AT&T EGA/VGA boards
  3214. ckatt:    mov    ax,0c000h        ; seg of first signature
  3215.     mov    es,ax
  3216.     mov    si,offset attvdc6    ; first pattern
  3217.     mov    di,35h            ; test area
  3218.     cld
  3219.     mov    cx,attvdlen        ; length
  3220.     repe    cmpsb
  3221.     je    ckatt2            ; e = found
  3222.     mov    cx,attvdlen        ; try second signature, same length
  3223.     mov    si,offset attvdc7
  3224.     mov    ax,0e000h        ; seg of second signature
  3225.     mov    es,ax
  3226.     mov    di,10h            ; test area
  3227.     repe    cmpsb
  3228.     je    ckatt2            ; e = found
  3229.     stc                ; not found
  3230.     ret
  3231. ckatt2:    mov    al,crt_norm        ; old mode
  3232.     xor    ah,ah
  3233.     cmp    byte ptr temp,0        ; resetting to 80 col?
  3234.     je    ckatt3            ; e = yes
  3235.     mov    ax,0055h        ; 132 cols, set mode 55h
  3236. ckatt3:    int    screen
  3237.     clc
  3238.     ret
  3239. chgdsp    endp
  3240.  
  3241. ; Character write/read and cursor manipulation routines for terminal emulator
  3242. ; All registers other than returned values are preserved.
  3243.  
  3244. ; Read char and attributes under cursor.
  3245. ; Returns AL = character, AH = video attributes
  3246. getatch    proc    near
  3247.     push    bx
  3248.     mov    ah,8            ; read char and attributes
  3249.     xor    bh,bh            ; page 0
  3250.     int    screen            ; Bios video call
  3251.     pop    bx
  3252.     ret
  3253. getatch    endp
  3254.  
  3255. ; Read cursor position
  3256. ; DH = column, DL = row, both counted from 0,0 at upper left corner
  3257. getpos    proc    near
  3258.     push    ax
  3259.     push    bx
  3260.     mov    ah,3            ; get cursor position
  3261.     xor    bh,bh            ; page 0
  3262.     int    screen
  3263.     pop    bx
  3264.     pop    ax
  3265.     ret
  3266. getpos    endp
  3267.  
  3268. ; Set cursor postion
  3269. ; DH = column, DL = row, both counted from 0,0 at upper left corner
  3270. setpos    proc    near
  3271.     push    ax
  3272.     push    bx
  3273.     mov    ah,2            ; set cursor
  3274.     xor    bh,bh            ; page 0
  3275.     int    screen
  3276.     pop    bx
  3277.     pop    ax
  3278.     ret
  3279. setpos    endp
  3280.  
  3281. ; Write char and attribute to screen at cursor position, do not move cursor.
  3282. ; AL = char, AH = video attribute
  3283. setatch    proc    near
  3284.     push    ax
  3285.     push    bx
  3286.     push    cx
  3287.     mov    cx,1            ; one char
  3288.     mov    bl,ah            ; attribute
  3289.     xor    bh,bh            ; page 0
  3290.     mov    ah,9            ; write char, do not move cursor
  3291.     int    screen
  3292.     pop    cx
  3293.     pop    bx
  3294.     pop    ax
  3295.     ret
  3296. setatch    endp
  3297.  
  3298. ; Write char to screen at cursor position, move cursor, use current attributes
  3299. ; AL = char.
  3300. putchar proc    near
  3301.     push    ax
  3302.     push    bx
  3303.     mov    ah,0eh            ; write char, increment cursor
  3304.     xor    bh,bh            ; page 0
  3305.     int    screen
  3306.     pop    bx
  3307.     pop    ax
  3308.     ret
  3309. putchar    endp
  3310.  
  3311. ; Get bold video attribute bit
  3312. ; Enter with AH = video attribute byte, returns AH = bold attribute bit
  3313. getbold    proc    near
  3314.     and    ah,att_intensity    ; select bold bit
  3315.     xor    ah,userbold        ; invert with user bold
  3316.     ret
  3317. getbold endp
  3318.  
  3319. ; Set bold video attribute bit
  3320. ; Enter with AH = video attribute byte
  3321. setbold proc    near
  3322.     or    ah,att_intensity    ; set bold bit
  3323.     xor    ah,userbold        ; invert with user bold
  3324.     ret
  3325. setbold endp
  3326.  
  3327. ; Clear bold video attribute bit
  3328. ; Enter with AH = video attribute byte, returns new attribute byte in AH
  3329. clrbold    proc    near
  3330.     and    ah,not att_intensity    ; clear bold bit
  3331.     or    ah,userbold        ; invert with user bold
  3332.     ret
  3333. clrbold    endp
  3334.  
  3335. ; Get blink video attribute bit
  3336. ; Enter with AH = video attribute byte, returns AH = blink attribute bit
  3337. getblink proc    near
  3338.     and    ah,att_blink        ; get blink bit
  3339.     ret
  3340. getblink endp
  3341.  
  3342. ; Set blink video attribute bit
  3343. ; Enter with AH = video attribute byte
  3344. setblink proc    near
  3345.     or    ah,att_blink        ; set blink bit
  3346.     ret
  3347. setblink endp
  3348.  
  3349. ; Clear blink video attribute bit
  3350. ; Enter with AH = video attribute byte, returns new attribute byte in AH
  3351. clrblink proc    near
  3352.     and    ah,not att_blink    ; clear blink bit
  3353.     ret
  3354. clrblink endp
  3355.  
  3356. ; Get underline video attribute bit
  3357. ; Enter with AH = video attribute byte, returns AH = underline attribute bit
  3358. getunder proc    near
  3359.     ret
  3360. getunder endp
  3361.  
  3362. ; Set underline video attribute bit
  3363. ; Enter with AH = video attribute byte, video_state (0=normal)
  3364. ; Return AH holding new attribute byte, new video_state.
  3365. setunder proc    near
  3366.     cmp    crt_mode,7        ; monochrome display adapter mode?
  3367.     je    setund2            ; e = yes, otherwise reverse video
  3368.     jmp    setrev
  3369. setund2:call    brkatt            ; break apart attributes
  3370.     or    al,att_underline    ; set underline bit
  3371.     call    addatt            ; reassemble attributes
  3372.     ret
  3373. setunder endp
  3374.  
  3375. ; Clear underline video attribute bit
  3376. ; Enter with AH = video attribute byte, returns new attribute byte in AH and
  3377. ; new video_state.
  3378. clrunder proc    near
  3379.     cmp    crt_mode,7        ; monochrome display adapter mode?
  3380.     je    clrund2            ; e = yes, otherwise reverse video
  3381.     jmp    clrrev
  3382. clrund2:call    brkatt            ; break apart attributes
  3383.     and    al,not att_underline    ; turn off underline bit
  3384.     call    addatt            ; reassemble attributes
  3385.     ret
  3386. clrunder endp
  3387.  
  3388. setrev    proc    near
  3389.     cmp    video_state,0        ; normal video
  3390.     jne    setrev1            ; ne = no, reversed already
  3391.     call    revideo            ; do reversal
  3392.     mov    video_state,1        ; say reversed
  3393. setrev1:ret
  3394. setrev    endp
  3395.  
  3396. clrrev    proc    near
  3397.     cmp    video_state,0        ; normal video?
  3398.     je    clrrev1            ; e = yes
  3399.     call    revideo            ; do reversal
  3400.     mov    video_state,0        ; say normal
  3401. clrrev1:ret
  3402. clrrev    endp
  3403.  
  3404.  
  3405. ; Compute reversed video attribute byte. Normally preserves blink/bold.
  3406. ; Enter with AH = video attribute byte, returns new attribute byte in AH
  3407. revideo    proc    near
  3408.     call    brkatt            ; separate colors from blink/bold
  3409.     rol    ah,1            ; reverse foreground & background
  3410.     rol    ah,1            ; RGB bits
  3411.     rol    ah,1
  3412.     rol    ah,1
  3413.     call    addatt            ; reinsert bold/blink bits
  3414.     ret
  3415. revideo    endp
  3416.  
  3417. ; This routine picks an attribute apart into its component "parts" - the
  3418. ; base attribute for the screen and the "extras" - i.e., blink, intensity
  3419. ; and underline.
  3420. ; enter with    ah = a cursor attribute
  3421. ; return    ah = base attribute for screen (07H normal, 70H reverse).
  3422. ;        al = "extra" attributes
  3423. ; Note that there is a complementary routine, addatt, for putting attributes
  3424. ; back together.
  3425.  
  3426. brkatt: xor    al,al            ; Clear returned "extra" attributes
  3427.     test    ah,att_intensity    ; intensity attribute on?
  3428.     jz    brkat3            ; z = no, check blink
  3429.     or    al,att_intensity    ; set intensity
  3430. brkat3: test    ah,att_blink        ; blink on?
  3431.     jz    brkat4            ; z = no
  3432.     or    al,att_blink        ; set blink
  3433. brkat4:    and    ah,not(att_intensity+att_blink)    ;strip blink/bold, leave color
  3434.     cmp    crt_mode,7        ; monochrome display adapter mode?
  3435.     jne    brkat2            ; ne = no, cut this short for color
  3436.     test    ah,att_low_mask        ; are any of these on?
  3437.     jnz    brkat1            ; nz = yes, can't be underline
  3438.     test    ah,att_underline    ; underline?
  3439.     jz    brkat2            ; z = no, some kind of reverse video
  3440.     or    al,att_underline    ; say underline
  3441.     test    ah,70h ;;att_reverse    ; reverse video + underline?
  3442.     jz    brkat1            ; z = no, fix up low nibble
  3443.     and    ah,not att_underline    ; clear the underline bit in ah
  3444.     ret
  3445. brkat1: or    ah,att_normal        ; normal, turn on all normal bits
  3446. brkat2:    ret
  3447.  
  3448. ; This routine builds a cursor attribute given the base attribute for the
  3449. ; screen background and the "extra" attributes we want (blink, etc.).
  3450. ; enter with    ah = base attribute for background (07H or 70H)
  3451. ;        al = "extra" attributes (89H for all three)
  3452. ; return    ah = base combined with "extras".
  3453.  
  3454. addatt: test    al,att_underline    ; want underline?
  3455.     jz    addat1            ; z = no, no need for hack
  3456.     and    ah,not att_low_mask    ; clear background colors
  3457. addat1: or    ah,al            ; Or in the attributes
  3458.     ret
  3459.  
  3460.  
  3461. ; This routine is called when we want to reverse everything on the screen
  3462. ; from normal to reverse video, or vice versa.    It is called only when
  3463. ; the decscnm attribute is changed.
  3464. ; Call:        no arguments.
  3465.  
  3466. revscn    proc    near
  3467.     push    ax
  3468.     push    bx
  3469.     push    cx
  3470.     push    dx
  3471.     mov    dh,byte ptr low_rgt+1    ; Compute last screen offset in ax
  3472.     inc    dh            ; One more row to catch mode line
  3473.     mov    dl,crt_cols        ; physical width
  3474.     dec    dl            ; and we count from 0
  3475.     call    scrloc            ; get screen offset into ax
  3476.     mov    cx,ax            ; Save it in cx for a minute
  3477.     add    cx,2
  3478.     sar    cx,1            ; In 16-bit words please
  3479.     push    di            ; Save some more acs
  3480.     push    es
  3481.     push    cx            ; save word count for Topview
  3482.     mov    ax,tv_segs        ; Get address of screen in ax, es:di
  3483.     mov    es,ax
  3484.     xor    di,di
  3485.     call    scroff            ; Turn screen off if color card
  3486.     cld
  3487. revsc1: mov    ax,es:[di]        ; Fetch a word
  3488.     mov    bl,al            ; Save the character
  3489.     call    revideo            ; get reversed video attributes (AH)
  3490.     call    addatt            ; Put attributes back together
  3491.     mov    al,bl            ; Restore character
  3492.     stosw                ; Stuff into screen memory
  3493.     loop    revsc1            ; Loop for entire screen
  3494.     pop    cx            ; recover word count for Topview
  3495.     call    scrsync            ; synch with Topview
  3496.     call    scron            ; Turn screen back on if color card
  3497.     pop    es            ; Restore segment register
  3498.     pop    di            ; And destination index
  3499.     pop    dx
  3500.     pop    cx
  3501.     pop    bx
  3502.     pop    ax
  3503.     ret
  3504. revscn    endp
  3505.  
  3506. ; IBM PC worker for insert/delete cx characters at and including cursor.
  3507. ; dh= logical cursor row, dl= logical cursor column,
  3508. ; cx has character repeat count, bl = logical screen width-1,
  3509. ; bh = +1 for insert, -1 for delete chars.
  3510. ; Double width lines have cx and dl doubled by our caller. Writing right to
  3511. ; left is managed here.
  3512. insdecom proc    near
  3513.     push    es
  3514.     push    ax
  3515.     push    cx
  3516.     push    dx
  3517.     push    si
  3518.     push    di
  3519.     mov    temp,0            ; worker temp
  3520.     mov    skip,cx            ; number of chars to insert/delete
  3521.     call    scrseg            ; pick up screen segment in es:di,ax
  3522.            test    vtemu.vtflgop,vswdir    ; writing left to right?
  3523.     jz    insdec1            ; z = yes, no changes needed
  3524.     sub    dl,bl            ; logical to physical cursor position
  3525.     neg    dl            ; make dl positive again
  3526.     xor    bl,bl            ; right-to-left, edge is left margin
  3527.                     ; bl is now logical eol
  3528. insdec1:mov    cl,dl            ; physical cursor dl saved here
  3529.     cmp    bh,0            ; insert?
  3530.     jl    insdec2            ; l = no, leave dl at cursor column
  3531.     mov    dl,bl            ; insert uses logical end of line
  3532. insdec2:call    scrloc            ; ax = offset in regen buffer
  3533.     add    di,ax            ; es:di = destination so far
  3534.     mov    si,di            ; align source to be same place
  3535.     cmp    bh,0            ; inserting?
  3536.     jge    insdec4            ; ge = yes
  3537.     test    vtemu.vtflgop,vswdir    ; writing right to left?
  3538.     jnz    insdec4a        ; nz = yes
  3539. insdec3:add    si,skip            ; delete
  3540.     add    si,skip
  3541.     mov    byte ptr temp+1,0    ; remember direction here as 0=cld
  3542.     cld
  3543.     jmp    short insdec5
  3544. insdec4:test    vtemu.vtflgop,vswdir    ; insert, writing right to left?
  3545.     jnz    insdec3            ; nz = yes
  3546. insdec4a:sub    si,skip
  3547.     sub    si,skip
  3548.     mov    byte ptr temp+1,0    ; remember direction here as 1=std
  3549.     std
  3550.  
  3551. insdec5:call    scroff            ; video off
  3552.     xor    ch,ch
  3553.     sub    cl,bl            ; cursor - margin
  3554.     jnc    insdec6            ; nc = non-negative
  3555.     neg    cl            ; make positive
  3556. insdec6:inc    cx            ; include cursor location too
  3557.     sub    cx,skip            ; cx = number chars to be moved
  3558.     jle    insdec7            ; le = none, just write spaces
  3559.     mov    byte ptr temp,cl    ; number of chars modified
  3560.     push    ds
  3561.     push    es
  3562.     pop    ds
  3563.     rep    movsw            ; mov cx chars from es:[si] to es:[di]
  3564.     pop    ds
  3565. insdec7:mov    cx,skip            ; number chars skipped
  3566.     jcxz    insdec8            ; z = none
  3567.     add    byte ptr temp,cl    ; number chars modified
  3568.     mov    al,' '            ; get fill pattern
  3569.     mov    ah,scbattr        ; attribute
  3570.     rep    stosw            ; fill at the end
  3571. insdec8:cld                ; restore direction flag
  3572.     call    scron            ; video back on for CGA screens
  3573.     mov    cl,byte ptr temp    ; number of char cells touched
  3574.     xor    ch,ch
  3575.     cmp    byte ptr temp+1,0    ; was Direction bit set?
  3576.     je    insdec9            ; e = no
  3577.     add    di,cx            ; make di be its highest value
  3578. insdec9:call    scrsync            ; synch Topview
  3579.     pop    di
  3580.     pop    si
  3581.     pop    dx
  3582.     pop    cx
  3583.     pop    ax
  3584.     pop    es
  3585.     ret
  3586. insdecom endp
  3587.  
  3588. ; Set coloring attributes.
  3589. ; Enter with AH holding current video attribute byte,
  3590. ; BL holding ANSI color code (30-37 or 40-47) where 30's are foreground,
  3591. ; 40's are background. ANSI colors are 1 = red, 2 = green, 4 = blue.
  3592. ; Return new attribute byte in AH.
  3593.  
  3594. setcolor proc    near
  3595.     cmp    video_state,0        ; normal video currently?
  3596.     je    setcol0            ; e = yes
  3597.     mov    al,ah            ; make a copy
  3598.     and    ax,7788h        ; strip bold,blink, keep both in al
  3599.     rol    ah,1            ; get colors in right parts
  3600.     rol    ah,1            ;  of ah = back, al = foreground
  3601.     rol    ah,1
  3602.     rol    ah,1
  3603.     call    setcol0            ; set fore or background color
  3604.     rol    ah,1            ; reverse coloring again
  3605.     rol    ah,1
  3606.     rol    ah,1
  3607.     rol    ah,1
  3608.     or    ah,al            ; put back blink and bold
  3609.     ret
  3610.  
  3611. setcol0:    cmp    bl,30            ; ANSI color series?
  3612.     jb    setcol7            ; b = no
  3613.     cmp    bl,37            ; foreground set (30-37)?
  3614.     ja    setcol4            ; a = no, try background set
  3615.     sub    bl,30            ; take away the bias
  3616.     and    ah,not 07H        ; clear foreground bits
  3617.     test    bl,1            ; ANSI red?
  3618.     jz    setcol1            ; z = no
  3619.     or    ah,4            ; IBM red foreground bit
  3620. setcol1:test    bl,2            ; ANSI & IBM green?
  3621.     jz    setcol2            ; z = no
  3622.     or    ah,2            ; IBM green foreground bit
  3623. setcol2:test    bl,4            ; ANSI blue?
  3624.     jz    setcol3            ; z = no
  3625.     or    ah,1            ; IBM blue foreground bit
  3626. setcol3:ret
  3627.  
  3628. setcol4:cmp    bl,40            ; background color set?
  3629.     jb    setcol7            ; b = no
  3630.     cmp    bl,47            ; background set is 40-47
  3631.     ja    setcol7            ; nb = no, not a color command
  3632.     sub    bl,40            ; take away the bias
  3633.     and    ah,not 70H        ; clear background bits
  3634.     test    bl,1            ; ANSI red?
  3635.     jz    setcol5            ; z = no
  3636.     or    ah,40h            ; IBM red background bit
  3637. setcol5:test    bl,2            ; ANSI & IBM green?
  3638.     jz    setcol6            ; z = no
  3639.     or    ah,20h            ; IBM green background bit
  3640. setcol6:test    bl,4            ; ANSI blue?
  3641.     jz    setcol7            ; z = no
  3642.     or    ah,10h            ; IBM blue background bit
  3643. setcol7:ret
  3644. setcolor endp
  3645.  
  3646. ; Routine to do keyclick if flag is set, no arguments
  3647. vclick    proc    near
  3648.     test    vtemu.vtflgop,vskeyclick ; is keyclick flag on?
  3649.     jz    vclick1            ; z = no, just return
  3650.     push    bx
  3651.     push    di
  3652.     mov    di,500            ; 500 Hertz
  3653.     mov    bx,1            ; For 1 millisecond
  3654.     call    vtsound            ; Do it
  3655.     pop    di            ; Restore the ACs
  3656.     pop    bx
  3657. vclick1:ret
  3658. vclick    endp
  3659.  
  3660. ; Routine to do VT100-style bell, no arguments
  3661. vtbell    proc    near
  3662.     cmp    belltype,1        ; visual bell?
  3663.     je    vtbell1            ; e = yes
  3664.     push    di
  3665.     push    bx
  3666.     mov    di,880            ; 880 Hertz
  3667.     mov    bx,40            ; For 40 ms
  3668.     call    vtsound            ; Do it
  3669.     pop    bx
  3670.     pop    di
  3671.     ret
  3672. vtbell1:call    revscn            ; reverse screen
  3673.     push    ax
  3674.     mov    ax,40            ; for 40 milliseconds
  3675.     call    pcwait
  3676.     pop    ax
  3677.     call    revscn            ; put back
  3678.     ret
  3679. vtbell    endp
  3680.  
  3681. ; Routine to make noise of arbitrary frequency for arbitrary duration.
  3682. ; Similar to routine (with typo removed) in "IBM PC Assembly Language:
  3683. ; A Guide for Programmers", Leo J. Scanlon, 1983 Robert J. Brady Co.,
  3684. ; Bowie, MD., page 270. Modified by J R Doupnik to use 0.1 millsec interval.
  3685. ; Call:        di/    frequency in Hertz.
  3686. ;        bx/    duration in 1 millisecond units
  3687. vtsound proc    near
  3688.     push    ax            ; save regs
  3689.     push    cx
  3690.     push    dx
  3691.     mov    al,0B6H            ; write timer mode register
  3692.     out    43H,al
  3693.     mov    dx,14H            ; timer divisor is
  3694.     mov    ax,4F38H        ; 1331000/frequency
  3695.     div    di
  3696.     out    42H,al            ; write timer 2 count low byte
  3697.     mov    al,ah
  3698.     out    42H,al            ; write timer 2 count high byte
  3699.     in    al,61H            ; get current port B setting
  3700.     or    al,3            ; turn speaker on
  3701.     out    61H,al
  3702.     mov    ax,bx            ; number of milliseconds to wait
  3703.     call    pcwait            ; do the calibrated wait
  3704.     in    al,61H            ; get current port B setting
  3705.     and    al,0fch            ; turn off speaker and timer
  3706.     out    61H,al
  3707.     pop    dx            ; restore regs
  3708.     pop    cx
  3709.     pop    ax
  3710.     ret
  3711. vtsound endp
  3712. code    ends
  3713.     end
  3714.