home *** CD-ROM | disk | FTP | other *** search
/ Columbia Kermit / kermit.zip / archives / msr313src.zip / msyibm.asm < prev    next >
Assembly Source File  |  1993-07-12  |  215KB  |  7,106 lines

  1.     NAME msyibm
  2. ; File MSYIBM.ASM
  3.     include mssdef.h
  4. ;       Copyright (C) 1982,1993, Trustees of Columbia University in the
  5. ;       City of New York.  Permission is granted to any individual or
  6. ;       institution to use, copy, or redistribute this software as long as
  7. ;       it is not sold for profit and this copyright notice is retained.
  8. ; edit history:
  9. ; 6 Sept 1991 version 3.11
  10. ; Last edit 9 June 1993
  11. ; 9 May 1993 Add test for Japanese DOS and if present avoid Int 15h. Presence
  12. ;  is held in tv_mode bit 20h.
  13. ; 12 April 1993 apply 5 dot compressed font (compressed text) to VT emulators
  14. ;  via option SET TERM COMPRESS GRAPHICS
  15. ; 14 Jan 1993 Add expanded memory usage for screen rollback buffer
  16. ; 25 June 1992 Multiple TCP/IP session support, revise segmenting, virtual
  17. ;  screens, horizontal scrolling, Connect mode macro at entry, DG support.
  18. ; 23 Dec 1990 Add Bert Tyler's (NIH) IBM XGA 132 column code.
  19. ; 9 May 1989 Add Bert Tyler's (NIH) new screen rollback routines.
  20. ; 21 Jan 1989 be more tolerate of propriatary video modes above 18 when
  21. ;  determining screen segment, Tnx to Terry Kennedy. Add check for IBM
  22. ;  85xx monitors on Video 7 boards, no 132 columns if it is the monitor.
  23. ;  Retain 43 rows on Video 7 boards.
  24. ; 30 Nov 1988 Add SET TERM CLEAR screen clearing support.
  25. ; 28 Nov 1988 Accomodate Tseng Labs UltraPAK mono/Herc board w/132 cols.
  26. ;  132 column mode is 18h. Requires Tseng's BIGSCR.COM (use BIGSCR /R:25
  27. ;  to enable 132x25 feature). Thanks to Tseng Labs for technical support.
  28. ; 21 Nov 1988 Version 2.32
  29. ; 14 Nov 1988 Write a space during lclini to obtain default screen colors.
  30. ; 12 Nov 1988 Add procs vtrmac and vtsmac to allow exit from Connect mode and
  31. ;  invokation of macros TERMINALR and TERMINALS by reception of escape seqs
  32. ;  in file mszibm.asm or by keyboard verbs.
  33. ; 7 Oct 1988 Reverse left/right arrow key codes when writing right to left.
  34. ; 24 Sept 1988 Make output to printer be buffered and flow controlled.
  35. ; 1 July 1988 Version 2.31
  36. ; 19 June 1988 Add Everex EVGA support, from Terry Kennedy.
  37. ; 10 June 1988 Add oldsp and procedure endcon to exit Connect mode if output
  38. ;  fails, mostly for networking (but we don't know that here).
  39. ; 23 May 1988 Add Everex EV-659 ega board test from Alex Zliu. Fixed incorrect
  40. ;  screen width assumption at startup.
  41. ; 29 March 1988 Include flag ttyact to group string bytes into one net packet,
  42. ;  thanks to Paul Fox of AT&T.
  43. ; 23 March 1988 Add "fairness" word to let serial port deliver max chars
  44. ;  between kbd reads, for connect mode only. [jrd]
  45. ; 10 Feb 1988 Revise getcirc and vtscrX routines to do proper scrolling with
  46. ;  MS Window 1.0x/2.0x [jrd].
  47. ; 9 Feb 1988 Mode line again. Make flags.modflg 0 for off, 1 for on and owned
  48. ;  by Kermit, and 2 for on and owned by remote host (toggling suppressed).
  49. ; 25 Jan 1988 Add global byte SCROLL, set in msz, to control emulator screen
  50. ;  scrolling for higher speeds. [jrd]
  51. ; 5 Jan 1988 Restore cursor codes broken by Tek code additions. [jrd]
  52. ; 1 Jan 1988 version 2.30
  53.  
  54.     public    term, lclyini, termswapout, termswapin, termswapdel
  55.     public    prtbout, prtnout, csrtype, fcsrtype, scrseg
  56.     public    atsclr, vtscru, vtscrd, trnmod, vclick, vtbell
  57.     public    chgdsp, vtroll, crt_lins, crt_cols, tv_mode, vtclear
  58.             ; action verb procedures for keyboard translator
  59.     public    uparrw, dnarrw, rtarr, lfarr, pf1, pf2, pf3, pf4
  60.     public    kp0, kp1, kp2, kp3, kp4, kp5, kp6, kp7, kp8, kp9
  61.     public    kpminus, kpcoma, kpenter, kpdot, chrout, cstatus, cquit
  62.     public    cquery, dmpscn,    vtans52, vtinit, dnwpg, upwpg, endwnd, homwnd
  63.     public    upone, dnone, trnprs, dumpscr, modlin, snull, ignore_key
  64.     public    klogon, klogof, cdos, chang, khold, product
  65.     public    vtksmac, vtkrmac, apcmacro, apcenable, vtenqenable
  66.     public    decf6,decf7,decf8,decf9,decf10,decf11,decf12,decf13,decf14
  67.     public    dechelp,decdo,decf17,decf18,decf19,decf20, udkclear
  68.     public    decfind, decinsert, decremove, decselect, decprev
  69.     public    decnext, setudk, extmacro, vtmacname, vtmaclen
  70.     public    rtone, lfone, rtpage, lfpage, kbdcompose
  71.     public    dgkc1,dgkc2,dgkc3,dgkc4,dgkf1,dgkf2,dgkf3,dgkf4,dgkf5
  72.     public    dgkf6,dgkf7,dgkf8,dgkf9,dgkf10,dgkf11,dgkf12,dgkf13
  73.     public    dgkf14,dgkf15, dgpoint, dgnckey
  74.  
  75.     public    vtemu, crt_mode, scbattr, refresh, low_rgt    ; data
  76.     public    setchtab, ftogmod, extattr, vtcpage
  77.     public    setpos, getatch, setatch, yflags
  78.     public    getbold, setbold, clrbold, getblink, setblink, clrblink
  79.     public    getunder, setunder, clrunder, revideo, revscn, setcolor
  80.     public    setrev, clrrev, frepaint, touchup
  81.     public    vts, vtstat, termtb, modbuf        ; terminal emulation
  82.     public    nextses, vtinited, setprot, clrprot, qsetatch
  83.     public    dgsettek
  84.  
  85. ; some definitions
  86. SIchar    equ    0fh
  87. SOchar    equ    0eh
  88. DGescape equ    1eh
  89.  
  90. ; hardware
  91. crt_status equ    3dah            ; CGA crt status port
  92. disp_enb equ    8            ; CGA display enable bit
  93. crtmset    equ    3D8H            ; CGA CRT mode set port
  94. screen    equ    10h            ; Bios screen interrupt
  95.  
  96. emsint    equ    67h            ; EMS interrupt
  97. xmspresent equ    4300h            ; EMS presence check for XMS mgr
  98. emsmgrstat equ    40h            ; EMS get manager status
  99. emsgetseg equ    41h            ; EMS get segment of page frame
  100. emsgetnpgs equ    42h            ; EMS get number free pages
  101. emsalloc equ    43h            ; EMS get handle and allocate memory
  102. emsmapmem equ    44h            ; EMS map memory
  103. emsrelease equ    45h            ; EMS release mapped memory
  104. emsgetver equ    46h            ; EMS get version number
  105. emssetname equ    5301h            ; EMS LIM 4, set name
  106.  
  107. att_bold    equ    08h        ; bold        in main video word
  108. att_blink    equ    80h        ; blinking    in main video word
  109. att_intensity    equ    08H
  110. att_protect    equ    01h        ; protected    in vsatt
  111. att_uline    equ    02h        ; underscored    in vsatt
  112. att_rev        equ    04h        ; reversed video  in vsatt
  113.  
  114. att_low_mask    equ    06H        ; Various attribute-related equates
  115. att_normal    equ    07h
  116. att_underline    equ    01H        ; for mono monitors, in video word
  117.  
  118. modfrm    struc                ; format of mode (status) line
  119.     db    'Esc-chr: '        ; do not write in last column
  120. m_echr    db    2 dup (' ')
  121.     db    '  help: '
  122. m_hlp    db    2 dup (' ')
  123.     db    '?  port:'
  124. m_prt    db    1 dup (' ')
  125.     db    ' speed:'
  126. m_baud    db    6 dup (' ')
  127.     db    'parity:'
  128. m_par    db    4 dup (' ')
  129.     db    ' echo:'
  130. m_echo    db    3 dup (' ')
  131. m_term    db    13 dup (' ')        ; 13 bytes for term type
  132. m_prn    db    3 dup (' ')        ; show PRN when printer is on
  133. m_comp    db    ' '            ; Compose indicator
  134.     db    '$'            ; terminator
  135. modfrm    ends
  136.  
  137. ; structure for status information table sttab.
  138. stent    struc
  139. sttyp    dw    ?        ; type (actually routine to call)
  140. msg    dw    ?        ; message to print
  141. val2    dw    ?        ; needed value: another message, or tbl addr
  142. tstcel    dw    ?        ; address of cell to test, in data segment
  143. basval    dw    0        ; base value, if non-zero
  144. stent    ends
  145.  
  146.  
  147. data    segment
  148.     extrn    flags:byte, mar_top:byte, mar_bot:byte, portval:word
  149.     extrn    filtst:byte, dmpname:byte, kbdflg:byte, rxtable:byte
  150.     extrn    anspflg:byte, tekflg:byte, scroll:byte, ttyact:byte
  151.     extrn    holdscr:byte, taklev:byte, takadr:word, mcctab:byte
  152.     extrn    trans:byte, npages:word, comand:byte, apctrap:byte
  153.     extrn    denyflg:word, tekgraf:byte, rdbuf:byte, dupflg:byte
  154.     extrn    chcontrol:byte, kbcodes:byte, repflg:byte, tekcursor:byte
  155.     extrn    decbuf:byte, param:word, nparam:word, prnhand:word
  156.     extrn    upss:byte, comptab:byte, GRptr:word, G1set:byte, G2set:byte
  157.     extrn    G3set:byte, kstatus:word, cursor:word, linescroll:byte
  158.     extrn    sescur:word, tcphost:byte, savezlen:word, savezoff:word
  159.     extrn    seslist:byte, savexoff:word, savexlen:word, savepoff:word
  160.     extrn    saveplen:word, rollwidth:word, dgkbl:byte, apcstring:word
  161.     extrn    blinkdis:byte, protectena:byte, dghscrdis:byte
  162.     extrn    dgwindcomp:byte, cursorst:byte, dgcross:byte
  163.     extrn    emsrbhandle:word, curattr:byte, saveuoff:word, saveulen:word
  164.     extrn    savegoff:word, saveglen:word, dosnum:word
  165.     extrn    parmsk:byte, flowon:byte, flowoff:byte, flowcnt:byte
  166.  
  167. inited    equ    08h            ; been here before
  168. prtscr    equ    1            ; print screen pressed
  169. ; stuff for screen routines
  170. ;;;;;;;;;;;;;; start session save area
  171.     even
  172. saveyoff label    word
  173. yflags    db    0            ; status flags
  174. vtemu    emulst    <>            ; emulator flags
  175. belltype db    0            ; 0 = aural bell, 1 = visual
  176. scbattr db    ?            ; screen background attribute
  177. savattr    db    ?            ; current emulator attributes
  178. extattr    db    0            ; extended scbattr
  179. crt_mode db    3            ; video mode (typ 3, must be text)
  180.                     ; keep crt_cols & crt_lins in order
  181. crt_cols db    80            ; number of screen columns (typ 80)
  182. crt_lins db    24            ; number of screen rows - 1 (typ 24)
  183. low_rgt    dw    174fh            ; lower right corner of text window
  184.                     ; high = row address (typ 23)
  185.                     ; low = column address (typ 79)
  186. handhsc    db    0            ; hand horizontal scroll
  187. dosetcursor dw    -1            ; place to set tekcursor, -1 = don't
  188. vtinited db    0            ; flag for emulator having been inited
  189. vtclear    db    0            ; nonzero to redo emulator screen
  190. writemode db    0            ; screen writing mode
  191. vtcpage    dw    437            ; terminal code page
  192. apcenable db    1            ; enable APC macro (default is on)
  193. vtenqenable db    0            ; enable Answerback
  194. saveflag    flginfo <>        ; copy of flags array
  195. ytermtype dw    0
  196. ymodetype db    0
  197. saveylen dw    ($ - saveyoff)
  198. ;;;;;;;;;;;;;;;;; end of session save area
  199.  
  200.  
  201. modbuf    modfrm    <>            ; mode line buffer
  202. argadr    dw    0            ; address of arg blk
  203. skip    dw    0
  204. inemulator db    0            ; non-zero if term emlator active
  205.  
  206. vid7id    db    'VEGA BIOS Code, '    ; Video 7 Vega version string subset
  207. vid7len    equ    $-vid7id        ; length of string
  208. vid7id2    db    'Video Seven BIOS Code, ' ; Video 7 VGA board
  209. vid7len2 equ    $-vid7id2
  210. atiwid    db    'ATI EGA Wonder Bios,'    ; ATI EGA wonder version string subset
  211. atilen    equ    $-atiwid        ; length of string, inc terminator
  212. atiwid2    db    '761295520'        ; ATI signature #2
  213. atilen2    equ    $-atiwid2
  214. tsngid    db    'Tseng'            ; Tseng Labs EVA (& Orchid Designer)
  215. tsnglen    equ    $-tsngid
  216. stbvid    db    'TVGA'            ; STB VGA/EM (also Tseng TVGA)
  217. stbvlen    equ    $-stbvid
  218. stavid    db    '4000'            ; STB VGA/EM Plus (Tesng 4000)
  219. stavlen equ    $-stavid
  220. evrxid  db      'Everex'                ; Everex Micro Enhancer Deluxe EGA
  221. evrxlen equ     $-evrxid
  222. evgid    db    'VGA EV673'        ; Everex EVGA EV-673
  223. evglen    equ    $-evgid
  224. evvid    db    'EV-678'        ; Everex Viewpoint EV-678
  225. evvlen    equ    $-evvid
  226. attvdc6    db    '003116'        ; AT&T video board, at c000:35h
  227. attvdlen equ    $-attvdc6
  228. attvdc7    db    'C02000'        ; AT&T video board, at e000:10h
  229. pmega1    db    '28190-A1001'        ; Paradise AutoSwitch EGA Mono String1
  230. pmegal1 equ    $-pmega1        
  231. p30id    db    'VGA'            ; VGA Plus, Plus 16, Professional
  232. p30ln    equ    $-p30id            ;  and VGA1024 by Paradise
  233. emsrollname db    'KERMIT  ',0        ; 8 byte EMS region name, + safety
  234. pageready dw    -1            ; ems page currently active
  235. cols80    db    'COLS80.BAT',0        ; to 80 column mode batch file
  236. cols132    db    'COLS132.BAT',0        ; to 132 column mode batch file
  237. xga_reg_base dw    -1            ; PS/2 MCA I/O register base
  238. ega_mode db    0            ; non-zero if IBM EGA is in use
  239. tvhere    equ    0feh            ; Topview active query
  240. tvsynch    equ    0ffh            ; Topview resynch request
  241. tv_segs    dw    0            ; Topview virtual screen, segment
  242. tv_sego    dw    0            ; and offset
  243. tv_mode    db    0            ; flag, 0 = no Topview or DESQview
  244. vs_ptr    dd    0            ; offset, segment of vscreen (dynamic)
  245. vsat_ptr dd    0            ; offset, segment of vs's attributes
  246. ; Note: (vswidth+1)/2 bytes of attributes/line, at two attributes/byte
  247. vswidth    equ    207            ; columns across DG virtual screen
  248.  
  249. ; The following are used to turn the display back on (after scrolling etc.)
  250. msets    db    2CH,28H,2DH,29H,2AH,2EH,1EH,29H
  251. dgcurtab db    23,26,24,25        ; ANSI to DG cursor converter
  252. dgcrostab db    72,80,77,75        ; DG cursor to PC scan for croshair
  253.  
  254. mtty    db    '  TTY   '        ; no terminal type (mode line)
  255. fairness dw    0
  256. fairprn    dw    0
  257. lincur    dw    ?            ; cursor type save area
  258. dosattr    db    ?            ; screen attributes at init time
  259. userbold db    0            ; screen bold attribute at start up
  260. dos_cols db    0            ; screen width (crt_cols) at DOS
  261. oldsp    dw    0            ; offset to longjmp to for i/o failure
  262. ten    db    10            ; byte constant for key defines
  263. temp    dw    0            ; scratch storage
  264. temp2    dw    0            ; scratch storage
  265. dmphand    dw    -1            ; screen dump file handle
  266. dumpsep    db    0ch,cr,lf        ; screen image separators
  267. dmperr    db    ' Cannot open file to save screen to disk $'
  268. memerr    db    cr,lf,'Not enough memory for terminal emulator$'
  269. crlf    db    cr,lf,'$'
  270. pntmsg    db    'Printer not ready, printing request skipped$'
  271. upsshlp    db    ' User Preferred Supplemental Set:'
  272.     db    cr,lf, 'DEC-MCS, Latin-1, Hebrew-7, Hebrew-ISO$'
  273. apchlp    db    cr,lf,'ON to allow APC cmd from host to invoke commands'
  274.     db    ' (default)'
  275.     db    cr,lf,'OFF to prevent all use of APC from the host'
  276.     db    cr,lf,'UNCHECKED to allow any command to be executed$'
  277. enqhlp    db    cr,lf,'ON to permit Answerback to Control-E Enquire request'
  278.     db    ' (def=off)$'
  279. ; some static data for mode line
  280. modmaster modfrm <>            ; master template
  281. unkbaud    db    'unkwn '        ; must be 6 chars
  282. baudn    db    ' 45.5 ',' 50   ',' 75   ',' 110  ','134.5 ',' 150  ',' 300  '
  283.     db    ' 600  ',' 1200 ',' 1800 ',' 2000 ',' 2400 ',' 4800 ',' 9600 '
  284.     db    '14400 ', '19200 ','28800 ', '38400 ','57.6K ','115 K '
  285.     db    '75/12 '
  286. baudnsiz  equ    21            ; # of baud rates known (tbl size / 6)
  287. repmsg    db    'REPLAY'        ; REPLAY message for speed field
  288. repmsgl    equ    $-repmsg
  289. parnams    db    'even','mark','none','odd ','spc '
  290. lclmsg    db    'loc'
  291. remmsg    db    'rem'
  292. portno    db    0
  293.  
  294. ; storage for multi-window stuff
  295. slen    equ    24            ; and length of text
  296. crt_norm db    3            ; video mode for normal screen
  297.                     
  298. inipara    dw    0            ; initial paragraphs of scroll memory
  299.                     ;  also is number ems pages for same
  300. refresh    db    0            ; screen refresh (0=wait for retrace)
  301. vtroll    db    0            ; auto roll back allowed (0 = no)
  302. useexp    db    0            ; non-zero to use exp mem for rollback
  303. vsbuff_inited db 0            ; non-zero if inited screen buffers
  304. setnoshow db    0            ; quiet setatch flag
  305.  
  306. vtkrname db    'KEYBOARDR'        ; a macro name, must be Upper Case
  307. vtkrlen    equ    $-vtkrname
  308. vtksname db    'KEYBOARDS'        ; a macro name, must be Upper Case
  309. vtkslen    equ    $-vtksname
  310. prodname db    'PRODUCT'
  311. vtplen    equ    $-prodname
  312. vtsesname db    'SESSION'
  313. vtsesnum db    '1'
  314. vtseslen equ    $-vtsesname
  315.  
  316. vtmacname dw    vtkrname        ; pointer to selected macro name
  317. vtmaclen dw    vtkrlen
  318. udkseg    dw    18 dup (0)        ; segment of user definable key defs
  319.     even                ; screen rollback material
  320. iniseg    dw    ?            ; (BDT) initial seg of scroll memory
  321. ppl    dw    0            ; (BDT) paragraphs per line
  322. lcnt    dw    0            ; (BDT) number of "filled" buffer lines
  323. linef    dw    0            ; (BDT) "first" filled line is here
  324. linec    dw    0            ; (BDT) "current" screen line number
  325. linee    dw    0            ; (BDT) total # of lines in the buffer
  326. lmax    dw    0            ; (BDT) max lines in buff (less 1 scrn)
  327. lineems    dw    0            ; lines per EMS 16KB page frame
  328.  
  329. tsave    dw    6 dup (0)        ; list of term swap paragraphs
  330.  
  331.                     ; DG SPCL three stroke Compose key
  332. grab    dw    0            ; zero if not grabbing output
  333. grabbox    db    0,0            ; store incoming pair of bytes
  334.  
  335. setchtab db    10            ; Set File Character-Set table
  336.     mkeyw    'CP437',437        ; hardware default Code Page
  337.     mkeyw    'CP850',850        ; Multilingual CP
  338.     mkeyw    'CP852',852        ; Latin2 CP
  339.     mkeyw    'CP860',860        ; Portuguese CP
  340.     mkeyw    'CP861',861        ; Icelandic CP
  341.     mkeyw    'CP862',862        ; Hebrew CP
  342.     mkeyw    'CP863',863        ; French Canadian CP
  343.     mkeyw    'CP865',865        ; Norwegian CP
  344.     mkeyw    'CP866',866        ; Latin5/Cryillic CP
  345.     mkeyw    'Shift-JIS',932        ; Japanese Shift-JIS
  346. ;;    mkeyw    'User-defined',1    ; User loadable table
  347.  
  348.                     ; begin Terminal emulator data set
  349. termtb    db    tttypes            ; entries for Status, not Set
  350.     mkeyw    'VT320',ttvt320
  351.     mkeyw    'VT220',ttvt220
  352.     mkeyw    'VT102',ttvt102
  353.     mkeyw    'VT100',ttvt100
  354.     mkeyw    'VT52',ttvt52
  355.     mkeyw    'Honeywell VIP7809',tthoney
  356.     mkeyw    'Heath-19',ttheath
  357.     mkeyw    'Tek4010',tttek
  358.     mkeyw    'PT200',ttpt200
  359.     mkeyw    'D463',ttd463
  360.     mkeyw    'D470',ttd470
  361.     mkeyw    'none',ttgenrc
  362.  
  363.  
  364. vttbl    db    43            ; number of entries
  365.     mkeyw    'Answerback',vtenqctl
  366.     mkeyw    'APC-macro',apcctl
  367.     mkeyw    'Arrow-keys',flg11
  368.     mkeyw    'Character-set',vtchar
  369.     mkeyw    'Code-Page',vtcodepage
  370.     mkeyw    'Compressed-text',flg14
  371.     mkeyw    'Controls',flg9
  372.     mkeyw    'Cursor-style',flg7
  373.     mkeyw    'Direction',flg4
  374.     mkeyw    'Expanded-memory',expmemory
  375.     mkeyw    'Horizontal-scroll',flg13
  376.     mkeyw    'Keyclick',flg5
  377.     mkeyw    'Keypad',flg10
  378.     mkeyw    'Margin-bell',flg6
  379.     mkeyw    'Newline',flg1
  380.     mkeyw    'Screen-background',flg8
  381.     mkeyw    'Video-writing',scrwrite
  382.     mkeyw    'Tabstops',tabmod
  383.     mkeyw    'Width',flg12
  384.     mkeyw    'Wrap-lines',flg2
  385.  
  386.     mkeyw    'Bell',vtbeep
  387.     mkeyw    'Bytesize',vtbyte
  388.     mkeyw    'Clear-screen',vtcls
  389.     mkeyw    'Color',vtcolor
  390.     mkeyw    'Display',vtbyte    ; syn for set display 7/8
  391.     mkeyw    'Graphics',vtgraph
  392.     mkeyw    'Replay',replay
  393.     mkeyw    'Rollback',vtrollbk
  394.     mkeyw    'output-shift',vtshift
  395.     mkeyw    'UPSS',vtupss
  396.     mkeyw    'Type',vttype        ; SET TERM TYPE
  397.     mkeyw    'None',vttyp0
  398.     mkeyw    'Heath-19',vttyp1
  399.     mkeyw    'VT52',vttyp2
  400.     mkeyw    'VT100',vttyp4
  401.     mkeyw    'VT102',vttyp8
  402.     mkeyw    'VT220',vttyp10
  403.     mkeyw    'VT320',vttyp20
  404.     mkeyw    'Tek4010',vttyp40
  405.     mkeyw    'Honeywell',vttyp80
  406.     mkeyw    'PT200',vttyp100
  407.     mkeyw    'D463',vttyp200
  408.     mkeyw    'D470',vttyp400
  409.  
  410. ontab    db    2            ; two entries
  411.     mkeyw    'off',0
  412.     mkeyw    'on',1
  413.  
  414. beltab    db    3            ; bell type
  415.     mkeyw    'audible',0
  416.     mkeyw    'visual',1
  417.     mkeyw    'none',2
  418.  
  419. distab    db    2            ; display
  420.     mkeyw    '7-bit',0
  421.     mkeyw    '8-bit',d8bit
  422.  
  423. scrtab    db    2            ; screen attributes
  424.     mkeyw    'normal',0
  425.     mkeyw    'reverse',1
  426.  
  427. dirtab    db    2            ; writing direction
  428.     mkeyw    'left-to-right',0
  429.     mkeyw    'right-to-left',1
  430.  
  431. writetab db    2            ; writing
  432.     mkeyw    'direct',0
  433.     mkeyw    'Bios',1
  434.  
  435. curtab    db    2            ; cursor attributes
  436.     mkeyw    'block',0
  437.     mkeyw    'underline',1
  438.  
  439. apctab    db    3            ; three entries
  440.     mkeyw    'off',0
  441.     mkeyw    'on',1
  442.     mkeyw    'unchecked',2
  443.      
  444. chatab    db    24            ; National Replacement Character sets
  445.     mkeyw    'ASCII',0        ; ASCII is default (0, no NRC)
  446.     mkeyw    'British',1        ; start NRC set (1-12)
  447.     mkeyw    'Dutch',2
  448.     mkeyw    'Finnish',3
  449.     mkeyw    'French',4
  450.     mkeyw    'Fr-Canadian',5
  451.     mkeyw    'German',6
  452.     mkeyw    'Hebrew-7',13
  453.     mkeyw    'Italian',7
  454.     mkeyw    'Norwegian/Danish',8
  455.     mkeyw    'Portuguese',9
  456.     mkeyw    'Spanish',10
  457.     mkeyw    'Swedish',11
  458.     mkeyw    'Swiss',12        ; end of NRC proper
  459.  
  460.     mkeyw    'Alternate-ROM',14    ; Alternate-ROM character set
  461.     mkeyw    'Transparent',15    ; use native display adapter hardware
  462.     mkeyw    'Latin1',16        ; Latin-1 in GR
  463.     mkeyw    'Latin2',23        ; Latin-2 (will presume CP852)
  464.     mkeyw    'Hebrew-ISO',24        ; Hebrew-ISO (presumes CP862)
  465.     mkeyw    'DEC-MCS',17        ; DEC Supplemental Graphics in GR
  466.     mkeyw    'DEC-Technical',18
  467.     mkeyw    'DEC-Special',19
  468.     mkeyw    'DG-International',20
  469.     mkeyw    'DG-Line-Drawing',21
  470.     mkeyw    'DG-Word-Processing',22
  471.  
  472. upsstab    db    4
  473.     mkeyw    'DEC-MCS','5%'            ; DEC Supplemental Graphics
  474.     mkeyw    'Latin1','A'            ; Latin-1
  475.     mkeyw    'Hebrew-7','4"'            ; DEC Hebrew-7
  476.     mkeyw    'Hebrew-ISO','H'        ; Hebrew-ISO
  477.  
  478. sidetab    db    4            ; SET TERM CHAR <char set> Gn
  479.     mkeyw    'G0','0'
  480.     mkeyw    'G1','1'
  481.     mkeyw    'G2','2'
  482.     mkeyw    'G3','3'
  483.  
  484. shifttab db    5            ; SET TERM OUTPUT-SHIFT
  485.     mkeyw    'none',0
  486.     mkeyw    'automatic',8
  487.     mkeyw    'SI/SO',1
  488.     mkeyw    'SS2',2
  489.     mkeyw    'SS3',4
  490.  
  491. graftab    db    12
  492.     mkeyw    'auto-sensing',0    ; autosensing
  493.     mkeyw    'CGA',1
  494.     mkeyw    'EGA',2
  495.     mkeyw    'VGA',3
  496.     mkeyw    'Hercules',4
  497.     mkeyw    'ATT',5
  498.     mkeyw    'WyseA(1280x800)',6    ; Wyse-700 1280 x 800 mode
  499.     mkeyw    'WyseH(1280x780)',7    ; Wyse-700 1280 x 780 mode
  500.     mkeyw    'WyseT(1024x780)',8    ; Wyse-700 1024 x 780 mode
  501.     mkeyw    'character-writing',101h
  502.     mkeyw    'color',103h
  503.     mkeyw    'cursor',102h
  504.  
  505. gchrtab    db    2            ; set term graphics char-writing
  506.     mkeyw    'opaque',1
  507.     mkeyw    'transparent',0
  508.  
  509. disatab    db    2            ; Tek disable/enable table
  510.     mkeyw    'disabled',1
  511.     mkeyw    'enabled',0
  512.  
  513. tabtab    db    2            ; label says it all!
  514.     mkeyw    'at',0FFH        ; For setting tab stops
  515.     mkeyw    'Clear',0        ; For clearing tab stops
  516.      
  517. alltab    db    2            ; more tab command decoding
  518.     mkeyw    'all',0
  519.     mkeyw    'at',1
  520.  
  521. cntltab    db    2            ; 8-bit controls
  522.     mkeyw    '7-bit',0
  523.     mkeyw    '8-bit',1
  524.  
  525. kpamtab    db    2            ; keypad, application
  526.     mkeyw    'numeric',0
  527.     mkeyw    'application',1
  528.  
  529. arrtab    db    2            ; cursor keys, application
  530.     mkeyw    'cursor',0
  531.     mkeyw    'application',1
  532.  
  533. widtab    db    2
  534.     mkeyw    '80-columns',0
  535.     mkeyw    '132-columns',1
  536.  
  537. hstab    db    2            ; horizontal scrolling
  538.     mkeyw    'auto',0
  539.     mkeyw    'manual',1
  540.  
  541. cmptab    db    2
  542.     mkeyw    'graphics',0
  543.     mkeyw    'text-132',1
  544.  
  545. colortb    db    0,4,2,6,1,5,3,7        ; color reversed-bit setting bytes
  546. clrset    db    0            ; Temp for SET Term Tabstops xxx
  547.  
  548. erms41    db    cr,lf,'?More parameters are needed$'
  549. vthlp    db    ' one of the following:',cr,lf
  550.     db    '  TYPE of: None, Heath-19, Honeywell VIP7809, VT52,'
  551.     db    ' VT100, VT102, VT220,',cr,lf,'    VT320 (default), Tek4010,'
  552.     db     ' PT200 (Prime), D463 or D470 (Data General)'
  553.     db    cr,lf
  554.     db    '  Newline-mode    Cursor-style        Character-set'
  555.     db     cr,lf
  556.     db    '  Keyclick        Margin-bell         Screen-background'
  557.     db    ' (normal, reverse)',cr,lf
  558.     db '  Tabstops        Wrap (long lines)   Color (fore & background)'
  559.     db    cr,lf,'  Answerback response (on or off, default is off)'
  560.     db    cr,lf,'  APC-macro  (APC cmd from host invokes local cmds)' 
  561.     db    cr,lf,'  Arrow-keys  cursor (normal) or application mode'
  562.     db    cr,lf,'  Bell  audible or visual or none'
  563.     db    cr,lf,'  Clear-screen  (clears old startup screen)'
  564.     db    cr,lf,'  Code-Page (overrides default)'
  565.     db    cr,lf,'  Compressed-text  Graphics or Text-132 (for D463/D470)'
  566.     db    cr,lf,'  Controls 7-bit or 8-bit  (permits VT320 to send'
  567.     db    ' 8-bit control sequences (C1))'
  568.     db    cr,lf,'  Direction Left-to-right or Right-to-left'
  569.     db    ' (screen writing direction)'
  570.     db    cr,lf,'  Display or Bytesize 7-bit or 8-bit'
  571.     db    cr,lf,'  Expanded-memory (for screen rollback), default on'
  572.     db    cr,lf,'  Graphics  (type of display adapter when in Tek4010'
  573.     db    ' mode, and char writing)'
  574.     db    cr,lf,'  Horizontal scrolling, auto (default) or manual'
  575.     db    cr,lf,'  Keypad numeric (normal) or application mode'
  576.     db    cr,lf,'  Output-shift (prefix 8-bit data for 7-bit channel)'
  577. ;;;    db     cr,lf,'  Replay filespec (display a file through the emulator)'
  578.     db    cr,lf,'  Rollback  (undo screen roll back before writing new'
  579.     db    ' chars, default=off)'
  580.     db    cr,lf,'  TEK ENABLE or DISABLE (activation by host command)'
  581.     db    cr,lf,'  Width 80 or 132 columns, if the adapter can do it'
  582.     db    cr,lf,'  Video-writing, Direct or via Bios$'
  583. clrhlp    db    ' one of the following:'
  584.     db    cr,lf,'  AT #s  (to set tabs at column #s)    or'
  585.     db    ' AT start-column:spacing'
  586.     db    cr,lf,'  Clear AT #s (clears individual tabs) or'
  587.     db    ' AT start-column:spacing'
  588.     db    cr,lf,'  Clear ALL  (to clear all tabstops)'
  589. clrhlp2    db    cr,lf,'  Ex: Set term tab at 10, 20, 34        sets tabs'
  590.     db    cr,lf,'  Ex: Set term tab at 1:8        sets tabs at 1, 9,'
  591.     db    cr,lf,'  Ex: Set term tab clear at 9, 17, 65   clears tabs'
  592.     db    cr,lf,'  Ex: Set term tab clear at 1:8  clears tabs at 1, 9,'
  593.     db    ' 17,...$'
  594. tbserr    db    cr,lf,'?Column number is not in range 1 to screen width-1$'
  595. colhlp    db    cr,lf,'  Set Term Color  value, value, value, ...'
  596.     db    cr,lf,'   0 no-snow mode on an IBM CGA and white on black'
  597.     db    cr,lf,'   1 for high intensity foreground'
  598.     db    cr,lf,'  10 for fast CGA screen updating (may cause snow)'
  599.     db    cr,lf,'  Foreground color (30-37) = 30 + sum of colors'
  600.     db    cr,lf,'  Background color (40-47) = 40 + sum of colors'
  601.     db    cr,lf,'    where colors are  1 = red, 2 = green, 4 = blue'
  602.     db    cr,lf,'  Ex: 0, 1, 37, 44   IBM CGA(0), bright(1) white(37)'
  603.     db    ' chars on a blue(44) field'
  604.     db    cr,lf,'  Attributes are applied in order of appearance.$'
  605. colerr    db    cr,lf,'?Value not in range of 0, 1, 10, 30-37, or 40-47$'
  606. expmhlp    db    cr,lf,' Use expanded memory for screen rollback buffer,'
  607.     db    ' on or off$'
  608. vtwrap    db    'Term wrap-lines: $'
  609. vtbellm    db    'Term margin-bell: $'
  610. vtnewln db    'Term newline: $'
  611. vtcur    db    'Term cursor-style: $'
  612. vtcset    db    'Term character-set: $'
  613. vtclik    db    'Term key-click: $'
  614. vtscrn    db    'Term screen-background: $'
  615. colst1    db    'Term color  foregnd:3$'
  616. colst2    db    ' backgnd:4$'
  617. vtgraf    db    'Term graphics: $'
  618. vtrolst    db    'Term rollback: $'
  619. vtdir    db    'Term direction: $'
  620. vtcntst    db    'Term controls: $'
  621. vtkpst    db    'Term keypad: $'
  622. vtarst    db    'Term arrow-keys: $'
  623. vtbset    db    'Term bell: $'
  624. vtgchst    db    'Term graph char: $'
  625. vtwdst    db    'Term width: $'
  626. vtupsst    db    'Term UPSS: $'
  627. vtshftst db    'Term output-shift: $'
  628. vthscst    db    'Term horizontal-scroll: $'
  629. vtapcst    db    'Term APC-macro: $'
  630. vtenqst db    'Term Answerback: $'
  631. vtwrtst    db    'Term video-writing: $'
  632. vtexpmst db    'Term expanded-memory: $'    
  633. vtcpagest db    'Term Code-Page: $'
  634. vtcmptst db    'Term compressed-text: $'
  635.                             ; terminal emulator
  636. vtstbl    stent    <srchkw,vtenqst,ontab,vtenqenable>        ; Answerback
  637.     stent    <srchkw,vtapcst,apctab,apcenable>        ; APC-macro
  638.     stent    <srchkw,vtcset,chatab,vtemu.vtchset>        ; char set
  639.     stent    <srchkb,vtclik,ontab,vskeyclick,vtemu.vtflgop>    ; keyclick
  640.     stent    <colstat>                    ; colors
  641.     stent    <srchkb,vtwrap,ontab,vswrap,vtemu.vtflgop>    ; line wrap
  642.     stent    <srchkb,vtcntst,cntltab,vscntl,vtemu.vtflgop>    ; controls
  643.     stent    <srchkb,vtbellm,ontab,vsmarginbell,vtemu.vtflgop>;margin bell
  644.     stent    <srchkb,vtcur,curtab,vscursor,vtemu.vtflgop>    ; cursor type
  645.     stent    <srchkw,vtbset,beltab,belltype>            ; bell
  646.     stent    <srchkb,vtdir,dirtab,vswdir,vtemu.vtflgop>    ; write direct
  647.     stent    <srchkb,vtnewln,ontab,vsnewline,vtemu.vtflgop>    ; newline
  648.     stent    <srchkw,vtgraf,graftab,tekgraf>            ; graphics
  649.     stent    <srchkw,vtrolst,ontab,vtroll>            ; rollback
  650.     stent    <srchkw,vtgchst,gchrtab,chcontrol>        ; chr cntrl
  651.     stent    <srchkb,vtarst,arrtab,decckm,vtemu.vtflgop>    ; arrow-keys
  652.     stent    <srchkb,vtscrn,scrtab,vsscreen,vtemu.vtflgop>    ; screen 
  653.     stent    <srchkb,vtkpst,kpamtab,deckpam,vtemu.vtflgop>    ; keypad
  654.     stent    <srchkb,vtwdst,widtab,deccol,vtemu.vtflgop>    ; width
  655.     stent    <srchkww,vtupsst,upsstab,upss+1>        ; UPSS
  656.     stent    <srchkw,vtshftst,shifttab,flags.oshift>        ; output-shift
  657.     stent    <srchkb,vthscst,hstab,vshscroll,vtemu.vtflgop>    ; Horz scroll
  658.     stent    <srchkw,vtwrtst,writetab,writemode>        ; Writing
  659.     stent    <srchkw,vtexpmst,ontab,useexp>            ; exp mem
  660.     stent    <srchkww,vtcpagest,setchtab,vtcpage>        ; Code-Page
  661.     stent    <srchkb,vtcmptst,cmptab,vscompress,vtemu.vtflgop> ; compress
  662.  
  663.     stent    <tabstat>    ; VT320 tab status - needs one whole line
  664.     dw    0        ; end of table
  665.  
  666. vtmacroptr    dd    vtmacro            ; FAR pointer
  667. ftogmod        dd    togmod            ; FAR pointer
  668. termlatch    db    0        ; reentry block for session macros
  669. data    ends
  670.  
  671. data1    segment
  672. ; structures below: byte cnt of combos, dw input combo list, db output list
  673. ; using DG International or Latin1 codes for output.
  674. grl1dgi db    48            ; case and order insensitive
  675.     dw    '++','AA','((','//','/<','^ ','(-','/^',')-','<<'
  676.     dw    '0^','* ','+-','>>','SS','/U','2^','3^','C/','C|'
  677.     dw    'L-','L=','Y-','Y=','SO','S!','S0','XO','X0','A-'
  678.     dw    'CO','C0','PP','P!','.^','O-','12','!!','??','T-'
  679.     dw    'TM','FF','<=','>=',',-','""',2727h,'RO'
  680. grc1dgi db    '#', '@', '[', '\', '\', '^', '{', '|', '}', 0b1h
  681.     db    0bch,0bch,0b6h,0b0h,0fch,0a3h,0a4h,0a5h,0a7h,0a7h
  682.     db    0a8h,0a8h,0b5h,0b5h,0bbh,0bbh,0bbh,0a6h,0a6h,0a9h
  683.     db    0adh,0adh,0b2h,0b2h,0b9h,0aah,0a2h,0abh,0ach,0afh
  684.     db    0b3h,0b4h,0b7h,0b8h,0a1h,0bdh,0beh, 0aeh
  685.  
  686. grl1lat db    44            ; case and order insensitive
  687.     dw    '<<','0^','* ','+-','>>','SS','/U','2^','3^','C/'
  688.     dw    'C|','L-','L=','Y-','Y=','SO','S!','S0','XO','X0'
  689.     dw    'A-','CO','C0','PP','P!','.^','O-','12','!!','??'
  690.     dw    'TM',',-','""',2727h,'RO','||','--','-^',',,','34'
  691.     dw    'XX','-:','1^','14'
  692. grc1lat db    0abh,0b0h,0b0h,0b1h,0bbh,0dfh,0b5h,0b2h,0b3h,0a2h
  693.     db    0a2h,0a3h,0a3h,0a5h,0a5h,0a7h,0a7h,0a7h,0a4h,0a4h
  694.     db    0aah,0a9h,0a9h,0b6h,0b6h,0b7h,0bah,0bdh,0a1h,0bfh
  695.     db    0aeh,0ach,0a8h,0b4h, 0aeh,0a6h,0adh,0afh,0b8h,0beh
  696.     db    0d7h,0f7h,0b9h,0bch
  697.  
  698. grl2dgi    db    25            ; case sensitive, order insensitive
  699.     dw    '''A','`A','^A','"A','~A','*A','''E','`E','^E','"E'
  700.     dw    '''I','`I','^I','"I','~N','''O','`O','^O','"O','~O'
  701.     dw    '''U','`U','^U','"U','"Y'
  702. grc2dgi    db    0c0h, 0c1h,0c2h,0c3h,0c4h,0c5h,0c8h, 0c9h,0cah,0cbh
  703.     db    0cch, 0cdh,0ceh,0cfh,0d0h, 0d1h,0d2h,0d3h,0d4h,0d5h
  704.     db    0d8h, 0d9h,0dah,0dbh,0ddh
  705.  
  706. grl2lat    db    25            ; case sensitive, order insensitive
  707.     dw    '''A','`A','^A','"A','~A','*A','''E','`E','^E','"E'
  708.     dw    '''I','`I','^I','"I','~N','''O','`O','^O','"O','~O'
  709.     dw    '''U','`U','^U','"U','''Y'
  710. grc2lat    db    0c1h, 0c0h,0c2h,0c4h,0c3h,0c5h,0c9h, 0c8h,0cah,0cbh
  711.     db    0cdh, 0cch,0ceh,0cfh,0d1h, 0d3h,0d2h,0d4h,0d6h,0d5h
  712.     db    0dah, 0d9h,0d8h,0dch,0ddh
  713.  
  714. grl3dgi db    7            ; case and order sensitive
  715.     dw    'EO','AE',',C','/O','ae',',c','/o'
  716. grc3dgi db    0d7h,0c6h,0c7h,0d6h,0e6h,0e7h,0f6h
  717.  
  718. grl3lat db    10            ; case and order sensitive
  719.     dw    'AE',',C','/O','HT','-D','ae',',c','/o','ht','-d'
  720. grc3lat db    0c6h,0c7h,0d8h,0deh,0d0h,0e6h,0e7h,0f8h,0feh,0f0h
  721. data1    ends
  722.                         ; end of Terminal data set
  723. code1    segment
  724.     extrn    ans52t:far, vsinit:near        ; in mszibm
  725.     extrn    anstty:near, ansini:near, ansrei:near    ; in mszibm
  726.     extrn    anskbi:near, ansdsl:near    ; in mszibm
  727.     extrn    tabset:near, tabclr:near, dgnctoggle:far
  728.  
  729. fanskbi    proc    far
  730.     call    anskbi                ; in mszibm
  731.     ret
  732. fanskbi    endp
  733. ftabset    proc    far
  734.     call    tabset                ; in mszibm
  735.     ret
  736. ftabset    endp
  737. ftabclr    proc    far
  738.     call    tabclr                ; in mszibm
  739.     ret
  740. ftabclr    endp
  741. code1    ends
  742.  
  743. code2    segment
  744.     extrn   tekini:far, tekemu:far, tekend:far, tekrint:far ;in msgibm
  745.     extrn    ttxtchr:far, ttxtline:far,teksetcursor:far,tekremcursor:far
  746.     extrn    croshair:far, dgcrossrpt:far
  747. code2    ends
  748.  
  749. code    segment
  750.     extrn    prtchr:near, outchr:near, sbrk:near, pcwait:near
  751.     extrn    isfile:near
  752.     extrn    msuinit:near, keybd:near, kbhold:near    ; in msuibm
  753.     extrn    clrmod:near, putmod:near, cmblnk:near, cptchr:near
  754.     extrn    telnet:near, srchkww:near
  755.     extrn    atoi:near, strlen:near, srchkb:near, srchkw:near, pasz:near
  756.     extrn    prompt:near, comnd:near, statc:near, replay:near
  757.     extrn    crun:near, serini:near, spath:near, strcpy:near, tekdmp:near
  758.     extrn    prttab:near, dec2di:near, tekgcptr:near
  759.     extrn    pntchr:near, pntflsh:near, tcpstart:near, serrst:near
  760.     assume    cs:code, ds:data, es:nothing
  761.  
  762. ; do initialization local to this module
  763. ; Dynamically allocates 4000 bytes for screen save/restore buffer plus
  764. ;  320 to 38400 bytes for screen scroll back buffers. Tries to leave space
  765. ;  for Command.com before enlarging buffers.
  766. lclyini    proc    near
  767.     call    msuinit            ; initialize keyboard module msuxxx
  768.     call    far ptr flclyini    ; far call specifics
  769.     ret
  770. lclyini    endp
  771.  
  772.                     ; begin Terminal set & status code
  773. ; SET Term parameters, especially for use with VT100 emulator.
  774. ; VTS is called only by mssset to set terminal type and characteristics.
  775. ; Exit carry set for failure.
  776. VTS    proc    near            ; SET TERM whatever
  777.     mov    kstatus,kssuc        ; success
  778.     mov    ah,cmkey        ; Parse another keyword
  779.     mov    bx,offset vthlp        ; Use this help
  780.     mov    dx,offset vttbl        ; Use this table
  781.     call    comnd
  782.     jnc    vset1            ; nc = success
  783.     ret                ; failure
  784. vset1:    call    bx            ; dispatch to processing routine
  785.     ret
  786.  
  787. vtcls:    mov    ah,cmeol        ; Clear-screen
  788.     call    comnd
  789.     jc    vtclsx            ; c = failure
  790.     mov    vtclear,2        ; set trigger for emulator clear scn
  791.     clc                ; success
  792. vtclsx:    ret
  793.  
  794.                     ; SET TERM kind
  795. vttyp0:    mov    bx,ttgenrc        ; NONE
  796.     jmp    short vsett1
  797. vttyp1:    mov    bx,ttheath        ; Heath-19
  798.     jmp    short vsett1
  799. vttyp2:    mov    bx,ttvt52        ; VT52
  800.     jmp    short vsett1
  801. vttyp4:    mov    bx,ttvt100        ; VT100
  802.     jmp    short vsett1
  803. vttyp8:    mov    bx,ttvt102        ; VT102
  804.     jmp    short vsett1
  805. vttyp10:mov    bx,ttvt220        ; VT220
  806.     jmp    short vsett1
  807. vttyp20:mov    bx,ttvt320        ; VT320
  808.     jmp    short vsett1
  809. vttyp40:mov    bx,tttek        ; Tek
  810.     jmp    short vsett1
  811. vttyp80:mov    bx,tthoney        ; Honeywell VIP7809
  812.     jmp    short vsett1
  813. vttyp100:mov    bx,ttpt200        ; Prime PT200
  814.     jmp    short vsett1
  815. vttyp200:mov    bx,ttd463        ; Data General D463
  816.     mov    vtemu.vtchset,0        ; setup ASCII as char set in G0
  817.     jmp    short vsett1
  818. vttyp400:mov    bx,ttd470        ; Data General D470
  819.     mov    vtemu.vtchset,0        ; setup ASCII as char set in G0
  820.     jmp    short vsett1
  821.  
  822. vttype:    mov    ah,cmkey        ; SET TERM TYPE
  823.     xor    bx,bx            ; table is help
  824.     mov    dx,offset termtb    ; use this table
  825.     call    comnd
  826.     jnc    vsett1            ; nc = success
  827.     ret                ; failure
  828.  
  829. vsett1:    mov    temp,bx            ; save terminal type
  830.     mov    temp2,-1        ; assume no enable/disable Tek
  831.     cmp    bx,tttek        ; set term tek?
  832.     jne    vsett2            ; ne = no
  833.     mov    dx,offset disatab    ; disable/enable keyword table
  834.     xor    bx,bx            ; help is the table
  835.     mov    comand.cmcr,1        ; allow bare CR's
  836.         mov    ah,cmkey        ; get enable/disable keyword
  837.     call    comnd
  838.     mov    comand.cmcr,0        ; no more bare CR's
  839.     jc    vsett2            ; c = no such keyword
  840.     mov    temp2,bx        ; save enable/disable keyword value
  841.     mov    bx,flags.vtflg        ; get current terminal type
  842.     mov    temp,bx            ; and force it here
  843.  
  844. vsett2:    mov    ah,cmeol
  845.     call    comnd            ; get a confirm
  846.     jc    vsettx            ; c = failure
  847. vsett3:    mov    bx,temp
  848.     mov    flags.vtflg,bx        ; Set the terminal emulation type
  849.     mov    tekflg,0        ; clear graphics mode
  850.     or    vtemu.vtflgst,vscompress+vshscroll ; set compress to text-132
  851.     or    vtemu.vtflgop,vscompress+vshscroll
  852.                     ; and horz scroll to manual
  853.     cmp    bx,tttek        ; adjusting Tek?
  854.     je    vsett4            ; e = yes
  855.     test    bx,ttd463+ttd470    ; DG D463/470?
  856.     jz    vsett6            ; z = no
  857.     and    vtemu.vtflgst,not (vscompress+vshscroll) ; comp = graphics,
  858.     and    vtemu.vtflgop,not (vscompress+vshscroll) ; horz scroll = auto
  859. vsett6:    cmp    temp2,-1        ; just enable/disable tek?
  860.     je    vsett5            ; e = no
  861. vsett4:    and    denyflg,not tekxflg    ; enable Tek
  862.     cmp    temp2,1            ; ought we disable?
  863.     jne    vsett5            ; ne = no
  864.     or    denyflg,tekxflg        ; disable Tek
  865. vsett5:    clc                ; success
  866. vsettx:    ret
  867.  
  868. vtchar: mov    ah,cmkey        ; Set Term character set
  869.     xor    bx,bx            ; character set table for help 
  870.     mov    temp,bx            ; counter of trailing items
  871.     mov    dx,offset chatab    ; character set table
  872.     call    comnd
  873.     jc    vtcharx            ; c = failure
  874.     mov    decbuf,bl        ; save here
  875.     mov    ax,word ptr vtemu.vttable ; table of 4 overrides now
  876.     mov    word ptr decbuf+1,ax    ; copy them to temporary table
  877.     mov    ax,word ptr vtemu.vttable+2
  878.     mov    word ptr decbuf+3,ax
  879. vtchar1:mov    comand.cmcr,1        ; allow bare CR's
  880.     mov    ah,cmkey
  881.     xor    bx,bx
  882.     mov    dx,offset sidetab    ; read Gnumber item, if any
  883.     call    comnd
  884.     mov    comand.cmcr,0        ; no bare CR's
  885.     jc    vtchar2            ; c = no match, get confirm
  886.     inc    temp            ; say have a trailing table number
  887.     and    bx,3            ; remove ASCII value encoding
  888.     add    bx,offset decbuf+1    ; address of slot to store info
  889.     mov    al,decbuf        ; set ident
  890.     mov    [bx],al            ; store table ident in G0..G3 slot
  891.     jmp    short vtchar1        ; repeat
  892.  
  893. ; vtemu.vtchset:    changed to new set if no table trailers, else intact
  894. ; vtemu.vttable    db 4 dup(0ffh)     char set numbers for G0..G3 as overrides,
  895. ;                use 0ffh to mean no override for table Gn
  896. vtchar2:mov    ah,cmeol        ; get EOL confirmation
  897.     call    comnd
  898.     jc    vtcharx            ; c = failure, quit
  899.     mov    vtemu.vtchop,-1        ; say reinit char tables
  900.     cmp    temp,0            ; trailers (skip regular setup)?
  901.     jne    vtchar3            ; ne = yes
  902.     mov    al,decbuf        ; get character set
  903.     mov    vtemu.vtchset,al    ; set default character set
  904.                     ; just overrides
  905. vtchar3:mov    ax,word ptr decbuf+1    ; first pair of char set idents
  906.     mov    word ptr vtemu.vttable,ax
  907.     mov    ax,word ptr decbuf+3    ; second pair
  908.     mov    word ptr vtemu.vttable+2,ax
  909.     clc
  910. vtcharx:ret
  911.  
  912. vtshift:mov    ah,cmkey        ; Set Term Output-shift auto, none
  913.     xor    bx,bx
  914.     mov    dx,offset shifttab
  915.     call    comnd
  916.     jc    vtcharx            ; c = failed
  917.     mov    flags.oshift,bl        ; store result
  918.     ret
  919.  
  920. vtrollbk:mov    ah,cmkey        ; Set Term Roll On/Off, auto roll back
  921.     xor    bx,bx            ; Use on/off table as help
  922.     mov    dx,offset ontab        ; Use on/off table
  923.     call    comnd
  924.     jc    vtrollx            ; c = failure
  925.     push    bx
  926.     mov    ah,cmeol        ; get a confirm
  927.     call    comnd
  928.     pop    bx
  929.     jc    vtrollx            ; c = failure
  930.     mov    vtroll,bl        ; set roll state (0=no auto rollback)
  931.     clc
  932. vtrollx:ret
  933.  
  934.                      ; Set Term Color foreground, background
  935. vtcolor:mov    bx,vtemu.att_ptr    ; get address of attributes byte
  936.     mov    bl,[bx]            ; get attributes
  937.     mov    decbuf,bl        ; save in work temp
  938.     mov    al,vtclear        ; screen clear state
  939.     mov    ah,refresh        ; refresh state
  940.     mov    word ptr decbuf+1,ax    ; save here
  941.     call    vsetcol            ; get and analyze colors
  942.     jc    vtcolo1            ; c = failure
  943.     mov    al,decbuf        ; get current attributes
  944.     mov    bx,vtemu.att_ptr    ; get address of attributes byte
  945.     mov    [bx],al            ; store attributes
  946.     mov    savattr,al        ; saved emulator attributes
  947.     mov    ax,word ptr decbuf+1
  948.     mov    vtclear,al        ; update these items
  949.     mov    refresh,ah
  950.     clc
  951. vtcolo1:ret
  952.                     ; setup color information
  953. vsetcol:mov    ah,cmword        ; get number(s) after set term color
  954.     mov    bx,offset colhlp    ; use this help
  955.     mov    dx,offset rdbuf        ; temp buffer
  956.     mov    rdbuf,0            ; clear the buffer
  957.     mov    comand.cmcr,1        ; allow bare c/r's
  958.     call    comnd
  959.     jc    vsetco2            ; c = failure
  960.     or    ax,ax            ; text given?
  961.     jz    vsetco1            ; z = no
  962.     mov    si,offset rdbuf        ; si = place where atoi wants text
  963.     call    vsetco3            ; analyze
  964.     jmp    short vsetcol        ; get more data
  965. vsetco1:mov    ah,cmeol        ; get end of line confirm
  966.     call    comnd
  967. vsetco2:ret                ; c set if failure
  968.  
  969. vsetco3:mov    dx,si
  970.     call    strlen            ; get count for atoi
  971.     mov    ah,cl            ; count for atoi
  972.     call    atoi            ; convert text to numeric in ax
  973.     jnc    vsetco3a        ; got a value
  974.     clc
  975.     ret                ; out of data
  976. vsetco3a:or    ax,ax            ; reset all? regular IBM CGA refresh
  977.     jnz    vsetco4            ; nz = no
  978.     mov    decbuf+2,0        ; Regular (slow) screen refresh
  979.     mov    decbuf,07h        ; clear all, set white on black
  980.     mov    decbuf+1,2        ; set trigger for emulator clear scrn
  981.     jmp    short vsetco3
  982.  
  983. vsetco4:cmp    ax,1            ; high intensity?
  984.     jne    vsetco5            ; e = no
  985.     or    decbuf,08h        ; set high intensity
  986.     mov    decbuf+1,1        ; set trigger for emulator keep screen
  987.     jmp    short vsetco3
  988.  
  989. vsetco5:cmp    ax,10            ; fast refresh?
  990.     jne    vsetco6            ; ne = no
  991.     mov    decbuf+2,1        ; Fast screen refresh
  992.     jmp    short vsetco3
  993.  
  994. vsetco6:cmp    ax,30            ; check range
  995.     jb    vsetco8            ; b = too small, complain
  996.     cmp    ax,37
  997.     ja    vsetco7            ; 30-37 is foreground color
  998.     sub    al,30            ; remove foreground bias
  999.     and    decbuf,not 07H        ; clear foreground bits
  1000.     mov    bx,ax
  1001.     mov    al,colortb[bx]        ; get reversed bit pattern
  1002.     or    decbuf,al        ; load new bits
  1003.     mov    decbuf+1,2        ; set trigger for emulator clear scn
  1004.     jmp    short vsetco3
  1005.  
  1006. vsetco7:cmp    ax,40
  1007.     jb    vsetco8            ; b = bad value
  1008.     cmp    ax,47            ; compare as unsigned
  1009.     ja    vsetco8            ; 40-47 is background
  1010.     sub    al,40            ; remove background bias
  1011.     and    decbuf,not 70H        ; clear background bits
  1012.     mov    bx,ax
  1013.     mov    al,colortb[bx]        ; get reversed bit pattern
  1014.     mov    cl,4            ; rotate 4 positions
  1015.     rol    al,cl
  1016.     or    decbuf,al        ; load new bits
  1017.     mov    decbuf+1,2        ; set trigger for emulator clear scn
  1018.     jmp    vsetco3
  1019.  
  1020. vsetco8:mov    ah,prstr        ; not in range - complain and exit
  1021.     mov    dx,offset colerr
  1022.     int    dos
  1023.     mov    kstatus,ksgen        ; general failure
  1024.     stc                ; error
  1025.     ret
  1026.          
  1027.  
  1028. vtgraph:mov    ah,cmkey        ; Set Term graphics
  1029.     xor    bx,bx            ; Use graphics table as help
  1030.     mov    dx,offset graftab    ; Use graphics table
  1031.     call    comnd
  1032.     jc    vtgrapx            ; c = failure
  1033.     cmp    bx,100h            ; in the special options area?
  1034.     ja    vtgrap1            ; a = yes
  1035.     push    bx
  1036.     mov    ah,cmeol        ; get a confirm
  1037.     call    comnd
  1038.     pop    bx
  1039.     jc    vtgrapx            ; c = failure
  1040.     mov    tekgraf,bl        ; set Tek graphics board type
  1041.     clc
  1042. vtgrapx:ret
  1043. vtgrap1:cmp    bx,101h            ; character writing?
  1044.     jne    vtgrap2            ; ne = no
  1045.     mov    ah,cmkey        ; Set Term graphics char-writing
  1046.     xor    bx,bx            ; no help
  1047.     mov    dx,offset gchrtab    ; opaque/transparent table
  1048.     call    comnd
  1049.     jc    vtgrapx            ; c = failure
  1050.     push    bx
  1051.     mov    ah,cmeol        ; get a confirm
  1052.     call    comnd
  1053.     pop    bx
  1054.     jc    vtgrapx
  1055.     mov    chcontrol,bl        ; set/reset opaque char control
  1056.     clc
  1057.     ret
  1058. vtgrap2:cmp    bx,102h            ; cursor on/off?
  1059.     jne    vtgrap4            ; ne = no
  1060.     mov    ah,cmkey        ; Set Term graphics cursor on/off
  1061.     xor    bx,bx            ; no help
  1062.     mov    dx,offset ontab        ; on/off table
  1063.     call    comnd
  1064.     jc    vtgrapx            ; c = failure
  1065.     push    bx
  1066.     mov    ah,cmeol        ; get a confirm
  1067.     call    comnd
  1068.     pop    bx
  1069.     jc    vtgrapx
  1070.     mov    tekcursor,bl        ; set Tek text cursor on/off
  1071.     clc
  1072.     ret
  1073.  
  1074. vtgrap4:cmp    bx,103h            ; Color?
  1075.     jne    vtgrap6            ; ne = no
  1076.     call    tekgcptr        ; get pointer to active Tek color pal
  1077.     mov    al,[bx]            ; get background attributes
  1078.     and    al,7            ; discard intensity bit
  1079.     mov    cl,4
  1080.     shl    al,cl
  1081.     mov    ah,[bx+7]        ; get foreground attributes
  1082.     or    al,ah
  1083.     mov    decbuf,al        ; setup work temp for vsetcol
  1084.     push    bx            ; save index
  1085.     call    vsetcol            ; get and analyze colors
  1086.     pop    bx
  1087.     jnc    vtgrap5            ; nc = ok
  1088.     ret
  1089. vtgrap5:mov    al,decbuf        ; get current attributes
  1090.     mov    ah,al            ; get background bits
  1091.     mov    cl,4
  1092.     shr    ah,cl            ; just background here
  1093.     and    al,0fh            ; just foreground here
  1094.     mov    [bx],ah            ; store colpal[0] as background
  1095.     mov    [bx+7],al        ; store colpal[7] as foreground
  1096.     clc                ; success
  1097. vtgrap6:ret
  1098.     
  1099. vtbeep:    mov    ah,cmkey        ; SET TERM BELL
  1100.     xor    bx,bx            ; use table as help
  1101.     mov    dx,offset beltab    ; use Bell table
  1102.     call    comnd
  1103.     jc    vtbeepx            ; c = failure
  1104.     push    bx
  1105.     mov    ah,cmeol        ; get a confirm
  1106.     call    comnd
  1107.     pop    bx
  1108.     jc    vtbeepx            ; c = failure
  1109.     mov    belltype,bl        ; set bell type
  1110. vtbeepx:ret                ; return carry clear or set
  1111.  
  1112.                     ; SET TERM BYTESIZE {7-bit | 8-bit}
  1113. vtbyte:    mov    ah,cmkey        ; SET TERM DISPLAY {7-bit | 8-bit}
  1114.     mov    dx,offset distab    ; table
  1115.     xor    bx,bx            ; help is table
  1116.     call    comnd
  1117.     jc    vtbytex            ; c = failure
  1118.     push    bx
  1119.     mov    ah,cmeol        ; get a confirm
  1120.     call    comnd
  1121.     pop    bx
  1122.     jc    vtbytex            ; c = failure
  1123.     and    flags.remflg,not d8bit    ; clear display 8-bit bit
  1124.     or    flags.remflg,bl        ; set or clear the bit
  1125. vtbytex:ret
  1126.  
  1127. vtupss:    mov    ah,cmkey        ; SET TERM UPSS
  1128.     mov    bx,offset upsshlp    ; help
  1129.     mov    dx,offset upsstab    ; UPSS table
  1130.     call    comnd            ; get UPSS char set
  1131.     jc    vtupssx            ; failure
  1132.     push    bx
  1133.     mov    ah,cmeol
  1134.     call    comnd
  1135.     pop    bx
  1136.     jc    vtupssx            ; c = fail
  1137.     mov    al,96            ; assume 96 byte set
  1138.     or    bh,bh            ; one byte set identifier?
  1139.     jz    vtupss1            ; z = yes
  1140.     mov    al,94            ; a 94 byte set
  1141. vtupss1:mov    upss,al            ; set length
  1142.     mov    word ptr upss+1,bx    ; store set ident
  1143.     mov    vtemu.vtchop,-1        ; clear operational char set to reinit
  1144.     clc
  1145. vtupssx:ret
  1146.  
  1147. apcctl:    mov    ah,cmkey        ; SET TERM APC-macro enable, disable
  1148.     mov    bx,offset apchlp    ; help
  1149.     mov    dx,offset apctab    ; APC table
  1150.     call    comnd
  1151.     jc    apcctl1            ; failure
  1152.     push    bx
  1153.     mov    ah,cmeol
  1154.     call    comnd
  1155.     pop    bx
  1156.     jc    apcctl1            ; c = fail
  1157.     mov    apcenable,bl        ; enable flag
  1158.     clc
  1159. apcctl1:ret
  1160.  
  1161. vtenqctl:mov    ah,cmkey        ; SET TERM Answerback {ON, OFF}
  1162.     mov    bx,offset enqhlp    ; help
  1163.     mov    dx,offset ontab        ; on/off table
  1164.     call    comnd
  1165.     jc    vtenqctl1        ; failure
  1166.     push    bx
  1167.     mov    ah,cmeol
  1168.     call    comnd
  1169.     pop    bx
  1170.     jc    vtenqctl1        ; c = fail
  1171.     mov    vtenqenable,bl        ; enable (1) flag
  1172.     clc
  1173. vtenqctl1:ret
  1174.  
  1175. scrwrite:mov    ah,cmkey        ; SET TERM SCREEN-WRITING
  1176.     xor    bx,bx            ; help
  1177.     mov    dx,offset writetab    ; screen table
  1178.     call    comnd
  1179.     jc    scrwritx        ; failure
  1180.     push    bx
  1181.     mov    ah,cmeol
  1182.     call    comnd
  1183.     pop    bx
  1184.     jc    vtupssx            ; c = fail
  1185.     mov    writemode,bl        ; store writing mode
  1186.     clc
  1187. scrwritx:ret
  1188.  
  1189. expmemory:mov    ah,cmkey        ; EXPANDED-MEMORY {ON, OFF}
  1190.     mov    bx,offset expmhlp    ; help
  1191.     mov    dx,offset ontab        ; on/off table
  1192.     call    comnd
  1193.     jc    expmem2            ; failure
  1194.     push    bx
  1195.     mov    ah,cmeol
  1196.     call    comnd
  1197.     pop    bx
  1198.     jc    expmem2            ; c = fail
  1199.     cmp    useexp,bl        ; changing kinds?
  1200.     je    expmem1            ; e = no
  1201.     mov    vsbuff_inited,0        ; say reinitialize buffer memory
  1202.     mov    useexp,bl        ; enable (1) flag
  1203. expmem1:clc
  1204. expmem2:ret
  1205.  
  1206. vtcodepage:mov    ah,cmkey        ; SET TERM CODE-PAGE
  1207.     xor    bx,bx            ; help
  1208.     mov    dx,offset setchtab    ; Code Page table
  1209.     call    comnd
  1210.     jc    vtcode1            ; failure
  1211.     push    bx
  1212.     mov    ah,cmeol
  1213.     call    comnd
  1214.     pop    bx
  1215.     jc    vtcode1            ; c = fail
  1216.     mov    vtcpage,bx        ; new terminal Code Page
  1217.     mov    vtemu.vtchop,-1        ; force change of working set
  1218.     clc
  1219. vtcode1:ret
  1220.  
  1221. ; SET Term flags. These are the (near) equivalent of VT100 Setup mode values.
  1222. flg1:    mov    ax,vsnewline        ; NEWLINE
  1223.     mov    dx,offset ontab
  1224.     jmp    short flgset
  1225. flg2:    mov    ax,vswrap        ; WRAP
  1226.     mov    dx,offset ontab
  1227.     jmp    short flgset
  1228. flg4:    mov    ax,vswdir        ; DIRECTION
  1229.     mov    dx,offset dirtab
  1230.     jmp    short flgset
  1231. flg5:    mov    ax,vskeyclick        ; KEYCLICK
  1232.     mov    dx,offset ontab
  1233.     jmp    short flgset
  1234. flg6:    mov    ax,vsmarginbell        ; MARGIN BELL
  1235.     mov    dx,offset ontab
  1236.     jmp    short flgset
  1237. flg7:    mov    ax,vscursor        ; CURSOR
  1238.     mov    dx,offset curtab
  1239.     jmp    short flgset
  1240. flg8:    mov    ax,vsscreen        ; SCREEN
  1241.     mov    dx,offset scrtab
  1242.     jmp    short flgset
  1243. flg9:    mov    ax,vscntl        ; CONTROLS
  1244.     mov    dx,offset cntltab
  1245.     jmp    short flgset
  1246. flg10:    mov    ax,deckpam        ; KEYPAD
  1247.     mov    dx,offset kpamtab
  1248.     jmp    short flgset
  1249. flg11:    mov    ax,decckm        ; ARROW
  1250.     mov    dx,offset arrtab
  1251.     jmp    short flgset
  1252. flg12:    mov    ax,deccol        ; WIDTH
  1253.     mov    dx,offset widtab
  1254.     jmp    short flgset
  1255. flg13:    mov    ax,vshscroll        ; Horizontal scrolling
  1256.     mov    dx,offset hstab
  1257.     jmp    short flgset
  1258. flg14:    mov    ax,vscompress        ; compressed text display
  1259.     mov    dx,offset cmptab
  1260. ;;    jmp    short flgset
  1261.  
  1262. flgset:    push    ax            ; save flag
  1263.     mov    ah,cmkey        ; another keyword
  1264.     xor    bx,bx            ; use default help, dx has table ptr
  1265.     call    comnd
  1266.     pop    ax            ; recover index
  1267.     jc    flgse0            ; c = failure
  1268.     push    ax
  1269.     push    bx            ; save result of keyword
  1270.     mov    ah,cmeol        ; get confirm
  1271.     call    comnd
  1272.     pop    bx
  1273.     pop    ax            ; recover flag
  1274.     jc    flgse0            ; c = failure
  1275.     or    bx,bx            ; set or clear?
  1276.     jz    flgse1            ; z = clear it
  1277.     or    vtemu.vtflgst,ax    ; set the flag
  1278.     or    vtemu.vtflgop,ax    ; in runtime flags too
  1279. flgse3:    test    ax,deccol        ; modifying screen width?
  1280.     jz    flgse2            ; z = no
  1281.     mov    al,crt_cols        ; current width
  1282.     mov    dos_cols,al        ; width to remember, for changes
  1283. flgse2:    clc                ; success
  1284. flgse0:    ret     
  1285. flgse1: not    ax            ; Complement
  1286.     and    vtemu.vtflgst,ax    ; clear the indicated setup flag
  1287.     and    vtemu.vtflgop,ax    ; clear the indicated runtime flag
  1288.     not    ax
  1289.     jmp    short flgse3        ; test for screen change
  1290.      
  1291. ;    SET Term Tabstops Clear ALL
  1292. ;    SET Term Tabstops Clear AT n1, n2, ..., nx
  1293. ;    SET Term Tabstops At n1, n2, ..., nx
  1294.      
  1295. tabmod:    mov    ah,cmkey        ; parse keyword
  1296.     mov    bx,offset clrhlp    ; help text
  1297.     mov    dx,offset tabtab    ; table
  1298.     call    comnd
  1299.     jc    tabmo2            ; c = failure
  1300.     mov    clrset,2        ; 2 = code for set a tab
  1301.     or    bl,bl            ; clear?
  1302.     jnz    tabmo4            ; nz = no, SET. parse column number(s)
  1303.     mov    clrset,1        ; code for clear at/all tab(s)
  1304.     mov    ah,cmkey        ; CLEAR, parse ALL or AT
  1305.     mov    bx,offset clrhlp    ; help text
  1306.     mov    dx,offset alltab    ; parse ALL or AT
  1307.     call    comnd
  1308.     jc    tabmo2            ; c = failure
  1309.     or    bx,bx            ; ALL?
  1310.     jnz    tabmo4            ; nz = AT, clear at specific places
  1311.     mov    ah,cmeol        ; confirm the ALL
  1312.     call    comnd
  1313.     jc    tabmo2            ; c = failure
  1314.     mov    cx,vswidth        ; ALL, means clear all tab stops
  1315. tabmo1:    mov    dx,cx
  1316.     dec    dl            ; column number, starting with 0
  1317.     mov    si,vtemu.vttbs        ; the cold-start buffer
  1318.     call    ftabclr            ; clear the tab
  1319.     loop    tabmo1            ; do all columns
  1320.     mov    si,vtemu.vttbs
  1321.     mov    di,vtemu.vttbst        ; and active buffer
  1322.     call    tabcpy            ; update active tabs
  1323.     clc                ; success
  1324. tabmo2:    ret                ; a success/fail return point
  1325.  
  1326. tabmo4:    mov    si,vtemu.vttbs        ; from the cold-start buffer
  1327.     mov    di,offset decbuf    ; temp work buffer
  1328.     call    tabcpy            ; make a working copy of the tabs
  1329.     mov    skip,0            ; clear spacing-active flag
  1330.     mov    temp,0            ; place where last tab was written
  1331. tabmo6:    mov    bx,offset clrhlp2    ; tell them we want a column number
  1332.     mov    ah,cmword        ; get line of text
  1333.     mov    dx,offset rdbuf        ; temp buffer
  1334.     call    comnd
  1335.     jc    tabmo2            ; c = failure
  1336.     or    ax,ax            ; anything given?
  1337.     jnz    tabmo7            ; nz = yes
  1338.     mov    ah,cmeol        ; confirm end of line
  1339.     call    comnd
  1340.     jc    tabmo2            ; failure
  1341.     mov    si,offset decbuf    ; copy tabs from temp work buffer
  1342.     mov    di,vtemu.vttbs        ; to the cold-start buffer
  1343.     call    tabcpy            ; copy work to cold start
  1344.     mov    di,vtemu.vttbst        ; and terminal emulator's active buf
  1345.     call    tabcpy
  1346.     clc
  1347.     ret
  1348.  
  1349. tbsbad:    mov    ah,prstr        ; not in range - complain
  1350.     mov    dx,offset tbserr
  1351.     int    dos
  1352.     stc
  1353.     ret
  1354.      
  1355. tabmo7:    mov    si,offset rdbuf        ; si = place where atoi wants text
  1356. tabmo8:    mov    dx,si
  1357.     call    strlen            ; get length of this word
  1358.     jcxz    tabmo6            ; empty, get more user input
  1359.     mov    ah,cl            ; where atoi wants length
  1360.     call    atoi            ; convert text to numeric in ax
  1361.     jnc    tabmo9            ; nc = successful
  1362.     cmp    byte ptr [si],':'    ; spacing separator?
  1363.     jne    tbsbad            ; ne = no, no number available
  1364.     inc    si            ; skip colon, do start:space analysis
  1365.     inc    skip            ; set spacing-active flag
  1366.     jmp    short tabmo8        ; get another token
  1367.  
  1368. tabmo9:    cmp    skip,0            ; want spacing value now?
  1369.     jne    tabmo11            ; ne = yes, go do it
  1370.     mov    dx,ax            ; column (1-vswidth style)
  1371.     dec    dx            ; put column in range 0-131
  1372.     or    dx,dx            ; check range (1-vswidth-->0-...)
  1373.     js    tbsbad            ; s = too small. complain
  1374.     cmp    dl,vswidth-1        ; more than the right most column?
  1375.     ja    tbsbad            ; a = yes, quit
  1376.     mov    temp,dx            ; remember last written position
  1377.     jmp    tabmo15            ; and write this member
  1378.  
  1379. tabmo11:mov    dx,temp            ; continue spacing analysis
  1380.     mov    skip,0            ; clear spacing-active flag
  1381.     mov    cx,ax            ; "space" value
  1382.     or    cx,cx            ; zero spacing?
  1383.     jnz    tabmo12            ; nz = no
  1384.     inc    cx            ; don't get caught with zero spacing
  1385. tabmo12:cmp    dx,vswidth-1        ; largest tab stop
  1386.     ja    tabmo8            ; a = done largest tab stop
  1387.     mov    temp,dx            ; remember last written tabstop
  1388.     push    si
  1389.     mov    si,offset decbuf    ; the work buffer
  1390.     cmp    clrset,2        ; set?
  1391.     jne    tabmo13            ; ne = no, clear
  1392.     call    ftabset            ; set tabstop in column DL
  1393.     jmp    short tabmo14
  1394. tabmo13:call    ftabclr            ; clear tabstop in column DL
  1395. tabmo14:add    dx,cx            ; new column value
  1396.     pop    si
  1397.     jmp    short tabmo12        ; finish spacing loop
  1398.  
  1399. tabmo15:push    si            ; individual tabstop
  1400.     mov    si,offset decbuf    ; the work buffer
  1401.     cmp    clrset,2        ; set?
  1402.     jne    tabmo16            ; ne = no, clear
  1403.     call    ftabset            ; set tabstop in column DL
  1404.     jmp    short tabmo17        ; get next command value
  1405. tabmo16:call    ftabclr            ; clear tabstop in column DL
  1406. tabmo17:pop    si
  1407.     jmp    tabmo8            ; get next command value
  1408.  
  1409. tabcpy:    push    es            ; worker copy routine
  1410.     push    si
  1411.     push    di
  1412.     mov    cx,ds
  1413.     mov    es,cx
  1414.     mov    cx,(vswidth+7)/8    ; update all active tab stops
  1415.     cld
  1416.     rep    movsb
  1417.     pop    di
  1418.     pop    si
  1419.     pop    es
  1420.     clc                ; success
  1421.     ret
  1422. VTS    endp                ; end of Set Term things
  1423.  
  1424.           ; Terminal Status display, called within STAT0: in MSSSET
  1425. VTSTAT    proc    near            ; enter with di within sttbuf, save bx
  1426.     mov    bx,offset vtstbl    ; table of things to show
  1427.     jmp    statc            ; status common code, in mssset
  1428. vtstat    endp
  1429.  
  1430. colstat proc    near            ; worker for colstat
  1431.     push    si
  1432.     mov    si,offset colst1
  1433.     cld
  1434. colstd1:lodsb
  1435.     cmp    al,'$'            ; end of string?
  1436.     je    colstd2            ; e = yes
  1437.     stosb
  1438.     jmp    short colstd1
  1439. colstd2:mov    bx,vtemu.att_ptr    ; pointer to attributes byte
  1440.     mov    bl,byte ptr[bx]
  1441.     xor    bh,bh
  1442.     push    bx
  1443.     and    bx,7            ; get foreground set
  1444.     mov    al,colortb[bx]        ; get reversed bit pattern
  1445.     add    al,'0'            ; add ascii bias
  1446.     stosb
  1447.     pop    bx
  1448.     mov    si,offset colst2
  1449. colstd3:lodsb
  1450.     cmp    al,'$'
  1451.     je    colstd4
  1452.     stosb
  1453.     jmp    short colstd3
  1454. colstd4:mov    cl,4            ; rotate 4 positions
  1455.     shr    bl,cl
  1456.     and    bx,7            ; get background set
  1457.     mov    al,colortb[bx]        ; get reversed bit pattern
  1458.     add    al,'0'            ; add ascii bias
  1459.     stosb
  1460.     pop    si
  1461.     ret
  1462. colstat endp
  1463.  
  1464. tabstat proc    near            ; worker,display tabs ruler for Status
  1465.     push    dx
  1466.     cld
  1467.     mov    al,cr
  1468.     stosb
  1469.     cmp    cl,10            ; are we on a new line?
  1470.     jb    tabsta0            ; b = no, do a lf now
  1471.     mov    al,lf
  1472.     stosb
  1473. tabsta0:xor    cl,cl            ; column index
  1474.     xor    ax,ax            ; ah = tens, al = units counter
  1475. tabsta1:mov    dl,'.'            ; default position symbol
  1476.     inc    al
  1477.     cmp    al,10            ; time to roll over?
  1478.     jb    tabsta2            ; b = not yet
  1479.     xor    al,al            ; modulo 10
  1480.     inc    ah
  1481.     mov    dl,ah            ; display a tens-digit
  1482.     add    dl,'0'
  1483.     cmp    dl,'9'            ; larger than 90?
  1484.     jbe    tabsta2            ; be = no
  1485.     sub    dl,10            ; roll over to 0, 1, etc
  1486. tabsta2:push    dx
  1487.     push    si
  1488.     mov    dl,cl            ; column number, counted from 0
  1489.     mov    si,vtemu.vttbst        ; the active buffer
  1490.     call    istabs            ; is tab set here?
  1491.     pop    si
  1492.     pop    dx
  1493.     jnc    tabsta3            ; nc = no
  1494.     mov    dl,'T'            ; yes, display a 'T'
  1495. tabsta3:push    ax
  1496.     mov    al,dl
  1497.     stosb
  1498.     pop    ax
  1499.     inc    cl
  1500.     cmp    cl,byte ptr low_rgt    ; done yet?
  1501.     jb    tabsta1            ; b = not yet
  1502.     pop    dx
  1503.     ret
  1504. tabstat endp
  1505.  
  1506. ; Returns carry set if column in DL is a tab stop, else carry clear.
  1507. ; Enter with column number in DL (starts at column 0, max of vswidth-1)
  1508. ; and tabstop buffer offset in SI.
  1509. istabs    proc    near
  1510.     push    bx
  1511.     push    cx
  1512.     mov    cl,dl            ; column number (0 to swidth-1)
  1513.     and    cl,00000111b        ; keep bit in byte (0-7)
  1514.     inc    cl            ; map to 1-8
  1515.     mov    bl,dl            ; column
  1516.     shr    bl,1            ; bl / 8 to get byte
  1517.     shr    bl,1
  1518.     shr    bl,1
  1519.     xor    bh,bh            ; clear high byte
  1520.     mov    bl,[si+bx]        ; get a byte of tab bits
  1521.     ror    bl,cl            ; rotate to put tab-set bit into carry
  1522.     pop    cx
  1523.     pop    bx
  1524.     ret
  1525. istabs    endp
  1526.  
  1527. filler    proc    near            ; use space
  1528.     mov    cx,20
  1529.     mov    al,' '
  1530.     cld
  1531.     rep    stosb
  1532.     ret
  1533. filler    endp
  1534.  
  1535. ; Jump here to exit Connect mode and execute macros 'KEYBOARDR' (vtkrmac) or
  1536. ; 'KEYBOARDS' (vtksmac). Does nothing if macro does not exist.
  1537. ; Preserves registers except ax. Returns to TELNET caller with 'C' in kbdflg.
  1538. vtkrmac    proc    near            ; RESET macro
  1539.     mov    vtmacname,offset vtkrname ; select macro name
  1540.     mov    vtmaclen,vtkrlen    ; and its length
  1541.     call    dword ptr vtmacroptr    ; FAR pointer, finish in common code
  1542.     jc    vtkrmac1        ; c = failure
  1543.     jmp    far ptr endcon        ; end connect mode, do macro
  1544. vtkrmac1:ret
  1545. vtkrmac    endp
  1546.  
  1547. vtksmac    proc    near            ; SET macro
  1548.     mov    vtmacname,offset vtksname
  1549.     mov    vtmaclen,vtkslen
  1550.     call    dword ptr vtmacroptr    ; FAR pointer
  1551.     jc    vtksmac1        ; c = failure
  1552.     jmp    far ptr endcon        ; end connect mode, do macro
  1553. vtksmac1:ret
  1554. vtksmac    endp
  1555.  
  1556. ; Invoked by keyboard translator when an unknown keyboard verb is used as
  1557. ; a string definition, such as {\ktest}. Enter with vtmacname pointing to
  1558. ; uppercased verb name, asciiz, and vtmaclen set to its length.
  1559. extmacro proc    near
  1560.     call    dword ptr vtmacroptr    ; FAR pointer
  1561.     jc    extmac1            ; c = failure
  1562.     jmp    far ptr endcon        ; end connect mode, do macro
  1563. extmac1:ret
  1564. extmacro endp
  1565.  
  1566. ; Invokes macro PRODUCT with variables \%1..\%9
  1567. ; defined as the ascii renditions of the control sequence numeric paramters
  1568. ; param[0]..param[8], and sets script ARGC item to one greater than this.
  1569.  
  1570. product    proc    near
  1571.     call    far ptr prodwork    ; FAR pointer
  1572.     jc    prodmac1        ; c = failure
  1573.     jmp    far ptr endcon        ; end connect mode, do macro
  1574. prodmac1:ret
  1575. product    endp
  1576.  
  1577.                 ; support for vtmacro and fproduct
  1578. fdec2di    proc    far
  1579.     call    dec2di
  1580.     ret
  1581. fdec2di    endp
  1582.  
  1583. term    proc    near
  1584.     call    far ptr fterm
  1585.     ret
  1586. term    endp
  1587.  
  1588. fclrmod    proc    far
  1589.     call    clrmod
  1590.     ret
  1591. fclrmod    endp
  1592.  
  1593. fputmod    proc    far
  1594.     call    putmod
  1595.     ret
  1596. fputmod    endp
  1597.  
  1598. fcmblnk    proc    far
  1599.     call    cmblnk
  1600.     ret
  1601. fcmblnk    endp
  1602. fkbhold    proc    far
  1603.     call    kbhold
  1604.     ret
  1605. fkbhold    endp
  1606. fisfile    proc    far
  1607.     call    isfile
  1608.     ret
  1609. fisfile    endp
  1610. fprtchr    proc    far
  1611.     call    prtchr
  1612.     ret
  1613. fprtchr    endp
  1614. fkeybd    proc    far
  1615.     call    keybd
  1616.     ret
  1617. fkeybd    endp
  1618. fpntflsh proc    far
  1619.     call    pntflsh
  1620.     ret
  1621. fpntflsh endp
  1622. fpntchr    proc    far
  1623.     call    pntchr
  1624.     ret
  1625. fpntchr    endp
  1626. foutchr    proc    far
  1627.     call    outchr
  1628.     ret
  1629. foutchr    endp
  1630. fpcwait    proc    far
  1631.     call    pcwait
  1632.     ret
  1633. fpcwait    endp
  1634. fstrcpy    proc    far
  1635.     call    strcpy
  1636.     ret
  1637. fstrcpy    endp
  1638. fspath    proc    far
  1639.     call    spath
  1640.     ret
  1641. fspath    endp
  1642. fcrun    proc    far
  1643.     call    crun
  1644.     ret
  1645. fcrun    endp
  1646. fserini    proc    far
  1647.     call    serini
  1648.     ret
  1649. fserini    endp
  1650. vtinit    proc    near
  1651.     call    fvtinit
  1652.     ret
  1653. vtinit    endp
  1654.  
  1655. rtone    proc    near
  1656.     call    frtone
  1657.     ret
  1658. rtone    endp
  1659.  
  1660. rtpage    proc    near
  1661.     call    frtpage
  1662.     ret
  1663. rtpage    endp
  1664.  
  1665. lfone    proc    near
  1666.     call    flfone
  1667.     ret
  1668. lfone    endp
  1669.  
  1670. lfpage    proc    near
  1671.     call    flfpage
  1672.     ret
  1673. lfpage    endp
  1674.  
  1675. homwnd    proc    near
  1676.     call    fhomwnd
  1677.     ret
  1678. homwnd    endp
  1679. endwnd    proc    near
  1680.     call    fendwnd
  1681.     ret
  1682. endwnd    endp
  1683. dnwpg    proc    near
  1684.     call    fdnwpg
  1685.     ret
  1686. dnwpg    endp
  1687. dnone    proc    near
  1688.     call    fdnone
  1689.     ret
  1690. dnone    endp
  1691. upwpg    proc    near
  1692.     call    fupwpg
  1693.     ret
  1694. upwpg    endp
  1695. upone    proc    near
  1696.     call    fupone
  1697.     ret
  1698. upone    endp
  1699. fcptchr    proc    far
  1700.     call    cptchr
  1701.     ret
  1702. fcptchr    endp
  1703. fserrst    proc    far
  1704.     call    serrst
  1705.     ret
  1706. fserrst    endp
  1707. code    ends
  1708.  
  1709. code1    segment
  1710.     assume    cs:code1
  1711.                     ; Kermit startup time initialization
  1712. flclyini proc    far
  1713.     mov    ah,conout        ; write a space to determine
  1714.     mov    dl,' '            ; DOS's default cursor coloring
  1715.     int    dos
  1716.     call    getpcur            ; get current cursor position into dx
  1717.     mov    lincur,cx        ; save cursor type (scan line #'s)
  1718.     dec    dl            ; backup to last char
  1719.     or    dl,dl
  1720.     jns    lclyin5            ; ns = no problem
  1721.     xor    dl,dl            ; else set cursor back to left margin
  1722. lclyin5:call    setpcur            ; set the cursor
  1723.     call    getpcha            ; read current attributes into AH
  1724.     mov    scbattr,ah        ; save video attributes
  1725.     mov    savattr,ah        ; and saved attributes
  1726.     mov    dosattr,ah        ; and here too
  1727.     and    ah,att_bold        ; select intensity bit
  1728.     mov    userbold,ah        ; save bit for user Bold control
  1729.     mov    ega_mode,0        ; assume no EGA
  1730.     mov    ax,1200H        ; EGA: Bios alternate select
  1731.     mov    bl,10H            ; Ask for EGA info
  1732.     mov    bh,0ffH            ; Bad info, for testing
  1733.     mov    cl,0fH            ; Reserved switch settings
  1734.     int    screen            ; EGA, are you there?
  1735.     cmp    cl,0cH            ; Test reserved switch settings
  1736.     jge    lclyin1            ; ge = no EGA in use
  1737.     push    es
  1738.     mov    ax,40h            ; check Bios 40:87h for ega being
  1739.     mov    es,ax            ;  the active display adapter
  1740.     test    byte ptr es:[87h],8    ; is ega active?
  1741.     pop    es
  1742.     jnz    lclyin1            ; nz = no
  1743.     mov    ega_mode,1        ; yes, set flag to say so
  1744.     mov    crt_norm,3        ; assume color monitor is attached
  1745.     or    bh,bh            ; is color mode in effect?
  1746.     jz    lclyin1            ; z = yes
  1747.     mov    crt_norm,7        ; else use mode 7 for mono
  1748. lclyin1:call    scrseg            ; test running in an Environment
  1749.     call    dvtest            ; test for running under DESQview
  1750.     call    scrmod            ; read video state, get crt_mode
  1751.     mov    cursor,0        ; initial cursor
  1752.     mov    dosetcursor,-1        ; cursor position reminder, none
  1753.     mov    ax,low_rgt        ; lower right corner of screen
  1754.     mov    al,crt_mode
  1755.     mov    crt_norm,al        ; save as normal mode
  1756.     mov    ah,crt_cols
  1757.     mov    dos_cols,ah        ; remember for exiting Connect mode
  1758.     call    vsalloc            ; allocate memory for virtual screen
  1759.     jnc    lclyin4            ; nc = success
  1760.     mov    ah,prstr
  1761.     mov    dx,offset memerr    ; say not enough memory to operate
  1762.     int    dos
  1763.     mov    flags.extflg,1        ; set Kermit exit flag
  1764.     ret
  1765.  
  1766. lclyin4:call    vsinit            ; init terminal emulator module MSZ
  1767.     mov    bx,vtemu.att_ptr    ; attributes pointer
  1768.     mov    ah,dosattr        ; startup video attributes
  1769.     and    ah,not att_bold        ; emulation intensity to normal
  1770.     or    ah,userbold
  1771.     mov    [bx],ah            ; set initial emulation attributes
  1772.     and    vtemu.vtflgst,not deccol ; assume 80 column screen
  1773.     and    vtemu.vtflgop,not deccol
  1774.     cmp    crt_cols,80        ; screen cols now, wide screen?
  1775.     jbe    lclyin6            ; be = no
  1776.     or    vtemu.vtflgst,deccol    ; say using 132 columns screen
  1777.     or    vtemu.vtflgop,deccol
  1778. lclyin6:ret
  1779. flclyini endp
  1780.  
  1781. ; Allocate memory for virtual screen buffers vscreen and vsat.
  1782. ; Return carry clear if success, else carry set. Removes older allocations.
  1783. vsalloc    proc    near
  1784.     call    vsalloc4        ; free alloc'd memory, if any
  1785.     mov    al,crt_lins        ; one minus number of screen rows
  1786.     inc    al
  1787.     mov    cl,vswidth        ; virtual screen vscreen
  1788.     mul    cl            ; lines time width, words for vscreen
  1789.     add    ax,ax            ; need words
  1790.     add    ax,15            ; round up
  1791.     mov    cl,4            ; convert to paragraphs
  1792.     shr    ax,cl            ; need words rather than bytes
  1793.     mov    cx,ax            ; save total wanted paragraphs in cx
  1794.     mov    bx,ax            ; ask for the memory
  1795.     mov    ah,alloc        ; allocate memory
  1796.     int    dos            ; bx has # free paragraphs
  1797.     mov    word ptr vs_ptr+2,ax    ; seg of vsscreen (offset is zero)
  1798.     cmp    cx,bx            ; got what we wanted
  1799.     jb    vsalloc5        ; b = no
  1800.     push    es
  1801.     mov    es,ax
  1802.     xor    di,di
  1803.     shl    cx,1
  1804.     shl    cx,1
  1805.     shl    cx,1            ; paragraphs to words
  1806.     mov    ah,scbattr
  1807.     mov    al,' '
  1808.     cld
  1809.     rep    stosw             ; clear the memory with def colors
  1810.     pop    es
  1811.     mov    al,crt_lins
  1812.     inc    al            ; attributes (nibbles)
  1813.     mov    cl,(vswidth+1)/2    ; lines time width, bytes for vsattr
  1814.     mul    cl
  1815.     add    ax,15            ; round up
  1816.     mov    cl,4            ; convert to paragraphs
  1817.     shr    ax,cl
  1818.     mov    cx,ax            ; save total wanted paragraphs in cx
  1819.     mov    bx,ax            ; ask for the memory
  1820.     mov    ah,alloc        ; allocate the memory
  1821.     int    dos            ; bx has # free paragraphs
  1822.     mov    word ptr vsat_ptr+2,ax    ; seg of vsattr (offset is zero)
  1823.     cmp    cx,bx            ; got what we wanted
  1824.     jb    vsalloc4        ; b = no
  1825.     push    es
  1826.     mov    es,ax
  1827.     xor    di,di
  1828.     shl    cx,1
  1829.     shl    cx,1
  1830.     shl    cx,1
  1831.     shl    cx,1            ; paragraphs to bytes
  1832.     xor    al,al
  1833.     rep    stosb             ; clear the memory with def extattr
  1834.     pop    es
  1835.     clc                ; report success
  1836.     ret
  1837.  
  1838. vsalloc4:mov    ax,word ptr vsat_ptr+2    ; seg of vsattr (offset is zero)
  1839.     or    ax,ax            ; unused?
  1840.     jz    vsalloc5        ; z = yes
  1841.     push    es
  1842.     mov    es,ax            ; allocated segment
  1843.     mov    ah,freemem        ; free it
  1844.     int    dos
  1845.     mov    word ptr vsat_ptr+2,0    ; clear pointer too
  1846.     pop    es
  1847. vsalloc5:mov    ax,word ptr vs_ptr+2    ; seg of vsscreen
  1848.     or    ax,ax            ; unused?
  1849.     jz    vsalloc6        ; z = yes
  1850.     push    es
  1851.     mov    es,ax            ; allocated segment
  1852.     mov    ah,freemem        ; free it
  1853.     int    dos
  1854.     mov    word ptr vs_ptr+2,0    ; clear pointer too
  1855.     pop    es
  1856. vsalloc6:stc                ; return failure
  1857.     ret
  1858. vsalloc    endp
  1859.  
  1860. ; Allocate memory for screen rollback buffers.
  1861. ; Return carry clear if success, else carry set to exit.
  1862. vsbuff    proc    near            ; screen roll back buffers
  1863.     cmp    vsbuff_inited,0        ; inited yet?
  1864.     je    vsbuff0            ; e = no
  1865.     clc                ; say success
  1866.     ret
  1867. vsbuff0:mov    vsbuff_inited,1        ; say we are initializing
  1868.     cmp    emsrbhandle,-1        ; valide EMS rollback handle?
  1869.     je    vsbuff20        ; e = no
  1870.     mov    ah,emsrelease        ; release pages
  1871.     mov    dx,emsrbhandle        ; handle
  1872.     int    emsint
  1873.     mov    emsrbhandle,-1        ; invalidate EMS rollback handle
  1874.     mov    iniseg,0        ; and no segment for page frame
  1875.     jmp    short vsbuff21
  1876. vsbuff20:mov    ax,iniseg        ; memory segment, window area
  1877.     or    ax,ax            ; anything allocated?
  1878.     jz    vsbuff21        ; z = no
  1879.     mov    es,ax
  1880.     mov    ah,freemem        ; free regular memory segment
  1881.     int    dos
  1882.     mov    iniseg,0
  1883. vsbuff21:
  1884.     mov    bx,rollwidth        ; columns to roll back
  1885.     or    bx,bx            ; user override given?
  1886.     jnz    vsbuff1            ; nz = yes, else physical screen
  1887.     mov    bl,crt_cols        ; physical screen
  1888.     xor    bh,bh
  1889.     mov    rollwidth,bx        ; set final roll width
  1890. vsbuff1:add    bx,7            ; round up (cancel common times twos)
  1891.     mov    cl,3
  1892.     shr    bx,cl            ; bytes/line to paragraphs/line
  1893.     mov    ppl,bx            ; paragraphs/line
  1894.                     ; expanded memory
  1895.     cmp    useexp,0        ; use expanded memory?
  1896.     je    vsbuff5            ; e = no
  1897.     mov    ax,sp            ; do push sp test for XT vs AT/386
  1898.     push    sp            ; XT pushes sp-2, AT's push old sp
  1899.     pop    cx            ; recover pushed value, clean stack
  1900.     xor    ax,cx            ; same?
  1901.     jne    vsbuff5            ; ne = no, XT. Don't do Int 2fh
  1902.     mov    ax,xmspresent        ; XMS presence test
  1903.     int    2fh
  1904.     cmp    al,80h            ; present?
  1905.     jne    vsbuff5            ; ne = no
  1906.     mov    ah,getintv        ; get interrupt vector
  1907.     mov    al,emsint        ; EMS interrupt 67h
  1908.     int    dos            ; to es:bx
  1909.     mov    ax,es
  1910.     or    ax,bx            ; check for null
  1911.     jz    vsbuff5            ; z = interrupt not activated
  1912.     mov    ah,emsmgrstat        ; LIM 3.2 manager status
  1913.     int    emsint
  1914.     or    ah,ah            ; ok?
  1915.     jnz    vsbuff5            ; nz = not ok
  1916.     mov    ax,1024            ; 1024 paragraphs per ems 16KB page
  1917.     xor    dx,dx
  1918.     div    ppl            ; divide by paragraphs per line
  1919.     mov    lineems,ax        ; lines per ems page, remember
  1920.     mov    al,crt_lins        ; lines-1 per physical screen
  1921.     xor    ah,ah
  1922.     mov    cx,npages        ; number of roll back screens wanted
  1923.     inc    cx            ; include current screen
  1924.     mul    cx            ; times number screens
  1925.     div    lineems            ; lines total / (lines/emspage)
  1926.     or    dx,dx            ; remainder?
  1927.     jz    vsbuff2            ; z = no
  1928.     inc    ax            ; add page for fraction
  1929. vsbuff2:push    ax            ;  ax is number of emspages
  1930.     mov    ah,emsgetnpgs        ; get number pages free
  1931.     int    emsint            ; to bx
  1932.     pop    ax
  1933.     or    bx,bx            ; any pages free?
  1934.     jz    vsbuff5            ; z = no, use regular memory
  1935.     cmp    bx,ax            ; enough?
  1936.     jb    vsbuff3            ; b = less, use what we can get
  1937.     mov    bx,ax            ; number of pages wanted
  1938. vsbuff3:mov    ah,emsalloc        ; allocate bx pages
  1939.     int    emsint
  1940.     or    ah,ah            ; successful?
  1941.     jnz    vsbuff5            ; nz = no, failure
  1942.     mov    emsrbhandle,dx        ; returned handle
  1943.     mov    ax,bx            ; pages allocated
  1944.     mov    inipara,ax        ; save for later resizing of buffers
  1945.     mov    ah,emsgetseg        ; get segment of page frame
  1946.     int    emsint            ;  to bx
  1947.     mov    iniseg,bx        ; save here
  1948.     mov    ah,emsgetver        ; get EMS version number
  1949.     int    emsint            ; to al (high=major, low=minor)
  1950.     cmp    al,40h            ; at least LIM 4.0?
  1951.     jb    vsbuff4            ; b = no, so no name for our area
  1952.     mov    si,offset emsrollname    ; point to name for rollback area
  1953.     mov    di,offset emsrollname+6    ; add digits
  1954.     mov    dx,emsrbhandle
  1955.     mov    ax,dx
  1956.     call    fdec2di            ; write to handle name
  1957.     mov    ax,emssetname        ; set name for handle from ds:si
  1958.     int    emsint
  1959. vsbuff4:jmp    short vsbuff9
  1960.                     ; no ems, so use regular memory
  1961. vsbuff5:mov    useexp,0        ; say no ems
  1962.     mov    bx,0ffffh        ; ask for all of memory, to get size
  1963.     mov    ah,alloc        ; allocate all of memory (must fail)
  1964.     int    dos            ; bx has # free paragraphs
  1965.     mov    ax,bx            ; ax has copy of number free paragraphs
  1966.     sub    bx,26000D/16        ; space for Command.com copy #2
  1967.     jc    vsbuff7            ; c = not enough for it
  1968.     mov    ax,ppl            ; paragraphs / line
  1969.     mul    crt_lins        ; times lines-1 on physical screen
  1970.     cmp    bx,ax            ; minimum roll back space left over?
  1971.     jbe    vsbuff7            ; be = not even that much
  1972.     mov    cx,npages        ; number of roll back screens wanted
  1973.     inc    cx            ; include current screen
  1974.     mul    cx            ; total number of paragraphs wanted
  1975.     mov    cx,ax            ; save in cx
  1976.     or    dx,dx            ; want more than 1 MB of real memory?
  1977.     jz    vsbuff6            ; e = no
  1978.     mov    cx,0ffffh        ; set all of real memory
  1979. vsbuff6:cmp    bx,cx            ; got vs wanted paras for roll back
  1980.     jbe    vsbuff8            ; be = enough but not more than needed
  1981.     mov    bx,cx            ; limit to our actual needs
  1982.     jmp    short vsbuff8        ; ask for all we really want
  1983. vsbuff7:xor    bx,bx            ; use no space at all
  1984.     mov    cx,bx            ; remember this new request
  1985. vsbuff8:mov    ah,alloc
  1986.     int    dos
  1987.     mov    iniseg,ax        ; (BDT) memory segment, window area
  1988.     mov    inipara,bx        ; save for later resizing of buffers
  1989.     cmp    cx,bx            ; paragraphs wanted vs delivered
  1990.     jae    vsbuff9            ; ae = enough
  1991.     mov    ah,prstr
  1992.     mov    dx,offset memerr    ; say not enough memory to operate
  1993.     int    dos
  1994.     stc                ; carry set = fail
  1995.     ret
  1996. vsbuff9:call    bufadj             ; set roll back buffer parameters
  1997.     clc                ; carry clear for success
  1998.     ret
  1999. vsbuff    endp
  2000.  
  2001. scrini    proc    far            ; init screen stuff
  2002.     mov    al,crt_lins        ; screen lines - 1 
  2003.     mov    ah,crt_mode        ; preserve this too
  2004.     push    ax            ; save
  2005.     call    scrmod            ; get screen mode now
  2006.     mov    ax,100h            ; assume 80 column mode, no-renter
  2007.     test    vtemu.vtflgop,deccol    ; supposed to be in 80 col?
  2008.     jz    scrin5            ; z = yes
  2009.     inc    al            ; say want 132 cols
  2010. scrin5:    call    chgdsp            ; set to 80/132 columns
  2011.     call    scrmod            ; get crt_lins again
  2012.     pop    ax
  2013.     mov    crt_mode,ah        ; restore in case in graphics now
  2014.     cmp    al,crt_lins        ; changed?
  2015.     je    scrin2            ; e = no
  2016.     mov    vtinited,0        ; say must reinit emulator
  2017.     mov    cursor,0
  2018.     call    vsalloc            ; reallocate virtual screen
  2019.     jnc    scrin2            ; nc = success
  2020.     mov    ah,prstr
  2021.     mov    dx,offset memerr    ; say not enough memory to operate
  2022.     int    dos
  2023.     mov    sp,oldsp
  2024.     ret                ; must be Far return
  2025.     
  2026. scrin2:    mov    ega_mode,0        ; assume no EGA
  2027.     mov    ax,1200H        ; EGA: Bios alternate select
  2028.     mov    bl,10H            ; Ask for EGA info
  2029.     mov    bh,0ffH            ; Bad info, for testing
  2030.     mov    cl,0fH            ; Reserved switch settings
  2031.     int    screen            ; EGA, are you there?
  2032.     cmp    cl,0cH            ; Test reserved switch settings
  2033.     jge    scrin1            ; ge = no EGA in use
  2034.     push    es
  2035.     mov    ax,40h            ; check Bios 40:87h for ega being
  2036.     mov    es,ax            ;  the active display adapter
  2037.     test    byte ptr es:[87h],8    ; is ega active?
  2038.     pop    es
  2039.     jnz    scrin1            ; nz = no
  2040.     mov    ega_mode,1        ; yes, set flag to say so
  2041.     mov    crt_norm,3        ; assume color monitor is attached
  2042.     or    bh,bh            ; is color mode in effect?
  2043.     jz    scrin1            ; z = yes
  2044.     mov    crt_norm,7        ; else use mode 7 for mono
  2045. scrin1:    mov    bx,vtemu.att_ptr    ; attributes pointer
  2046.     mov    ah,[bx]
  2047.     and    ah,att_bold
  2048.     mov    userbold,ah        ; remember old bold
  2049.     mov    ah,savattr        ; saved emulator attributes
  2050.     mov    scbattr,ah        ; restore active value
  2051.     call    scrseg            ; update screen segment tv_seg(s/o)
  2052.     call    getpcur            ; get cursor position DX and type CX
  2053.     cmp    flags.vtflg,0        ; emulating anything?
  2054.     jne    scrin4            ; ne = yes
  2055.     mov    cursor,dx        ; use physical cursor
  2056. scrin4:    mov    dx,cursor        ; use old cursor, if any
  2057.     call    setpos            ; set cursor position
  2058.     cmp    vtinited,inited        ; inited emulator yet?
  2059.     je    scrin11            ; e = yes, do reinit
  2060.     call    fvtinit            ; init it now
  2061.     call    repaint            ; repaint screen
  2062.     ret
  2063.  
  2064. scrin11:cmp    flags.vtflg,tttek    ; Tek mode?
  2065.     je    scrin12            ; e = yes
  2066. ;;    test    tekflg,tek_tek+tek_dec     ; Tek submode?
  2067. ;;    jz    scrin14            ; z = no
  2068.     cmp    tekflg,tek_tek+tek_dec     ; Tek submode?
  2069.     jne    scrin14            ; ne = no
  2070. scrin12:call    tekini            ; init graphics mode
  2071.     ret
  2072.  
  2073. scrin14:call    ansrei            ; reinit the emulator
  2074.     call    repaint            ; restore screen from vscreen
  2075. scrin15:ret
  2076. scrini    endp
  2077.  
  2078. ; Initialize terminal emulators
  2079. fvtinit    proc    far
  2080.     mov    ax,apcstring        ; seg of apcmacro memory area
  2081.     or    ax,ax            ; empty?
  2082.     jz    vtini4            ; z = yes
  2083.     mov    es,ax
  2084.     mov    ah,freemem
  2085.     int    dos            ; free that memory
  2086.     mov    apcstring,0
  2087. vtini4:    mov    holdscr,0        ; clear holdscreen
  2088.     mov    vtclear,0        ; clear clear-screen indicator
  2089.     call    fkbhold            ; tell DEC LK250 the state, in msuibm
  2090.     or    vtinited,inited
  2091.     mov    ax,vtemu.vtflgst    ; Setup flags
  2092.     mov    vtemu.vtflgop,ax    ; to operational
  2093.     mov    dosetcursor,0        ; cursor position reminder, none
  2094.     mov    bx,portval
  2095.     mov    dl,[bx].ecoflg        ; local echo flag
  2096.     and    yflags,not lclecho
  2097.     or    yflags,dl
  2098.     mov    bx,argadr        ; address of argument block
  2099.     mov    dl,[bx].baudb        ; baud rate code in dl
  2100.     mov    dh,[bx].parity        ; parity code in bits
  2101.     mov    cl,4            ; 0-3 of dh
  2102.     shl    dh,cl
  2103.     or    dh,07H            ; just say 7 data bits
  2104.     test    flags.remflg,d8bit    ; eight bit display?
  2105.     jz    vtini1            ; z = no
  2106.     inc    dh            ; set low four bits to value 8
  2107. vtini1:    cmp    flags.vtflg,0        ; doing emulation?
  2108.     je    vtini3            ; e = no
  2109.     cmp    tekflg,tek_active+tek_tek ; Tek graphics mode?
  2110.     je    vtini2            ; e = yes, do it's reinit
  2111.     cmp    tekflg,tek_active+tek_dec ; Tek graphics submode?
  2112.     je    vtini2            ; e = yes, do it's reinit
  2113.     xor    ax,ax            ; assume 80 col mode (al=0)
  2114.     test    vtemu.vtflgst,deccol    ; want wide display?
  2115.     jz    vtini1a            ; z = no
  2116.     inc    al            ; set AL to 1 for set 132 col mode
  2117. vtini1a:call    chgdsp            ; set screen width
  2118.     call    ansini            ; call startup routine in mszibm
  2119.     cmp    flags.vtflg,tttek    ; full Tek mode?
  2120.     jne    vtinix            ; ne = no
  2121.     or    tekflg,tek_tek        ; say tek mode
  2122.     jmp    short vtini2        ; e = yes
  2123. vtinix:    clc
  2124.     ret
  2125. vtini2:    call    tekrint            ; reinitialize Tek emulator
  2126.     clc
  2127.     ret
  2128. vtini3:    call    fcmblnk            ; clear the screen
  2129.     clc
  2130.     ret
  2131. fvtinit    endp
  2132.  
  2133. argini    proc    near            ; read passed arguments
  2134.     mov    bx,argadr        ; base of argument block
  2135.     mov    al,[bx].flgs        ; get flags
  2136.     and    al,capt+emheath+trnctl+lclecho+modoff
  2137.     mov    yflags,al        ; mask for allowable and save
  2138.     mov    al,[bx].prt
  2139.     mov    portno,al        ; update port number
  2140.     ret
  2141. argini    endp
  2142.  
  2143. fterm    proc    FAR            ; terminal mode entry point
  2144.     mov    argadr,ax        ; save argument ptr
  2145.     mov    oldsp,sp        ; remember stack for i/o failure,
  2146.     mov    apctrap,0        ; un-trap certain commands
  2147.     cmp    flags.comflg,'t'    ; doing internal Telnet?
  2148.     jne    fterm2            ; ne = not Telnet
  2149.     cmp    termlatch,0        ; have we been here for macro?
  2150.     jne    fterm2            ; ne = yes, reset it and skip macro
  2151.     mov    termlatch,1        ; arm reentry bypass
  2152.     mov    bx,sescur        ; get session to bl
  2153.     call    vtsesmac        ; this returns us to the Kermit prompt
  2154.     jc    fterm2            ; c = no such macro
  2155. fterm1:    call    fserrst            ; shut down serial port now
  2156.     mov    kbdflg,'C'         ; say exit Connect mode
  2157.     ret                ; return, to process macro
  2158.  
  2159. fterm2:    mov    termlatch,0        ; disable bypass, enable macro again
  2160.     mov    handhsc,0        ; cancel hand scrolling
  2161.     call    vsbuff            ; allocate screen buffer memory
  2162.     jc    fterm1            ; c = failure, quit now
  2163.     call    argini            ; init options from arg address
  2164.     mov    inemulator,1        ; say in terminal emulator (local)
  2165.     call    scrini            ; call screen setup
  2166.     mov    grab,0            ; clear Compose/Spcl output grabber
  2167.     or    kbcodes,80h        ; set need-to-init flg for kbd xtlator
  2168.     mov    fairprn,0        ; set printer buffer flush counter
  2169. lp:    call    fprtchr            ; char at port?
  2170.     jnc    short lpinp        ; nc = yes, go handle
  2171.     cmp    tekflg,tek_active+tek_sg ; special graphics active?
  2172.     jne    lpcross            ; ne = no, stay in idle loop
  2173.     mov    dx,dosetcursor        ; preserved cursor position
  2174.     cmp    dx,-1            ; should we set the cursor?
  2175.     je    lpcursor        ; e = no
  2176.     call    teksetcursor        ; set the cursor at dx
  2177.     mov    dosetcursor,-1        ; turn off reminder
  2178.  
  2179. lpcursor:test    flags.vtflg,ttd463+ttd470 ; doing DG D463/D470 emulation?
  2180.     jz    lpcross            ; z = not DG
  2181.     cmp    dgcross,0        ; is DG crosshair active?
  2182.     je    lpcross            ; e = no
  2183.     xor    al,al            ; feed it a null command, to do mouse
  2184.     call    croshair        ; call Tek crosshair to read mouse
  2185. lpcross:push    bx
  2186.     mov    bx,portval        ; port structure address
  2187.     cmp    [bx].portrdy,0        ; is port ready for business?
  2188.     pop    bx
  2189.     jne    lpkbd            ; ne = ready
  2190.     jmp    quit            ; end the communications now
  2191. lpkbd:    mov    fairness,0        ; say kbd was examined
  2192.     call    dvpause            ; tell DESQview we are not busy
  2193.     inc    fairprn            ; inc printer dump counter
  2194.     cmp    fairprn,100        ; been here enough times now?
  2195.     jb    lpkbd1            ; b = no
  2196.     call    fpntflsh        ; flush printer buffer
  2197.     jnc    lpkbd0            ; nc = success
  2198.     call    pntdead            ; call bad printer notifier
  2199. lpkbd0:    mov    fairprn,0        ; reset for next time
  2200. lpkbd1:    call    fkeybd            ; call keyboard translator in msu
  2201.     jc    quit            ; carry set = quit connect mode
  2202.     jmp    short lp        ; and repeat idle loop
  2203.  
  2204. lpinp:    and    al,parmsk        ; apply 8/7 bit parity mask
  2205.     call    outtty            ; print on terminal
  2206.     inc    fairness        ; say read port but not kbd, again
  2207.     cmp    fairness,100        ; this many port reads before kbd?
  2208.     jb    lp            ; b = no, read port again
  2209.     jmp    short lpkbd        ; yes, let user have a chance too
  2210.  
  2211. quit:    mov    sp,oldsp        ; recover startup stack pointer
  2212.                     ; TERM caller's return address is now
  2213.                     ; on the top of stack. A longjmp.
  2214.     mov    ah,scbattr        ; current emulator attributes
  2215.     mov    savattr,ah        ; save them here
  2216.     call    fpntflsh        ; flush printer buffer
  2217.     call    tekend            ; cleanup Tektronix mode
  2218.  
  2219.     mov    inemulator,0        ; say not in terminal emulator (local)
  2220.     mov    al,1
  2221.     call    csrtype            ; turn on underline cursor
  2222.     mov    ah,dosattr        ; attributes at init time
  2223.     mov    scbattr,ah        ; background = original state
  2224.     call    fclrmod            ; clear mode line with DOS attributes
  2225.     mov    ax,100h            ; assume using 80 col screen
  2226.     cmp    dos_cols,80        ; startup screen width
  2227.     jbe    quit1            ; be = assume 80 columns
  2228.     inc    al            ; say do 132 columns
  2229. quit1:
  2230.     push    vtemu.vtflgop
  2231.     or    vtemu.vtflgop,vscompress ; turn off compressed mode
  2232.     call    chgdsp            ; reset display width to startup
  2233.     pop    vtemu.vtflgop
  2234.     call    scrmod            ; update size info
  2235.                     ; for ega in non-standard # lines
  2236.     test    tv_mode,10h        ; DV active?
  2237.     jnz    quit2            ; nz = yes, it messes with the cursor
  2238.     cmp    ega_mode,0        ; ega board active?
  2239.     je    quit2            ; e = no
  2240.     cmp    byte ptr low_rgt+1,23    ; is screen standard length?
  2241.     je    quit2            ; e = yes, so regular cursor set is ok
  2242.     push    es            ; turn off ega cursor emulation
  2243.     mov    ax,40h            ; byte 40:87H is ega Info byte
  2244.     mov    es,ax
  2245.     push    es:[87h]        ; save info byte around call
  2246.     or    byte ptr es:[87h],1    ; set emulation off (low bit = 1)
  2247.     mov    cx,lincur        ; cursor shape to set
  2248.     mov    ah,1            ; set the shape
  2249.     int    screen            ;   back to starting value
  2250.     pop    es:[87h]        ; recover original Info byte
  2251.     pop    es            ; and our work reg
  2252.     jmp    short quit3        ; skip regular mode cursor setting
  2253. quit2:                    ; for regular sized screen
  2254.     mov    cx,lincur        ; cursor type at startup
  2255.     mov    ah,1
  2256.     int    screen            ; restore cursor type
  2257. quit3:     mov    dh,byte ptr low_rgt+1    ; bottom line -1
  2258.     xor    dl,dl            ; left most column
  2259.     call    setpcur            ; set cursor physical position
  2260.     mov    al,yflags
  2261.     mov    bx,argadr
  2262.     mov    [bx].flgs,al        ; update flags in arg block
  2263.     call    dvpause            ; tell DESQview we are not busy
  2264.     ret
  2265. fterm    endp
  2266.  
  2267. ; put the character in al to the screen
  2268. outtty    proc    near
  2269.     test    flags.remflg,d8bit    ; keep 8 bits for displays?
  2270.     jnz    outtt1            ; nz = yes, 8 bits if possible
  2271.     and    al,7fh            ; remove high bit
  2272. outtt1:    cmp    flags.vtflg,0        ; emulating a terminal?
  2273.     je    outnp10            ; e = no
  2274.     cmp    vtroll,0        ; auto roll back allowed?
  2275.     je    outem1            ; e = no, leave screen as is
  2276.     test    tekflg,tek_active    ; Tek mode active?
  2277.     jnz    outem1            ; nz = yes, skip screen rolling
  2278.     push    ax            ; (BDT) save this for a tad
  2279.     mov    ax,linec        ; (BDT) are we at the buffer end?
  2280.     cmp    ax,lcnt
  2281.     pop    ax            ; (BDT) restore the register
  2282.         je      outem1            ; (BDT) e = yes
  2283.     push    ax            ; (BDT) save AX again
  2284.     call    fendwnd            ; do END to roll screen to end of buf
  2285.     pop    ax            ; (BDT) restore the register
  2286. outem1:    test    tekflg,tek_active    ; graphics mode active?
  2287.     jz    outem2            ; z = no
  2288.     test    tekflg,tek_tek+tek_dec    ; Tek submode active for input?
  2289.     jnz    outem3            ; nz = yes, use Tek emulator
  2290. outem2:    call    anstty            ; call terminal emulator, char in AL
  2291.     ret
  2292. outem3:    call    tekemu            ; use Tek emulator and return
  2293.     ret
  2294.                          ; use DOS for screen output
  2295. outnp10:test    flags.remflg,d8bit    ; keep 8 bits for displays?
  2296.     jnz    outnp9            ; nz = yes, 8 bits if possible
  2297.     and    al,7fh            ; remove high bit
  2298. outnp9:    cmp    rxtable+256,0        ; translation turned off?
  2299.     je    outnp7            ; e = yes, no translation
  2300.     push    bx
  2301.     mov    bx,offset rxtable    ; address of translate table
  2302.     xlatb                ; new char is in al
  2303.     pop    bx
  2304. outnp7:    test    anspflg,prtscr        ; should we be printing?
  2305.     jz    outnp8            ; no, keep going
  2306.     call    fpntchr            ; queue char for printer
  2307.     jnc    outnp8            ; nc = successful print
  2308.     push    ax
  2309.     call    vtbell            ; else make a noise and
  2310.     call    ftrnprs            ;  turn off printing
  2311.     pop    ax
  2312. outnp8:    test    yflags,capt        ; capturing output?
  2313.     jz    outnp6            ; no, forget this part
  2314.     call    fcptchr            ; give it captured character
  2315. outnp6:    test    yflags,trnctl        ; debug? if so use Bios tty mode
  2316.     jz    outnp4            ; z = no
  2317.     mov    ah,conout        ; DOS screen write
  2318.     cmp    al,7fh            ; Ascii Del char or greater?
  2319.     jb    outnp1            ; b = no
  2320.     je    outnp0            ; e = Del char
  2321.     push    ax            ; save the char
  2322.     mov    dl,7eh            ; output a tilde for 8th bit
  2323.     int    dos
  2324.     pop    ax            ; restore char
  2325.     and    al,7fh            ; strip high bit
  2326. outnp0:    cmp    al,7fh            ; is char now a DEL?
  2327.     jne    outnp1            ; ne = no
  2328.     and    al,3fH            ; strip next highest bit (Del --> '?')
  2329.     jmp    outnp2            ; send, preceded by caret
  2330. outnp1:    cmp    al,' '            ; control char?
  2331.     jae    outnp3            ; ae = no
  2332.     add    al,'A'-1        ; make visible
  2333. outnp2:    push    ax            ; save char
  2334.     mov    dl,5eh            ; caret
  2335.     int    dos            ; display it
  2336.     pop    ax            ; recover the non-printable char
  2337. outnp3:    push    ax
  2338.     mov    dl,al
  2339.     int    dos
  2340.     pop    ax
  2341.     ret
  2342. outnp4:    cmp    al,bell            ; bell (Control G)?
  2343.     jne    outnp5            ; ne = no
  2344.     jmp    vtbell            ; use short beep, avoid char loss
  2345. outnp5:    mov    dl,al            ; write without intervention
  2346.     mov    ah,conout
  2347.     int    dos            ; else let dos display char
  2348.     ret
  2349. outtty    endp
  2350.      
  2351. ;[IU2] Here to output an unsigned 8-bit number (in al) to the port
  2352. ; Used by terminal emulator escape sequence output.
  2353.      
  2354. prtnout proc    near
  2355.     jmp    short prtno2        ; ensure at least a zero
  2356.      
  2357. prtno1: or    al,al
  2358.     jnz    prtno2            ; nz = yes, do more digits
  2359.     ret                ; no, return from recursive call
  2360. prtno2: xor    ah,ah            ; clear previous remainder
  2361.     mov    bl,10            ; output in base 10
  2362.     div    bl            ; divide off a digit
  2363.     push    ax            ; push remainder (in ah) on stack
  2364.     call    prtno1            ; recurse
  2365.     pop    ax            ; pop off a digit
  2366.     add    ah,'0'            ; make it ASCII
  2367.     mov    al,ah            ; send to port, in ah
  2368.     call    outprt
  2369.     jc    prtno3            ; failure, end connection
  2370.     ret
  2371. prtno3:    jmp    far ptr endcon
  2372. prtnout endp
  2373.  
  2374. ; Send the character in al out to the serial port; handle echoing.
  2375. ; Can send an 8 bit char while displaying only 7 bits locally.
  2376. outprt    proc    near
  2377.     mov    ah,1            ; say local echo is permitted
  2378.     jmp    short outprt0
  2379.  
  2380. prtbout:xor    ah,ah            ; no local echo
  2381.  
  2382. outprt0:cmp    grab,0            ; grabbing output?
  2383.     je    outprt0a        ; e = no
  2384.     call    fgrabber        ; yes, give it to the guy
  2385.     ret
  2386. outprt0a:test    al,80h            ; high bit set?
  2387.     jz    outpr2            ; z = no
  2388.     test    flags.vtflg,ttd463+ttd470 ; Data General?
  2389.     jz    outprt4            ; z = no
  2390.     test    flags.remflg,d8bit    ; chop DG high bit?
  2391.     jnz    outpr2            ; nz = no, send as-is
  2392.     and    al,7fh            ; chop high bit
  2393.     jmp    short outpr1        ; send with possible DG SI/SO brackets
  2394.  
  2395. outprt4:cmp    al,0a0h            ; C1 area?
  2396.     jae    outpr1            ; ae = no
  2397.     test    vtemu.vtflgop,vscntl    ; sending 8-bit controls?
  2398.     jz    outprt5            ; z = no, force use of 7-bit controls
  2399.     cmp    parmsk,7fh        ; using parity?
  2400.     jne    outpr2            ; ne = no, no need to force on that
  2401. outprt5:push    ax            ; save char
  2402.     mov    al,Escape        ; C1 as ESCAPE <char-40h>
  2403.     call    outpr2            ; send ESCAPE
  2404.     pop    ax            ; recover char
  2405.     sub    al,40h            ; relocate the code
  2406.     jmp    short outpr2        ; send the char
  2407.                     ; GRight printable characters
  2408. outpr1:    cmp    flags.vtflg,ttgenrc    ; doing term type of NONE?
  2409.     je    outpr2            ; e = yes, no tables (maybe SO/SI?)
  2410.     cmp    parmsk,7fh        ; using parity?
  2411.     jne    outpr2            ; ne = no, no shifts needed
  2412.     cmp    flags.oshift,0        ; allowing shifts on output?
  2413.     je    outpr2            ; e = no
  2414.     and    al,not 80h        ; strip high bit
  2415.     test    flags.oshift,8        ; Auto?
  2416.     jnz    outpr1a            ; nz = yes
  2417.     test    flags.oshift,1        ; force SI/SO?
  2418.     jnz    outpr8            ; nz = yes
  2419.     jmp    short outpr1b        ; else SS2/SS3
  2420. outpr1a:cmp    GRptr,offset G1set    ; GR points to G1 char set?
  2421.     je    outpr8            ; e = yes, use SO/char/SI
  2422. outpr1b:push    ax            ; save char
  2423.     mov    al,Escape        ; send SS2 as ESC N
  2424.     call    outpr2            ; ESC N is Single Shift 2
  2425.     mov    al,'N'
  2426.     cmp    flags.oshift,4        ; force SS3?
  2427.     jb    outpr7            ; b = force SS2
  2428.     je    outpr1c            ; e = force SS3
  2429.     cmp    GRptr,offset G2set    ; GR points to G2 char set?
  2430.     je    outpr7            ; e = yes, else use SS3 (ESC P)
  2431. outpr1c:inc    al            ; use ESC P for Single Shift 3
  2432. outpr7:    call    outpr2
  2433.     pop    ax            ; recover char
  2434.     jmp    short outpr2
  2435.  
  2436. outpr8:    push    ax            ; save char
  2437.     mov    al,SOchar        ; SO locking shift 1 for G1 to GL
  2438.     cmp    flags.vtflg,ttd463+ttd470 ; D463/D470?
  2439.     jz    outpr8a            ; z = no
  2440.     mov    al,DGescape        ; send SO as DG's  RS N
  2441.     call    outpr2
  2442.     mov    al,'N'
  2443. outpr8a:call    outpr2            ; send it
  2444.     pop    ax
  2445.     push    ax            ; preserve ah around call
  2446.     call    outpr2            ; send real character (7 bit'd)
  2447.     pop    ax
  2448.     mov    al,SIchar        ; shift back to normal
  2449.     test    flags.vtflg,ttd463+ttd470 ; D463/D470?
  2450.     jz    outpr2            ; z = no
  2451.     mov    al,DGescape        ; send SI as DG's  RS O
  2452.     call    outpr2
  2453.     mov    al,'O'
  2454.  
  2455. outpr2:    or    ah,ah            ; local echo permitted?
  2456.     jz    outpr3            ; z = no
  2457.     test    yflags,lclecho        ; echoing?
  2458.     jz    outpr3            ; z = no, forget it
  2459.     push    ax            ; save char
  2460.     call    outtty            ; display it
  2461.     pop    ax            ; restore
  2462.     cmp    flags.comflg,'t'    ; doing Telnet?
  2463.     jne    outpr3            ; ne = no
  2464.     cmp    al,CR            ; sending CR?
  2465.     jne    outpr3            ; ne = no
  2466.     push    ax
  2467.     mov    al,LF            ; locally show LF which we will send
  2468.     call    outtty
  2469.     pop    ax
  2470. outpr3:    mov    ah,al            ; this is where outchr expects it
  2471.     call    foutchr            ; output to the port
  2472.     jc    outpr4            ; c = failure
  2473.     ret
  2474. outpr4:    jmp    far ptr endcon        ; failure, end connection
  2475. outprt    endp
  2476.  
  2477. fansdsl    proc    far
  2478.     call    ansdsl
  2479.     ret
  2480. fansdsl    endp
  2481.  
  2482. foutprt    proc    far
  2483.     call    outprt
  2484.     ret
  2485. foutprt    endp
  2486.  
  2487. fprtbout proc    far
  2488.     call    prtbout
  2489.     ret
  2490. fprtbout endp
  2491.  
  2492. fprtnout proc    far
  2493.     call    prtnout
  2494.     ret
  2495. fprtnout endp
  2496.  
  2497. ; Product macro worker
  2498. prodwork proc    far
  2499.     push    si
  2500.     push    di
  2501.     push    es
  2502.     mov    ax,ds
  2503.     mov    es,ax
  2504.     mov    di,offset decbuf+2    ; macro def buffer starts here
  2505.     mov    si,offset prodname    ; pointer to macro name
  2506.     mov    cx,vtplen        ; length of macro name
  2507.     cld
  2508.     rep    movsb            ; copy to rdbuf+2
  2509.     mov    byte ptr [di],0        ; null terminator
  2510.     mov    cx,nparam        ; number of parameters
  2511.     cmp    cx,9            ; more than 9?
  2512.     jle    produc1            ; le = no
  2513.     mov    cx,9            ; limit to 9
  2514. produc1:jcxz    produc3            ; z = none
  2515.     xor    bx,bx            ; parameter subscript
  2516. produc2:push    bx
  2517.     push    cx
  2518.     mov    al,' '            ; and a space separator
  2519.     stosb
  2520.     shl    bx,1            ; address words
  2521.     mov    ax,param[bx]        ; get parameter to use as definition
  2522.     call    fdec2di            ; convert numerics to ascii string
  2523.     pop    cx
  2524.     pop    bx
  2525.     inc    bx
  2526.     loop    produc2
  2527. produc3:xor    al,al            ; safety terminator
  2528.     mov    [di],al            ; don't count in length
  2529.     mov    ax,di
  2530.     sub    ax,offset decbuf + 2    ; compute length
  2531.     mov    vtmaclen,ax        ; pass along to vtmacro
  2532.     mov    vtmacname,offset decbuf+2 ; say this is our macro text ptr
  2533.     pop    si
  2534.     pop    di
  2535.     pop    es
  2536.     jmp    short vtmacro
  2537. prodwork endp
  2538.  
  2539. ;
  2540. ; Reference    Macro structure for    db    number of entries (mac names)
  2541. ;  is file     table mcctab       |->    dw    length of macroname
  2542. ;  mssset.asm        each entry |->     db    'macroname'
  2543. ;  where these               |->    dw    segment:0 of definition string
  2544. ;  are stored.                      (offset part is always 0)    
  2545. ;        Definition string in     db    length of <string with null>
  2546. ;         buffer macbuf          db    'string with trailing null'
  2547. ;
  2548. vtmacro    proc    far            ; common code for macros vtsmac,vtrmac
  2549.     push    bx            ; and Product
  2550.     push    cx
  2551.     push    si
  2552.     push    di
  2553.     push    es
  2554.     mov    ax,ds
  2555.     mov    es,ax
  2556.     mov    di,offset decbuf+2    ; macro def buffer starts here
  2557.     mov    si,vtmacname        ; pointer to macro name
  2558.     mov    cx,vtmaclen        ; length of macro name<sp/null>text
  2559.     mov    [di-2],cx        ; counted string field
  2560.     cld
  2561.     rep    movsb            ; copy to rdbuf
  2562.     mov    byte ptr [di],0        ; null terminator
  2563.     mov    si,offset decbuf+2    ; look for name-text separator
  2564.     mov    cx,vtmaclen
  2565. vtmac1:    lodsb
  2566.     cmp    al,' '            ; space separator?
  2567.     je    vtmac1a            ; e = yes, stop here
  2568.     or    al,al            ; null terminator?
  2569.     jz    vtmac1a            ; e = yes, stop here
  2570.     loop    vtmac1
  2571.     inc    si            ; to do null length correctly
  2572. vtmac1a:sub    si,offset decbuf+2+1    ; compute length of macro name
  2573.     mov    cx,si
  2574.     mov    vtmaclen,cx        ; save a macro name length
  2575.                     ; check for existence of macro
  2576.     mov    bx,offset mcctab    ; table of macro names
  2577.     mov    cl,[bx]            ; number of names in table
  2578.     xor    ch,ch
  2579.     jcxz    vtmacx            ; z = empty table, do nothing
  2580.     inc    bx            ; point to length of first name
  2581. vtmac2:    mov    ax,[bx]            ; length of this name
  2582.     cmp    ax,vtmaclen        ; length same as desired keyword?
  2583.     jne    vtmac3            ; ne = no, search again
  2584.     mov    si,bx
  2585.     add    si,2            ; point at first char of name
  2586.     push    cx            ; save name counter
  2587.     push    di            ; save reg
  2588.     mov    cx,vtmaclen        ; length of name
  2589.     mov    di,vtmacname        ; point at desired macro name
  2590.     push    es            ; save reg
  2591.     push    ds
  2592.     pop    es            ; make es use data segment
  2593.     cld
  2594.     repe    cmpsb            ; match strings
  2595.     pop    es            ; need current si below
  2596.     pop    cx
  2597.     pop    di            ; recover saved regs
  2598.     je    vtmac4            ; e = matched
  2599. vtmac3:    add    bx,ax            ; step to next name, add name length
  2600.     add    bx,4            ; + count and def word ptr
  2601.     loop    vtmac2            ; try next name
  2602. vtmacx:    pop    es
  2603.     pop    di
  2604.     pop    si            ; no macro, return to Connect mode
  2605.     pop    cx
  2606.     pop    bx
  2607.     stc                ; say failure
  2608.     ret
  2609.  
  2610. vtmac4:    cmp    taklev,maxtak        ; room in Take level?
  2611.     jge    vtmacx            ; ge = no, exit with no action
  2612.     inc    taklev            ; increment take level
  2613.     add    takadr,size takinfo    ; make a new Take entry/macro
  2614.     mov    bx,takadr        ; point to current macro structure
  2615.     mov    ax,ds            ; segment of rdbuf
  2616.     mov    [bx].takbuf,ax        ; segment of definition string struc
  2617.     mov    cx,word ptr decbuf    ; length of count + string
  2618.     mov    [bx].takcnt,cx        ; number of chars in definition
  2619.     mov    [bx].takargc,0        ; our argument count
  2620.     mov    [bx].takptr,offset decbuf+2 ; where to read next command char
  2621.     mov    [bx].taktyp,0ffh    ; flag as a macro
  2622.     pop    es
  2623.     pop    di
  2624.     pop    si
  2625.     pop    cx
  2626.     pop    bx
  2627.     clc                ; say success, can exit connect mode
  2628.     ret
  2629. vtmacro    endp
  2630.  
  2631. ; APC macro
  2632. apcmacro proc    near
  2633.     cmp    taklev,maxtak        ; room in take level?
  2634.     jb    apcmac1            ; b = yes
  2635.     stc                ; fail
  2636.     ret
  2637. apcmac1:inc    taklev            ; increment take level
  2638.     add    takadr,size takinfo    ; make a new Take entry/macro
  2639.     mov    bx,takadr        ; point to current macro structure
  2640.     mov    ax,apcstring        ; segment of buffer
  2641.     mov    [bx].takbuf,ax        ; segment of definition string struc
  2642.     mov    [bx].takcnt,cx        ; number of chars in definition
  2643.     mov    [bx].takargc,0        ; our argument count
  2644.     mov    [bx].takptr,0         ; where to read next command char
  2645.     mov    [bx].taktyp,0ffh    ; flag as a macro
  2646.     cmp    apcenable,2        ; enable all commands?
  2647.     je    apcmac2            ; e = yes
  2648.     mov    apctrap,1        ; trap certain commands
  2649. apcmac2:jmp    far ptr endcon        ; exit Connect mode cleanly
  2650. apcmacro endp
  2651.  
  2652. ; Error recovery routine used when outchr reports unable to send character
  2653. ;  or when vtmacro requests exiting Connect mode.
  2654. ; Exit Connect mode cleanly, despite layers of intermediate calls.
  2655. endcon    proc    FAR
  2656.     mov    kbdflg,'C'        ; report 'C' to TERM's caller
  2657.     mov    sp,oldsp        ; recover startup stack pointer
  2658.                     ; TERM caller's return address is now
  2659.                     ; on the top of stack. A longjmp.
  2660.     jmp    quit            ; exit Connect mode cleanly
  2661. endcon    endp
  2662. code1    ends
  2663.  
  2664. code    segment
  2665.     assume    cs:code
  2666. ;;; Action routines (verbs) for keyboard translator KEYBD in msuibm.
  2667. ; These are invoked by a jump instruction. Return carry clear for normal
  2668. ; processing, return carry set for invoking Quit (kbdflg has transfer char).
  2669. uparrw:    mov    al,'A'            ; cursor keys
  2670.     jmp    short comarr
  2671. dnarrw:    mov    al,'B'
  2672.     jmp    short comarr
  2673. rtarr:    mov    al,'C'
  2674.     test    vtemu.vtflgop,vswdir    ; writing left to right?
  2675.     jz    comarr            ; z = yes
  2676.     mov    al,'D'            ; reverse sense of keys
  2677.     jmp    short comarr
  2678. lfarr:    mov    al,'D'
  2679.     test    vtemu.vtflgop,vswdir    ; writing left to right?
  2680.     jz    comarr            ; z = yes
  2681.     mov    al,'C'            ; reverse sense of keys
  2682.  
  2683. comarr:    test    flags.vtflg,ttd463+ttd470 ; DG D463/D470?
  2684.     jz    comar4            ; z = no
  2685.     sub    al,'A'            ; translate to DG 463/470 form
  2686.     cmp    tekflg,tek_active+tek_sg ; in special graphics mode?
  2687.     jne    comar5            ; ne = no
  2688.     test    dgcross,1        ; DG crosshair active?
  2689.     jz    comar5            ; z = no
  2690.     test    dgcross,2        ; DG crosshair active for keypad?
  2691.     jz    comar5            ; z = no
  2692.     mov    bx,offset dgcrostab    ; use scan code table instead
  2693.     xlatb
  2694.     call    croshair        ; send AL to graphics to move cursor
  2695.     ret
  2696.  
  2697. comar5:    mov    bx,offset dgcurtab    ; VT to DG cursor code table
  2698.     xlatb
  2699.     push    ax            ; setup for comar3
  2700.     jmp    short comar3
  2701.  
  2702. comar4:    push    ax            ; save final char
  2703.     mov    ttyact,0        ; network, group chars for packet
  2704.     test    vtemu.vtflgop,decanm    ; ANSI mode?
  2705.     jz    comar2            ; z = no
  2706.     mov    al,CSI            ; CSI character
  2707.     test    vtemu.vtflgop,decckm    ; cursor keys in application mode?
  2708.     jz    comar1            ; z = no, in cursor mode
  2709.     mov    al,SS3            ; SS3 character
  2710. comar1:    call    foutprt            ; send in 7 or 8 bit form, with echo
  2711.     jmp    short comar3
  2712.  
  2713. comar2:    mov    al,escape        ; do Heath/VT52 mode "ESC char"
  2714.     call    foutprt
  2715. comar3: pop    ax            ; recover final char
  2716.     mov    ttyact,1        ; network, restore tty active flag
  2717.     call    foutprt
  2718.     ret
  2719.  
  2720. pf1:    mov    al,'P'            ; keypad function keys PF1-4
  2721.     jmp    short compf
  2722. pf2:    mov    al,'Q'
  2723.     jmp    short compf
  2724. pf3:    mov    al,'R'
  2725.     jmp    short compf
  2726. pf4:    mov    al,'S'
  2727. compf:    push    ax            ; save final char
  2728.     mov    ttyact,0        ; network, group chars for packet
  2729.     test    vtemu.vtflgop,decanm    ; ansi mode?
  2730.     jz    short compf1        ; z = no
  2731.     mov    al,SS3
  2732.     call    foutprt            ; send 7 or 8 bit version
  2733.     jmp    short compf2
  2734. compf1:    mov    al,escape        ; output ESC
  2735.     call    foutprt
  2736. compf2: pop    ax            ; get the saved char
  2737.     mov    ttyact,1        ; network, restore tty active flag
  2738.     call    foutprt
  2739.     ret
  2740.  
  2741. ignore_key:                ; key is to be ignored
  2742.     ret
  2743.  
  2744. kp0:    mov    al,'p'            ; keypad numeric keys
  2745.     jmp    short comkp
  2746. kp1:    mov    al,'q'
  2747.     jmp    short comkp
  2748. kp2:    mov    al,'r'
  2749.     jmp    short comkp
  2750. kp3:    mov    al,'s'
  2751.     jmp    short comkp
  2752. kp4:    mov    al,'t'
  2753.     jmp    short comkp
  2754. kp5:    mov    al,'u'
  2755.     jmp    short comkp
  2756. kp6:    mov    al,'v'
  2757.     jmp    short comkp
  2758. kp7:    mov    al,'w'
  2759.     jmp    short comkp
  2760. kp8:    mov    al,'x'
  2761.     jmp    short comkp
  2762. kp9:    mov    al,'y'
  2763.     jmp    short comkp
  2764. kpminus:mov    al,'m'
  2765.     jmp    short comkp
  2766. kpcoma:    mov    al,'l'
  2767.     jmp    short comkp
  2768. kpenter:mov    al,'M'
  2769.     jmp    short comkp
  2770. kpdot:    mov    al,'n'
  2771. comkp:    test    vtemu.vtflgop,deckpam    ; keypad application mode active?
  2772.     jnz    comkp1            ; nz = yes, use escape sequences
  2773.     sub    al,40h            ; deduct offset to numeric symbols
  2774.     push    ax            ; save final char
  2775.     jmp    short comkp3        ; and send that single char
  2776. comkp1:    push    ax
  2777.     mov    ttyact,0        ; network, group chars for packet
  2778.     test    vtemu.vtflgop,decanm    ; ANSI mode?
  2779.     jz    comkp2            ; z = no
  2780.     mov    al,SS3            ; SS3 character
  2781.     call    foutprt            ; send 7 or 8 bit version
  2782.     jmp    short comkp3
  2783. comkp2:    mov    al,escape        ; output "ESC ?"
  2784.     call    foutprt
  2785.     mov    al,'?'
  2786.     call    foutprt
  2787. comkp3:    pop    ax            ; recover final char
  2788.     mov    ttyact,1        ; network, restore tty active flag
  2789.     call    foutprt            ; send it
  2790.     ret
  2791.  
  2792. klogon    proc    near            ; resume logging (if any)
  2793.     test    flags.capflg,logses    ; session logging enabled?
  2794.     jz    klogn            ; z = no, forget it
  2795.     push    bx
  2796.     mov    bx,argadr
  2797.     or    [bx].flgs,capt        ; turn on capture flag
  2798.     pop    bx
  2799.     or    yflags,capt        ; set local msy flag as well
  2800. klogn:    clc
  2801.     ret
  2802. klogon    endp
  2803.  
  2804. klogof    proc    near            ; suspend logging (if any)
  2805.     push    bx
  2806.     mov    bx,argadr
  2807.     and    [bx].flgs,not capt    ; stop capturing
  2808.     pop    bx
  2809.     and    yflags,not capt        ; reset local msy flag as well
  2810.     clc
  2811.     ret
  2812. klogof    endp
  2813.  
  2814. snull    proc    near            ; send a null byte
  2815.     xor    al,al            ; the null
  2816.     call    fprtbout        ; send without logging and local echo
  2817.     ret
  2818. snull    endp
  2819.  
  2820. khold:    xor    holdscr,1        ; toggle Hold screen byte for msx
  2821.     call    kbhold            ; tell DEC LK250 the hold kbd state
  2822.     clc                ;  kbhold is in file msuibm.asm
  2823.     ret
  2824.  
  2825. ; Data General "Fn" function keys
  2826. dgkf1:    mov    al,113            ; F1 sends RS q
  2827.     jmp    short dgkeyccom
  2828. dgkf2:    mov    al,114            ; F2 sends RS r
  2829.     jmp    short dgkeyccom
  2830. dgkf3:    mov    al,115            ; F3 sends RS s
  2831.     jmp    short dgkeyccom
  2832. dgkf4:    mov    al,116            ; F4 sends RS t
  2833.     jmp    short dgkeyccom
  2834. dgkf5:    mov    al,117            ; F5 sends RS u
  2835.     jmp    short dgkeyccom
  2836. dgkf6:    mov    al,118            ; F6 sends RS v
  2837.     jmp    short dgkeyccom
  2838. dgkf7:    mov    al,119            ; F7 sends RS w
  2839.     jmp    short dgkeyccom
  2840. dgkf8:    mov    al,120            ; F8 sends RS x
  2841.     jmp    short dgkeyccom
  2842. dgkf9:    mov    al,121            ; F9 sends RS y
  2843.     jmp    short dgkeyccom
  2844. dgkf10:    mov    al,122            ; F10 sends RS z
  2845.     jmp    short dgkeyccom
  2846. dgkf11:    mov    al,123            ; F11 sends RS {
  2847.     jmp    short dgkeyccom
  2848. dgkf12:    mov    al,124            ; F12 sends RS |
  2849.     jmp    short dgkeyccom
  2850. dgkf13:    mov    al,125            ; F13 sends RS }
  2851.     jmp    short dgkeyccom
  2852. dgkf14:    mov    al,126            ; F14 sends RS ~
  2853.     jmp    short dgkeyccom
  2854. dgkf15:    mov    al,112            ; F15 sends RS p
  2855.     jmp    short dgkeyccom
  2856.  
  2857. ; Data General "C" keys C1..C4
  2858. dgkc1:    mov    al,92            ; C1 sends RS \
  2859.     jmp    short dgkeyccom
  2860. dgkc2:    mov    al,93            ; C2 sends RS ]
  2861.     jmp    short dgkeyccom
  2862. dgkc3:    mov    al,95            ; C3 sends RS ^
  2863.     jmp    short dgkeyccom
  2864. dgkc4:    mov    al,96            ; C4 sends RS _
  2865. dgkeyccom:                ; common code
  2866.     push    ax
  2867.     mov    al,DGescape        ; send DG escape (RS)
  2868.     call    fprtbout        ; with no echo
  2869.     pop    ax
  2870.     call    fprtbout        ; send the second byte
  2871.     ret
  2872.  
  2873. ; Keyboard "Compose" key to compose characters by the three stroke method
  2874. kbdcompose proc    near
  2875.     mov    grab,1            ; say grabbing normal output
  2876.     call    togmod
  2877.     call    togmod            ; update mode line
  2878.     ret
  2879. kbdcompose endp
  2880.  
  2881. ; DG POINT (aka CMD CURSOR-TYPE)
  2882. dgpoint    proc    near
  2883.     cmp    tekflg,tek_active+tek_sg ; special graphics mode?
  2884.     jne    dgpoint1        ; ne = no, ignore cmd
  2885.     call    dgcrossrpt        ; send crosshair report
  2886. dgpoint1:ret
  2887. dgpoint    endp
  2888.  
  2889. ; DG N/C (normal, compressed font) key
  2890. dgnckey proc    near
  2891.     test    flags.vtflg,ttd470+ttd463 ; DG terminal?
  2892.     jz    dgnckey1        ; z = no, ignore
  2893.     call    dgnctoggle        ; toggle normal/compressed mode
  2894. dgnckey1:clc
  2895.     ret
  2896. dgnckey endp
  2897.  
  2898. ; Compose char lookup and reemitter.
  2899. fgrabber proc    far
  2900.     push    bx
  2901.     mov    bx,grab            ; count chars grabbed (want two)
  2902.     dec    bx            ; first char becomes bx=0
  2903.     mov    grabbox[bx],al        ; stuff char in short buffer
  2904.     cmp    bx,1            ; got both chars?
  2905.     pop    bx
  2906.     jae    fgrab2            ; ae = yes, go produce output
  2907.     inc    grab            ; keep grabbing
  2908.     ret                ; return for the second
  2909.                     ; process the byte pair
  2910. fgrab2:    mov    grab,0            ; say done grabbing output
  2911.     push    dx            ; compose new single char result
  2912.     push    di
  2913.     push    es
  2914.     mov    di,seg data1
  2915.     mov    es,di
  2916.     mov    di,offset grl1lat    ; use Latin1 ptr
  2917.     test    flags.vtflg,ttd463+ttd470 ; DG D463/D470?
  2918.     jz    fgrab3            ; z = no
  2919.     cmp    dgkbl,16        ; Latin1?
  2920.     je    fgrab3            ; e = yes
  2921.     mov    di,offset grl1dgi    ; get DG Internat ptr to structure
  2922.     cmp    dgkbl,20        ; DG keyboard language, DG Internat?
  2923.     jne    fgrab15            ; ne = no
  2924. fgrab3:    mov    ax,word ptr grabbox    ; get pair of chars
  2925.     call    toupper            ; convert AX to upper case
  2926.     call    match
  2927.     jnc    fgrab11            ; nc = found
  2928.     xchg    ah,al
  2929.     call    match
  2930.     jnc    fgrab11            ; nc = match
  2931.  
  2932. fgrab5:    mov    di,offset grl2lat    ; use Latin1 ptr
  2933.     test    flags.vtflg,ttd463+ttd470 ; DG D463/D470?
  2934.     jz    fgrab6            ; z = no
  2935.     cmp    dgkbl,16        ; Latin1?
  2936.     je    fgrab6            ; e = yes
  2937.     mov    di,offset grl2dgi    ; get DG Internat ptr to structure
  2938.     cmp    dgkbl,20        ; DG keyboard language, DG Internat?
  2939.     jne    fgrab15            ; ne = no
  2940. fgrab6:    mov    ax,word ptr grabbox
  2941.     mov    dx,ax
  2942.     call    toupper            ; convert AX to upper case
  2943.     call    match
  2944.     jnc    fgrab7            ; nc = found
  2945.     xchg    ah,al            ; try reversed order
  2946.     xchg    dh,dl
  2947.     call    match
  2948.     jc    fgrab8            ; c = not found
  2949. fgrab7:    cmp    dl,'a'            ; lower case char?
  2950.     jb    fgrab11            ; b = no, upper case
  2951.     or    al,20h            ; move to lower case output codes
  2952.     jmp    short fgrab11
  2953.  
  2954. fgrab8:    mov    di,offset grl3lat    ; use Latin1 ptr
  2955.     test    flags.vtflg,ttd463+ttd470 ; DG D463/D470?
  2956.     jz    fgrab9            ; z = no
  2957.     cmp    dgkbl,16        ; Latin1?
  2958.     je    fgrab9            ; e = yes
  2959.     mov    di,offset grl3dgi    ; get DG Internat ptr to structure
  2960.     cmp    dgkbl,20        ; DG keyboard language, DG Internat?
  2961.     jne    fgrab15            ; ne = no
  2962. fgrab9:    mov    ax,word ptr grabbox
  2963.     xchg    ah,al
  2964.     call    match            ; look for matching combination
  2965.     jc    fgrab16            ; c = failed
  2966. fgrab11:call    foutprt            ; send it to the host
  2967. fgrab15:call    togmod
  2968.     call    togmod            ; update mode line
  2969.     pop    es
  2970.     pop    di
  2971.     pop    dx
  2972.     ret
  2973.  
  2974. fgrab16:call    fvtbell            ; mismatch, beep, cancel
  2975.     jmp    short fgrab15        ;  finish up
  2976. fgrabber endp
  2977.  
  2978.                     ; worker for above
  2979. match    proc    near
  2980.     push    bx
  2981.     push    si
  2982.     push    di
  2983.     mov    cl,es:[di]        ; get count of pairs
  2984.     xor    ch,ch
  2985.     inc    di
  2986.     mov    si,di            ; start of char lists
  2987.     jcxz    match2            ; nothing to look at
  2988.     mov    si,di            ; remember where pairs start
  2989.     mov    bx,di
  2990.     add    bx,cx
  2991.     add    bx,cx            ; output singles start here
  2992.     cld
  2993.     push    cx            ; save counter
  2994.     repne    scasw            ; look for a match
  2995.     pop    cx
  2996.     jne    match2            ; ne = no match
  2997.     sub    di,2            ; backup to match
  2998.     sub    di,si            ; get item count
  2999.     shr    di,1            ; count bytes
  3000.     mov    al,es:[bx+di]        ; get new output char
  3001.     pop    di
  3002.     pop    si
  3003.     pop    bx
  3004.     clc                ; say success
  3005.     ret
  3006. match2:    pop    di
  3007.     pop    si
  3008.     pop    bx
  3009.     stc                ; say no match
  3010.     ret
  3011. match    endp
  3012.  
  3013. toupper    proc    near
  3014.     cmp    ah,'a'            ; less that lower A?
  3015.     jb    toupp1            ; b = yes, leave untouched
  3016.     cmp    ah,'z'            ; more than lower Z?
  3017.     ja    toupp1            ; a = yes
  3018.     and    ah,not 20H        ; convert to uppercase
  3019. toupp1:    cmp    al,'a'            ; less that lower A?
  3020.     jb    toupp2            ; b = yes, leave untouched
  3021.     cmp    al,'z'            ; more than lower Z?
  3022.     ja    toupp2            ; a = yes
  3023.     and    al,not 20H        ; convert to uppercase
  3024. toupp2:    ret
  3025. toupper    endp
  3026.  
  3027. ; DEC LK201 keyboard keys and "User Definable Keys" in VT3xx mode
  3028. decfind:mov    al,1            ; Find
  3029.     jmp    udkout
  3030. decinsert:mov    al,2            ; Insert
  3031.     jmp    udkout
  3032. decremove:mov    al,3            ; Remove
  3033.     jmp    udkout
  3034. decselect:mov    al,4            ; Select
  3035.     jmp    udkout
  3036. decprev:mov    al,5            ; Previous screen
  3037.     jmp    udkout
  3038. decnext:mov    al,6            ; Next screen
  3039.     jmp    udkout
  3040. decf6:    mov    al,17            ; key ident for DEC F6
  3041.     jmp    udkout            ; process it
  3042. decf7:    mov    al,18            ; key ident for DEC F7
  3043.     jmp    udkout            ; process it
  3044. decf8:    mov    al,19            ; key ident for DEC F8
  3045.     jmp    udkout            ; process it
  3046. decf9:    mov    al,20            ; key ident for DEC F9
  3047.     jmp    udkout            ; process it
  3048. decf10:    mov    al,21            ; key ident for DEC F10
  3049.     jmp    udkout            ; process it
  3050. decf11:    mov    al,23            ; key ident for DEC F11
  3051.     jmp    udkout            ; process it
  3052. decf12:    mov    al,24            ; key ident for DEC F12
  3053.     jmp    udkout            ; process it
  3054. decf13:    mov    al,25            ; key ident for DEC F13
  3055.     jmp    udkout            ; process it
  3056. decf14:    mov    al,26            ; key ident for DEC F14
  3057.     jmp    udkout            ; process it
  3058. dechelp:mov    al,28            ; key ident for DEC HELP
  3059.     jmp    udkout            ; process it
  3060. decdo:    mov    al,29            ; key ident for DEC DO
  3061.     jmp    udkout            ; process it
  3062. decf17:    mov    al,31            ; key ident for DEC F17
  3063.     jmp    udkout            ; process it
  3064. decf18:    mov    al,32            ; key ident for DEC F18
  3065.     jmp    udkout            ; process it
  3066. decf19:    mov    al,33            ; key ident for DEC F19
  3067.     jmp    udkout            ; process it
  3068. decf20:    mov    al,34            ; key ident for DEC F20
  3069.     jmp    udkout            ; process it
  3070.  
  3071. ; common worker to output contents of User Definable Key definition strings
  3072. ; Enter with al = key ident (17 - 34)
  3073. udkout    proc    near
  3074.     push    ax
  3075.     push    bx
  3076.     push    cx
  3077.     push    es
  3078.     test    flags.vtflg,ttvt320+ttvt220 ; VT320/VT220?
  3079.     jnz    udkout3            ; nz = yes, else use VT100/VT52 default
  3080.     test    flags.vtflg,tttek    ; Tek?
  3081.     jnz    udkout3            ; nz = yes, try this
  3082.     cmp    al,23            ; F11 sends ESC
  3083.     jne    udkou1a            ; ne = not F11
  3084.     mov    al,escape
  3085.     call    foutprt
  3086.     jmp    udkoutx
  3087. udkou1a:cmp    al,24            ; F12 sends BS
  3088.     jne    udkou1b            ; ne = not F12
  3089.     mov    al,BS
  3090.     call    foutprt
  3091.     jmp    udkoutx
  3092. udkou1b:cmp    al,25            ; F13 sends LF
  3093.     jne    udkou1c            ; ne = not F13, ignore
  3094.     mov    al,LF
  3095.     call    foutprt
  3096. udkou1c:jmp    udkoutx
  3097.  
  3098. udkout3:mov    bl,al            ; VT3XX key ident, UDK style (17-34)
  3099.     cmp    al,6            ; is this the CSI 1-6 set?
  3100.     jbe    udkout4            ; be = yes, do separately
  3101.     sub    bl,17            ; minus starting offset of 17
  3102.     xor    bh,bh
  3103.     cmp    bl,17            ; out of range?
  3104.     ja    udkoutx            ; a = yes, ignore
  3105.     shl    bx,1            ; index words
  3106.     mov    bx,udkseg[bx]        ; segment of definition
  3107.     or    bx,bx            ; anything there?
  3108.     jz    udkout4            ; z = no, use DEC defaults below
  3109.     mov    es,bx            ; definition segment
  3110.     xor    bx,bx            ;  and offset
  3111.     mov    cl,es:[bx]        ; get string length byte
  3112.     xor    ch,ch            ; use cx as a counter
  3113.     jcxz    udkout4            ; z = empty, use defaults
  3114. udkou3a:inc    bx            ; es:bx is now the string text
  3115.     mov    al,es:[bx]        ; get a char
  3116.     push    bx
  3117.     push    cx
  3118.     push    es
  3119.     call    foutprt            ; output
  3120.     pop    es
  3121.     pop    cx
  3122.     pop    bx
  3123.     loop    udkou3a
  3124.     jmp    short udkoutx        ; done
  3125.  
  3126. udkout4:push    ax            ; VT320, use default definitions
  3127.     mov    al,CSI            ; char to send
  3128.     call    foutprt            ; send lead-in char in 7/8-bit form
  3129.     pop    ax
  3130.     call    fprtnout        ; key ident (17-34) as ascii digits
  3131.     mov    al,7eh            ; tilde terminator
  3132.     call    foutprt
  3133. udkoutx:pop    es
  3134.     pop    cx
  3135.     pop    bx
  3136.     pop    ax
  3137.     clc
  3138.     ret
  3139. udkout    endp
  3140.  
  3141. ; Change Telnet sessions
  3142. nextses proc    near
  3143.     cmp    flags.comflg,'t'    ; doing Telnet?
  3144.     je    nextses1        ; e = yes
  3145.     clc                ; do not exit Connect mode
  3146.     ret
  3147. nextses1:mov    bx,sescur        ; current session ident
  3148.     mov    cx,6            ; sessions to consider
  3149. nextses3:inc    bx
  3150.     cmp    bx,6            ; over the top yet
  3151.     jb    nextses4            ; b = no
  3152.     xor    bx,bx            ; wrap
  3153. nextses4:cmp    seslist[bx],0        ; is this session active?
  3154.     jge    nextses5        ; ge = yes
  3155.     loop    nextses3
  3156.     clc
  3157.     ret                ; do nothing
  3158.  
  3159. nextses5:push    bx
  3160.     mov    bx,sescur        ; old session
  3161.     call    termswapout        ; save current terminal items
  3162.     pop    bx
  3163.     mov    sescur,bx        ; next session, from above
  3164.     call    tcpstart        ; start session, ident in bl
  3165.     mov    bx,sescur        ; new session
  3166.     call    termswapin        ; get data structures
  3167.     mov    kbdflg,' '        ; return Connect mode
  3168.     stc                ; but exit Connect mode now
  3169.     ret
  3170. nextses endp
  3171.  
  3172. vtsesmac  proc    far            ; SESSION macro
  3173.     mov    vtmacname,offset vtsesname
  3174.     mov    al,bl            ; session number
  3175.     add    al,'1'            ; to ascii, from 1
  3176.     mov    vtsesnum,al        ; to name
  3177.     mov    vtmaclen,vtseslen
  3178.     call    dword ptr vtmacroptr    ; FAR pointer
  3179.     ret
  3180. vtsesmac endp
  3181.  
  3182. ; Call from mszibm DG components to put system into DG special graphics mode,
  3183. ; and thus to cause incoming material to be still sent to the text emulator.
  3184. ; This also unshifts the screen (as seen on the status line) before starting
  3185. ; graphics so the column 81 stuff comes out right.
  3186. dgsettek proc    far
  3187.     cmp    tekflg,tek_active+tek_sg ; inited already?
  3188.     je    dgsettek3        ; e = yes
  3189.     push    bx
  3190.     push    cx
  3191.     mov    cl,byte ptr low_rgt+1    ; examine whole screen
  3192.     inc    cl            ; lines in emulation part
  3193.     xor    ch,ch
  3194.     mov    bx,cx            ; for status line
  3195.     xor    al,al
  3196.     xchg    al,linescroll[bx]    ; status line scroll value
  3197.     or    al,al
  3198.     jz    dgsettek2        ; z = no shift in effect
  3199.     xor    bx,bx            ; start of screen
  3200. dgsettek1:sub    linescroll[bx],al    ; unscroll by status line amount
  3201.     inc    bx            ; next line
  3202.     loop    dgsettek1        ; do all emulation lines
  3203. dgsettek2:pop    cx
  3204.     pop    bx
  3205.     or    tekflg,tek_sg        ; set special graphics mode
  3206.     call    TEKINI            ; go to Tektronix Emulator
  3207. dgsettek3:ret
  3208. dgsettek endp
  3209.  
  3210. code    ends
  3211.  
  3212. code1    segment
  3213.     assume    cs:code1
  3214.  
  3215. ; Set (define) the DEC "User Definable Keys". Inserts text definitions for
  3216. ; keyboard verbs \KdecF6 ...\KdecF14, \KdecHELP, \KdecDO, \KdecF17...\KdecF20.
  3217. ; Enter with the DCS definition string as key-number/hex-chars. UDK key number
  3218. ; is 17 for \KdecF6, et seq, the definition are pairs of hex digits converted
  3219. ; here to a single byte per pair. The DCS definition string is pointed at by
  3220. ; DS:SI, and the byte count is in CX.
  3221. ; Example:  17/54657374204636   means key \KdecF6 sends string "Test F6"
  3222. setudk    proc    near
  3223.     push    ax
  3224.     push    bx
  3225.     push    cx
  3226.     push    si
  3227.     push    di
  3228.     push    es
  3229.     cld
  3230.     lodsb                ; get key ident first byte
  3231.     sub    al,'0'            ; ascii to binary
  3232.     mul    ten            ; times 10
  3233.     xchg    ah,al            ; to ah
  3234.     lodsb                ; get key ident second byte
  3235.     sub    al,'0'            ; ascii to binary
  3236.     add    al,ah            ; plus high order part
  3237.     xor    ah,ah
  3238.     mov    bx,ax            ; key ident, 17 - 34
  3239.     lodsb                ; skip slash separator
  3240.     sub    cx,3            ; three less bytes in the string
  3241.     jge    setudk0            ; ge = had three or more bytes
  3242.     jmp    setudkx            ; else error
  3243. setudk0:sub    bx,17            ; remove key ident bias of 17
  3244.     cmp    bx,17            ; out of range?
  3245.     ja    setudkx            ; a = yes, ignore
  3246.     shl    bx,1            ; index words
  3247.     cmp    udkseg[bx],0        ; has a segment been allocated for it?
  3248.     je    setudk1            ; e = no
  3249.     mov    ax,udkseg[bx]        ; get segment to es
  3250.     mov    es,ax
  3251.     mov    ah,freemem        ; deallocate old memory block, es:0
  3252.     int    dos
  3253.     mov    udkseg[bx],0        ; clear table entry too
  3254. setudk1:and    cl,not 1        ; force an even number of inputs
  3255.     jcxz    setudkx            ; z = no definition, clear entry
  3256.     push    bx            ; save index BX
  3257.     mov    bx,cx            ; get string length
  3258.     shr    bx,1            ; two hex digits per final byte
  3259.     add    bx,15+1            ; round up plus length byte
  3260.     shr    bx,1            ; convert to paragraphs
  3261.     shr    bx,1
  3262.     shr    bx,1
  3263.     shr    bx,1
  3264.     mov    di,bx            ; remember request
  3265.     mov    ah,alloc        ; allocate BX paragraphs
  3266.     int    dos
  3267.     jc    setudkx            ; c = failure
  3268.     cmp    di,bx            ; requested vs allocated
  3269.     pop    bx            ; recover bx
  3270.     je    setudk2            ; e = enough
  3271.     mov    ah,freemem        ; return the memory, es is ptr
  3272.     int    dos
  3273.     jmp    short setudkx        ; exit failure
  3274.  
  3275. setudk2:mov    es,ax            ; segment of allocated memory
  3276.     mov    udkseg[bx],ax        ; segment:0 of definition string
  3277.     xor    di,di
  3278.     cld
  3279.     mov    al,cl            ; length of string
  3280.     shr    al,1            ; two hex bytes per stored byte
  3281.     xor    ch,ch
  3282.     stosb                ; store length byte
  3283.     jcxz    setudkx            ; z = empty string
  3284. setukd3:lodsb                ; get first hex digit
  3285.     dec    cx            ; adjust count remaining
  3286.     or    al,20h            ; to lower case
  3287.     cmp    al,'9'            ; digit?
  3288.     jbe    setudk4            ; be = yes
  3289.     sub    al,'a'-'9'-1        ; hex letter to column three
  3290. setudk4:sub    al,'0'            ; ascii to binary
  3291.     shl    al,1            ; times 16
  3292.     shl    al,1
  3293.     shl    al,1
  3294.     shl    al,1
  3295.     mov    ah,al            ; save in ah
  3296.     lodsb                ; get second hex digit
  3297.     or    al,20h            ; to lower case
  3298.     cmp    al,'9'            ; digit?
  3299.     jbe    setudk5            ; be = yes
  3300.     sub    al,'a'-'9'-1        ; hex letter to column three
  3301. setudk5:sub    al,'0'            ; ascii to binary
  3302.     add    al,ah            ; join both parts
  3303.     stosb                ; store final byte
  3304.     loop    setukd3
  3305. setudkx:pop    es
  3306.     pop    di
  3307.     pop    si
  3308.     pop    cx
  3309.     pop    bx
  3310.     pop    ax
  3311.     clc
  3312.     ret
  3313. setudk    endp
  3314.  
  3315. ; Clear all User Definable Keys, deallocate memory for their definitions
  3316. udkclear proc    near
  3317.     push    ax
  3318.     push    bx
  3319.     push    cx
  3320.     push    es
  3321.     mov    cx,17            ; 17 entries
  3322.     xor    bx,bx
  3323. udkcle1:mov    ax,udkseg[bx]        ; segment of definition
  3324.     or    ax,ax            ; segment defined?
  3325.     jz    udkcle2            ; z = no, try next key
  3326.     mov    es,ax
  3327.     mov    udkseg[bx],0        ; clear the entry
  3328.     mov    ah,freemem        ; release the memory
  3329.     int    dos
  3330. udkcle2:add    bx,2            ; word index
  3331.     loop    udkcle1            ; do all
  3332.     pop    es
  3333.     pop    cx
  3334.     pop    bx
  3335.     pop    ax
  3336.     clc
  3337.     ret
  3338. udkclear endp
  3339.  
  3340. fsetpos    proc    far
  3341.     call    setpos
  3342.     ret
  3343. fsetpos    endp
  3344.  
  3345. frepaint proc    far
  3346.     call    repaint
  3347.     ret
  3348. frepaint endp
  3349. code1    ends
  3350.  
  3351. code    segment
  3352.     assume    cs:code
  3353.                     ; these commands invoke Quit
  3354. cdos:    mov    al,'P'            ; Push to DOS
  3355.     jmp    short cmdcom
  3356. cstatus:mov    al,'S'            ; Status
  3357.     jmp    short cmdcom
  3358. cquit:    mov    al,'C'            ; Exit Connect mode
  3359.     jmp    short cmdcom
  3360. cquery:    mov    al,'?'            ; Help
  3361.     jmp    short cmdcom
  3362. chang:    mov    al,'H'            ; Hangup, drop DTR & RTS
  3363.     jmp    short cmdcom
  3364. cmdcom:    mov    kbdflg,al        ; pass char to msster.asm via kbdflg
  3365.     stc                ; signal that Quit is needed
  3366.     ret
  3367.                     ; general character out for emulator
  3368. chrout    proc    near
  3369.     cmp    flags.vtflg,0        ; emulating?
  3370.     je    chrou5            ; e = no
  3371.     call    fanskbi            ; say we had keyboard input
  3372.     cmp    al,cr            ; CR?
  3373.     jne    chrou5            ; ne = no, just output it and return
  3374.     test    vtemu.vtflgop,anslnm    ; ANSI new-line mode set?
  3375.     jz    chrou5            ; z = no, just send the cr
  3376.     cmp    dupflg,0        ; full duplex?
  3377.     je    chrou4            ; e = yes
  3378.     cmp    al,trans.seol        ; End of Line char?
  3379.     jne    chrou5            ; ne = no
  3380. chrou4:    mov    ah,trans.seol        ; save eol char
  3381.     push    ax            ; save on stack
  3382.     mov    trans.seol,lf        ; make LF the eol char
  3383.     call    foutprt            ; output a carriage-return
  3384.     mov    al,lf            ; followed by a line feed
  3385.     call    foutprt            ; send the LF
  3386.     pop    ax
  3387.     mov    trans.seol,ah        ; restore eol char
  3388.     ret
  3389. chrou5:    call    foutprt
  3390.     ret
  3391. chrout    endp
  3392.  
  3393.                        ; Screen dump entry from keyboad xlat
  3394. dmpscn    proc    near            ; dump screen to file
  3395.     cmp    flags.vtflg,tttek    ; doing Tektronix emulation?
  3396.     je    dmpscn2            ; e = yes, use Tek emulator
  3397.     cmp    tekflg,tek_active+tek_dec ; emulation a Tektronix?
  3398.     jne    dmpscn1            ; ne = no
  3399. dmpscn2:call    tekdmp            ; near-call Tek screen dump utility
  3400.     clc
  3401.     ret
  3402. dmpscn1:call    dumpscr            ; do buffer to file
  3403.     clc                ; do not exit Connect mode
  3404.     ret
  3405. dmpscn    endp
  3406.  
  3407. ; Save the screen to a buffer and then append buffer to a disk file. [jrd]
  3408. ; Default filename is Kermit.scn; actual file can be a device too. Filename
  3409. ; is determined by mssset and is passed as pointer dmpname.
  3410. ; Dumpscr reads the screen image saved in vscreen.
  3411.  
  3412. dumpscr proc    near
  3413.     push    ax
  3414.     push    bx
  3415.     push    cx
  3416.     push    dx
  3417.     mov    dmphand,-1        ; preset illegal handle
  3418.     mov    dx,offset dmpname    ; name of disk file, from mssset
  3419.     mov    ax,dx            ; where isfile wants name ptr
  3420.     call    fisfile            ; what kind of file is this?
  3421.     jc    dmp5            ; c = no such file, create it
  3422.     test    byte ptr filtst.dta+21,1fh ; file attributes, ok to write?
  3423.     jnz    dmp0            ; nz = no.    
  3424.     mov    al,1            ; writing
  3425.     mov    ah,open2        ; open existing file
  3426.     int    dos
  3427.     jc    dmp0            ; c = failure
  3428.     mov    dmphand,ax        ; save file handle
  3429.     mov    bx,ax            ; need handle here
  3430.     mov    cx,0ffffh        ; setup file pointer
  3431.     mov    dx,-1            ; and offset
  3432.     mov    al,2            ; move to eof minus one byte
  3433.     mov    ah,lseek        ; seek the end
  3434.     int    dos
  3435.     jmp    dmp1
  3436.  
  3437. dmp5:    test    filtst.fstat,80h    ; access problem?
  3438.     jnz    dmp0            ; nz = yes
  3439.     mov    ah,creat2        ; file did not exist
  3440.     mov    cx,20h            ; attributes, archive bit
  3441.     int    dos
  3442.     mov    dmphand,ax        ; save file handle
  3443.     jnc    dmp1            ; nc = ok
  3444.  
  3445. dmp0:    mov    ah,3            ; get cursor position
  3446.     xor    bh,bh            ; page 0
  3447.     int    screen
  3448.     push    dx            ; save it
  3449.     mov    dh,byte ptr low_rgt+1    ; go to status line
  3450.     inc    dh
  3451.     xor    dl,dl            ; left most column
  3452.     mov    ah,2            ; set cursor
  3453.     xor    bh,bh            ; page 0
  3454.     int    screen
  3455.     mov    dx,offset dmperr    ; say no can do
  3456.     mov    ah,prstr
  3457.     int    dos
  3458.     pop    dx            ; get original cursor position
  3459.     mov    ah,2            ; set cursor
  3460.     xor    bh,bh            ; page 0
  3461.     int    screen
  3462.     pop    dx
  3463.     pop    cx
  3464.     pop    bx
  3465.     pop    ax
  3466.     clc
  3467.     ret
  3468.  
  3469. dmp1:    mov    ah,ioctl        ; is destination ready for output?
  3470.     mov    al,7            ; test output status
  3471.     mov    bx,dmphand        ; handle
  3472.     int    dos
  3473.     jc    dmp0            ; c = error
  3474.     cmp    al,0ffh            ; ready?
  3475.     jne    dmp0            ; ne = not ready
  3476.     push    di            ; read screen buffer, write lines
  3477.     push    si
  3478.     push    es
  3479.     mov    cl,byte ptr low_rgt+1    ; number of lines - 2
  3480.     add    cl,2            ; number of line on screen
  3481.     xor    ch,ch
  3482.     les    si,vs_ptr        ; seg and offset of vscreen
  3483.     sub    si,vswidth*2        ; prep for inc below
  3484. dmp2:    add    si,vswidth*2        ; virtual screen width in bytes
  3485.     push    si
  3486.     push    cx            ; save outer loop counter
  3487.     push    di
  3488.     mov    di,offset decbuf    ; data segment memory
  3489.     mov    cl,byte ptr low_rgt    ; number of columns on screen -1
  3490.     inc    cl
  3491.     xor    ch,ch
  3492. dmp3:    mov    ax,word ptr es:[si]    ; read char + attribute
  3493.     or    al,al            ; is it a null?
  3494.     jnz    dmp3c            ; nz = no
  3495.     mov    al,' '            ; replace null with space
  3496. dmp3c:    mov    byte ptr [di],al    ; store just char, don't use es:
  3497.     inc    si            ; update pointers
  3498.     inc    si
  3499.     inc    di
  3500.     loop    dmp3            ; do for each column
  3501.     mov    cl,byte ptr low_rgt    ; number of columns on screen - 1
  3502.     inc    cl
  3503.     xor    ch,ch
  3504.     push    es
  3505.     mov    ax,ds
  3506.     mov    es,ax            ; set es to data segment for es:di
  3507.     mov    di,offset decbuf    ; start of line
  3508.     add    di,cx            ; plus length of line
  3509.     dec    di            ; minus 1 equals end of line
  3510.     mov    al,' '            ; thing to scan over
  3511.     std                ; set scan backward
  3512.     repe    scasb            ; scan until non-space
  3513.     cld                ; set direction forward
  3514.     pop    es
  3515.     je    dmp3a            ; e = all spaces
  3516.     inc    cx
  3517.     inc    di
  3518. dmp3a:    mov    word ptr [di+1],0A0Dh    ; append cr/lf
  3519.     add    cx,2            ; line count + cr/lf
  3520.     mov    dx,offset decbuf    ; array to be written
  3521.     mov    bx,dmphand        ; need file handle
  3522.     mov    ah,write2        ; write the line
  3523.     int    dos
  3524.     pop    di
  3525.     pop    cx            ; get line counter again
  3526.     pop    si            ; screen offset
  3527.     jc    dmp3b            ; c = error
  3528.     loop    dmp2            ; do next line
  3529. dmp3b:    mov    dx,offset dumpsep    ; put in formfeed/cr/lf
  3530.     mov    bx,dmphand        ; need file handle
  3531.     mov    cx,3            ; three bytes overall
  3532.     mov    ah,write2        ; write them
  3533.     mov    bx,dmphand        ; file handle
  3534.     int    dos
  3535.     mov    bx,dmphand        ; need file handle
  3536.     mov    ah,close2        ; close the file now
  3537.     int    dos
  3538.     pop    es
  3539.     pop    si
  3540.     pop    di
  3541.     pop    dx
  3542.     pop    cx
  3543.     pop    bx
  3544.     pop    ax
  3545.     clc
  3546.     ret
  3547. dumpscr endp
  3548.  
  3549. togmod    proc    FAR
  3550.     call    trnmod            ; FAR callable trnmod
  3551.     ret
  3552. togmod    endp
  3553.  
  3554.                     ; Toggle Mode Line
  3555. trnmod    proc    near
  3556.     cmp    inemulator,0        ; in terminal emulator?
  3557.     je    trnm1            ; e = no, no mode line
  3558.     cmp    flags.modflg,1        ; mode line enabled and owned by us?
  3559.     jne    trnm1            ; ne = no, don't touch it
  3560.     cmp    flags.vtflg,tttek    ; Tek mode?
  3561.     je    trnm1            ; e = yes
  3562.     test    tekflg,tek_dec        ; in Tek submode?
  3563.     jnz    trnm1            ; nz = yes, no mode line changes
  3564.     test    yflags,modoff        ; mode line already off?
  3565.     jnz    trnm2            ; nz = yes, go turn on
  3566.     or    yflags,modoff        ; say modeline is toggled off
  3567.     cmp    flags.vtflg,0        ; emulating none?
  3568.     jne    trnm0            ; ne = no
  3569.     push    dx
  3570.     call    fgetpcur        ; get physical cursor
  3571.     mov    cursor,dx
  3572.     pop    dx
  3573. trnm0:    call    clrmod            ; clear mode line
  3574. trnm1:    clc                ; clear c bit so don't exit Connect
  3575.     ret
  3576. trnm2:    cmp    flags.vtflg,0        ; emulating a terminal?
  3577.     jne    trnm3            ; ne = yes
  3578.     push    dx            ; scroll screen to save bottom line
  3579.     call    fgetpcur        ; get physical cursor
  3580.     mov    cursor,dx
  3581.     mov    ah,prstr        ; for terminal type none
  3582.     mov    dx,offset crlf
  3583.     int    dos
  3584.     pop    dx
  3585. trnm3:    call    modlin            ; turn on modeline
  3586.     and    yflags,not modoff    ; say modeline is not toggled off
  3587.     clc
  3588.     ret
  3589. trnmod    endp
  3590.  
  3591. modlin    proc    near
  3592.     push    si
  3593.     push    di
  3594.     push    es
  3595.     mov    ax,ds
  3596.     mov    es,ax
  3597.     mov    si,offset modmaster    ; master template
  3598.     mov    di,offset modbuf    ; working copy
  3599.     cld
  3600. modl20:    lodsb
  3601.     stosb
  3602.     cmp    al,'$'            ; at end?
  3603.     jne    modl20            ; ne = no
  3604.     mov    al,trans.escchr        ; Connect mode escape character
  3605.     mov    modbuf.m_echr,' '    ; first char is initial space
  3606.     mov    modbuf.m_hlp,' '    ; goes here too
  3607.     cmp    al,32            ; printable?
  3608.     jnb    modl1            ; yes, keep going
  3609.     add    al,40h            ; made printable
  3610.     mov    modbuf.m_echr,5eh    ; caret, note control char
  3611.     mov    modbuf.m_hlp,5eh
  3612. modl1:    mov    modbuf.m_echr+1,al    ; fill in character
  3613.     mov    modbuf.m_hlp+1,al
  3614.     mov    bx,argadr        ; get argument block
  3615.     mov    al,[bx].baudb        ; get baud bits
  3616.     mov    si,offset unkbaud    ; assume unknown baud
  3617.     mov    cx,size m_baud        ; length of baud space
  3618.     cmp    al,baudnsiz        ; beyond end of table?
  3619.     jnb    modl2            ; nb = yes, use default
  3620.     mul    cl
  3621.     xor    ah,ah
  3622.     add    ax,offset baudn
  3623.     mov    si,ax
  3624. modl2:    mov    di,offset modbuf.m_baud
  3625.     cld
  3626.     rep    movsb            ; copy in baud rate
  3627.     mov    bx,portval
  3628.     mov    al,[bx].parflg        ; get parity code
  3629.     shl    al,1            ; each is 4 bytes long
  3630.     shl    al,1
  3631.     xor    ah,ah
  3632.     add    ax,offset parnams    ; names of parity settings
  3633.     mov    si,ax
  3634.     mov    cx,4            ; each is 4 long
  3635.     mov    di,offset modbuf.m_par
  3636.     rep    movsb
  3637.     mov    si,offset remmsg    ; assume remote echoing
  3638.     test    yflags,lclecho        ; local echo on?
  3639.     jz    modl3            ; z = no
  3640.     mov    si,offset lclmsg    ; say echo is local
  3641. modl3:    mov    cx,3            ; size of on/off
  3642.     mov    di,offset modbuf.m_echo
  3643.     rep    movsb
  3644.     mov    al,portno        ; communications port
  3645.     cmp    al,' '            ; binary (non-printable)?
  3646.     jae    modl4            ; ae = no, ascii
  3647.     add    al,'0'            ; convert to ascii
  3648. modl4:    mov    modbuf.m_prt,al        ; fill in port number
  3649.     mov    al,portno
  3650.     cmp    repflg,0        ; REPLAY?
  3651.     je    modl5            ; e = no
  3652.     mov    si,offset repmsg    ; say "REPLAY"
  3653.     mov    cx,repmsgl        ; its length
  3654.     mov    di,offset modbuf.m_prt
  3655.     mov    al,' '            ; start with a space
  3656.     stosb
  3657.     mov    dx,12            ; space to be filled
  3658.     sub    dx,cx            ; amount we will use here
  3659.     rep    movsb            ; copy string
  3660.     mov    cx,dx
  3661.     rep    stosb            ; flesh out with spaces
  3662.     jmp    short modl10
  3663.  
  3664. modl5:    cmp    al,'4'            ; in networks material?
  3665.     jbe    modl10            ; be = no
  3666.     cmp    flags.comflg,'t'    ; doing TCP/IP Telnet?
  3667.     jne    modl5d            ; ne = no
  3668.     mov    si,offset tcphost    ; name of host
  3669.     mov    di,offset modbuf.m_prt - 6 ; overwrite "port:"
  3670.     mov    ax,sescur        ; ident of session
  3671.     add    al,'1'            ; ascii, show as 1:nodename
  3672.     mov    ah,':'
  3673.     stosw                ; store that much
  3674.     mov    cx,17            ; bytes max
  3675. modl5a:    lodsb
  3676.     or    al,al             ; at null terminator?
  3677.     jz    modl5b            ; z = yes
  3678.     stosb
  3679.     loop    modl5a
  3680. modl5b:    mov    al,' '            ; fill out with spaces
  3681.     rep    stosb            ; noop if cx == 0
  3682.     jmp    short modl5d        ; done with tcp/ip 
  3683.  
  3684. modl5d:    mov    bx,offset comptab    ; table of comms ports
  3685.     mov    cl,[bx]            ; number of entries
  3686.     xor    ch,ch
  3687.     inc    bx
  3688. modl6:    mov    dx,[bx]            ; length of this entry
  3689.     mov    si,bx
  3690.     add    si,2            ; points to entry text string
  3691.     add    si,dx            ; point to qualifier
  3692.     cmp    [si],al            ; our port?
  3693.     je    modl7            ; e = yes
  3694.     add    bx,[bx]            ; add text length
  3695.     add    bx,4            ; plus count and qualifier
  3696.     loop    modl6            ; next entry
  3697.     jmp    short modl10        ; no match, curious
  3698. modl7:    mov    si,bx            ; point at entry
  3699.     add    si,2            ; point at string
  3700.     mov    cx,[bx]            ; length of string
  3701.     mov    di,offset modbuf.m_prt
  3702.     mov    al,' '            ; start with a space
  3703.     stosb
  3704.     mov    dx,12            ; space to be filled
  3705.     sub    dx,cx            ; amount we will use here
  3706.     rep    movsb            ; copy string
  3707.     mov    cx,dx
  3708.     rep    stosb            ; flesh out with spaces
  3709. modl10:    mov    cx,8            ; blank out terminal id field
  3710.     mov    si,offset mtty        ; assume no terminal emulation
  3711.     mov    di,offset modbuf.m_term ; destination
  3712.     rep    movsb            ; copy it in
  3713.     mov    word ptr modbuf.m_prn,'  '; assume not printing the screen
  3714.     mov    modbuf.m_prn+2,' '
  3715.     test    anspflg,prtscr+2    ; print the screen? (msz uses 1 & 2)
  3716.     jz    modl10a            ; z = no
  3717.     mov    word ptr modbuf.m_prn,'RP' ; yes. display PRN at end of line
  3718.     mov    modbuf.m_prn+2,'N'
  3719. modl10a:mov    modbuf.m_comp,' '    ; flag for not-compose
  3720.     cmp    grab,0            ; doing Compose grabbing?
  3721.     je    modl11            ; e = no
  3722.     mov    modbuf.m_comp,'C'    ; flag for compose
  3723. modl11:    cmp    inemulator,0        ; in terminal emulator now?
  3724.     jne    modl11a            ; ne = yes
  3725.     pop    es            ; do nothing
  3726.     pop    di
  3727.     pop    si
  3728.     ret
  3729. modl11a:push    dx
  3730.     cmp    flags.vtflg,0        ; emulating?
  3731.     je    modl12            ; e = no
  3732.     and    yflags,not modoff    ; update local flags (mode line on)
  3733.     call    fansdsl            ; get extras from emulator
  3734. modl12:    mov    dx,offset modbuf    ; mode line image ptr for putmod
  3735.     call    putmod            ; display mode line
  3736.     mov    dx,cursor        ; restore active cursor position
  3737.     call    fsetpos            ; set cursor
  3738.     pop    dx
  3739.     pop    es
  3740.     pop    di
  3741.     pop    si
  3742.     ret
  3743. modlin    endp
  3744.  
  3745. fmodlin    proc    far
  3746.     call    modlin
  3747.     ret
  3748. fmodlin    endp
  3749.  
  3750. ;[IU2] Routine to toggle VT100/VT52/Heath-19 modes in VT100 emulator.
  3751. vtans52 proc    near
  3752.     cmp    flags.vtflg,0        ; emulating?
  3753.     je    vtans52a        ; e = no
  3754.     call    ans52t            ; call MSZ toggle-it routine
  3755.     cmp    flags.vtflg,tttek    ; Tek now?
  3756.     je    vtans52a        ; e = yes
  3757.     test    tekflg,tek_tek+tek_dec     ; Tek submode?
  3758.     jnz    vtans52a        ; nz = yes
  3759.     call    scrini            ; check on screen size changes
  3760. vtans52a:clc                ; clear c bit so don't exit Connect
  3761.     ret
  3762. vtans52 endp
  3763.  
  3764. ftrnprs proc    far
  3765.     call    trnprs
  3766.     ret
  3767. ftrnprs    endp
  3768.  
  3769. trnprs    proc    near
  3770.     push    ax            ; toggle ^ PrtSc screen to printer
  3771.     test    anspflg,prtscr        ; are we currently printing?
  3772.     jnz    trnpr2            ; nz = yes, its on and going off
  3773.     push    bx
  3774.     mov    bx,prnhand        ; file handle for system printer
  3775.     mov    ah,ioctl
  3776.     mov    al,7            ; get output status of printer
  3777.     int    dos
  3778.     pop    bx
  3779.     jc    trnpr1            ; c = printer not ready
  3780.     cmp    al,0ffh            ; Ready status?
  3781.     je    trnpr2            ; e = Ready    
  3782. trnpr1:    call    fvtbell            ; Not Ready, complain
  3783.     jmp    trnpr3            ; and ignore request
  3784. trnpr2:    xor    anspflg,prtscr        ; flip the flag
  3785.     test    yflags,modoff        ; mode line off?
  3786.     jnz    trnpr3            ; nz = yes
  3787.     call    fmodlin            ; else rewrite mode line
  3788. trnpr3:    pop    ax
  3789.     clc                ; return carry clear (don't quit)
  3790.     ret
  3791. trnprs    endp
  3792. code    ends
  3793.  
  3794. code1    segment
  3795.     assume    cs:code1
  3796.  
  3797. pntdead    proc    near            ; display printer is inoperative msg
  3798.     push    ax
  3799.     test    yflags,modoff        ; is mode line off?
  3800.     jnz    pntdea1            ; nz = off, skip msg
  3801.     push    bx
  3802.     mov    dx,offset pntmsg    ; say printer not ready
  3803.     call    fputmod            ; write on mode line
  3804.     pop    bx
  3805. pntdea1:pop    ax
  3806.     stc                ; say printer not ready
  3807.     ret
  3808. pntdead    endp
  3809.  
  3810. ;;;;; General screen management routines for IBM PC
  3811.  
  3812. ; computes screen location to ax, given row and col in [dh,dl], resp.
  3813.  
  3814. scrloc    proc    near
  3815.     push    cx
  3816.     mov    cl,crt_cols
  3817.     cmp    inemulator,0        ; emulating?
  3818.     je    scrloc1            ; e = no
  3819.     cmp    flags.vtflg,0        ; emulating anything?
  3820.     je    scrloc1            ; e = no
  3821.     mov    cl,vswidth
  3822. scrloc1:mov    al,dh            ; get row
  3823.     mul    cl            ; multiply by number of columns
  3824.     add    al,dl            ; plus current column number
  3825.     adc    ah,0            ; ripple carry
  3826.     shl    ax,1            ; double for attributes
  3827.     pop    cx
  3828.     ret
  3829. scrloc    endp
  3830.  
  3831. ; Routine to set cursor type.  Pass cursor type in al: 0,4 = No cursor,
  3832. ; 1 = Underline cursor, 2 = Block cursor.   All cursors blink due to hardware.
  3833. ; For EGA boards running in non-25 line mode the cursor emulation is turned
  3834. ; off during cursor shape changing and restored afterward. It's another
  3835. ; ega Feature. [jrd]
  3836. ; Sense crt_mode 18h as Tseng Labs UltraPAK mono board in 132 column mode.
  3837. csrtype proc    near
  3838.     push    cx            ; save the reg
  3839.     mov    cx,0F00H        ; assume no cursor
  3840.     test    al,4            ; no cursor?
  3841.     jz    csrtyp6            ; z = no
  3842.     xor    al,al            ; set type to invisible
  3843. csrtyp6:or    al,al            ; no cursor?
  3844.     jz    csrty2            ; z = yes, no cursor
  3845.     cmp    crt_mode,7        ; B&W card?
  3846.     je    csrty3            ; e = yes, different sizes
  3847.     cmp    crt_mode,18h        ; Tseng UltraPAK mono board?
  3848.      je    csrty3            ; e = yes, use mono cursor
  3849.     mov    cx,0607H        ; use CGA underline cursor
  3850.     cmp    al,2            ; Block?
  3851.     jne    csrty2            ; ne = no, set it now
  3852. csrty1: xor    ch,ch            ; make cursor a block
  3853. csrty2:    cmp    ega_mode,0        ; ega board active?
  3854.     je    csrty4            ; e = no
  3855.     test    tv_mode,10h        ; DV active?
  3856.     jnz    csrty4            ; nz = yes, it messes with the cursor
  3857.     cmp    byte ptr low_rgt+1,23    ; standard screen length?
  3858.     je    csrty4            ; e = yes, use regular cursor setting
  3859.     push    es            ; EGA. turn off cursor emulation
  3860.     mov    ax,40h            ; 40:87h is ega Info byte
  3861.     mov    es,ax
  3862.     push    es:[87h]        ; save Info byte around call
  3863.     or    byte ptr es:[87h],1    ; set emulation off (low bit = 1)
  3864.     mov    ah,1            ; video function for set cursor type
  3865.     int    screen
  3866.     pop    es:[87h]        ; restore Info byte
  3867.     pop    es            ;  and our work register
  3868.     pop    cx
  3869.     ret
  3870.  
  3871. csrty4:    push    ax
  3872.     mov    ah,1            ; video function for set cursor type
  3873.     int    screen            ; regular cursor shape setting
  3874.     pop    ax
  3875. csrty5:    pop    cx
  3876.     ret
  3877.  
  3878. csrty3: mov    cx,0B0CH        ; assume B&W underline cursor
  3879.     cmp    al,2            ; Block?
  3880.     jne    csrty2            ; ne = no, set it now
  3881.     jmp    short csrty1        ; make it a block
  3882. csrtype endp
  3883.  
  3884. fcsrtype proc    far
  3885.     call    csrtype
  3886.     ret
  3887. fcsrtype endp
  3888.  
  3889. ; Get CRT mode - returns mode in variable crt_mode,
  3890. ; updates crt_cols, and low_rgt.
  3891. ; For EGA active it looks in Bios work memory 40:84H for number of rows
  3892. scrmod    proc    near
  3893.     push    ax
  3894.     push    dx
  3895.     mov    ah,0fh            ; get current video state
  3896.     int    screen
  3897.     and    al,not 80h        ; strip "preserve regen" bit 80h
  3898.     mov    crt_mode,al        ; store CRT mode value
  3899.     mov    crt_cols,ah        ; store # of cols
  3900.     mov    dl,ah            ; # of cols again
  3901.     mov    dh,crt_lins        ; and # of rows (constant from msster)
  3902.     cmp    tv_mode,0        ; Topview active?
  3903.     je    scrmod2            ; e = no
  3904.     test    tv_mode,20h        ; Japanese DOS active?
  3905.     jnz    scrmod2            ; nz = yes, do not do Int 15h
  3906.     push    cx
  3907.     push    bx
  3908.     mov    ah,12h            ; TV, Get Object Length
  3909.     mov    bx,0901h        ; object, BL = 01 = chars/line
  3910.     int    15h
  3911.     pop    ax            ; chars/line from stack dword
  3912.     cmp    al,10            ; keep things sane, chars per line
  3913.     ja    scrmod7            ; a = might be sane
  3914.     pop    ax            ; clean stack
  3915.     jmp    scrmod2            ; wacko, ignore DV stuff
  3916.  
  3917. scrmod7:mov    crt_cols,al        ; TV windowed screen columns
  3918.     pop    ax            ; clear rest of dword from stack
  3919.     mov    ah,12h            ; send
  3920.     mov    bx,1            ; handle (0*256) + window (me, 1)
  3921.     int    15h
  3922.     pop    bx            ; handle low word
  3923.     pop    bx            ; handle high word to BX for next call
  3924.     mov    ax,1024h        ; TV Get Virtual Screen Info
  3925.     int    15h
  3926. scrmod1:cmp    cx,128*25*2        ; get sanity for DV big DOS window
  3927.     jbe    scrmod1a        ; be = reasonable size
  3928.     shr    cx,1            ; reduce size
  3929.     jmp    short scrmod1        ;  and try again
  3930. scrmod1a:mov    ax,cx            ; CX is virtual screen size, bytes
  3931.     mov    bl,crt_cols        ; divide by columns to get width
  3932.     shl    bl,1            ; get words (char and attribute)
  3933.     div    bl            ; al = lines, ah = fractions of line
  3934.     dec    al            ; count this from zero like the Bios
  3935.     mov    crt_lins,al        ; visible screen lines -1 (24)
  3936.     mov    dh,al
  3937.     mov    dl,crt_cols        ; visible screen columns (80)
  3938.     pop    bx
  3939.     pop    cx
  3940.     jmp    short scrmod4
  3941.  
  3942. scrmod2:cmp    ega_mode,0        ; ega active?
  3943.     je    scrmod4            ; e = no
  3944.     push    es            ; yes, permit different lengths
  3945.     mov    ax,40h            ; refer to 40:84h for # ega rows
  3946.     mov    es,ax
  3947.     mov    ah,es:[84h]        ; get number of rows - 1 (typ 24)
  3948.     cmp    ah,20            ; less than 20 rows?
  3949.     jb    scrmod3            ; b = yes, ignore this length
  3950.     cmp    ah,80            ; more than 80 rows?
  3951.     ja    scrmod3            ; a = yes, ignore this length
  3952.     mov    dh,ah            ; use this length
  3953.     mov    crt_lins,dh        ; update our working constant
  3954. scrmod3:pop    es
  3955. scrmod4:dec    dl            ; max text column, count from zero
  3956.     dec    dh            ; max text row, count from zero
  3957.     cmp    flags.vtflg,ttgenrc    ; no terminal emulation
  3958.     je    scrmod6            ; e = yes
  3959.     cmp    tekflg,tek_active+tek_sg ; doing special graphics?
  3960.     jne    scrmod4a        ; ne = no
  3961.     mov    crt_cols,128        ; VT style special graphics uses this
  3962. scrmod4a:
  3963.     cmp    crt_cols,80        ; doing wide now?
  3964.     ja    scrmod5            ; a = yes
  3965.     mov    dl,80-1            ; assume 80 column width
  3966.     test    vtemu.vtflgop,deccol    ; 132 column mode set?
  3967.     jz    scrmod6            ; z = no
  3968. scrmod5:mov    dl,132-1        ; set to 132 column mode
  3969. scrmod6:mov    low_rgt,dx        ; save away window address
  3970.     pop    dx
  3971.     pop    ax
  3972.     ret
  3973. scrmod    endp
  3974.  
  3975. ; Get screen segment. Returns screen segment in ax, and full address in es:di
  3976. scrseg    proc    near
  3977.     xor    di,di            ; start at beginning of screen (0,0)
  3978.     mov    ax,0B800H        ; video memory is here on color
  3979.     cmp    crt_mode,7        ; normal color modes?
  3980.     jb    scrse1            ; b = yes
  3981.     mov    ax,0B000H        ; assume B&W card
  3982.     cmp    crt_mode,12        ; 
  3983.     jb    scrse1
  3984.     cmp    crt_mode,18h        ; Tseng UltraPAK mono in 132 col?
  3985.     je    scrse1            ; e = yes, use seg B000H
  3986.     cmp    crt_mode,56h        ; Paradise EGA Mono in 132x43 mode?
  3987.     je     scrse1            ; e = yes, use seg B000H
  3988.     cmp    crt_mode,57h        ; Paradise EGA Mono in 132x25 mode?
  3989.     je    scrse1            ; e = yes, use seg B000H
  3990.     mov    ax,0B800H        ; video memory is here on color
  3991.     cmp    crt_mode,18        ; end of ordinary 640x480 graphics
  3992.     ja    scrse1            ; a = no, assume CGA segment
  3993.     mov    ax,0A000H        ; graphics
  3994. scrse1:    mov    es,ax        ; tell Topview our hardware address needs
  3995.     mov    tv_segs,es        ; save our hardware screen address
  3996.     mov    tv_sego,di        ; segment and offset form
  3997.     or    tv_mode,1        ; assume we're running under Topview
  3998.     mov    ah,tvhere        ; query Topview for its presence
  3999.     int    screen
  4000.     mov    ax,es            ; get its new segment for screen work
  4001.     cmp    ax,tv_segs        ; same as hardware?
  4002.     jne    scrse2            ; ne = no, we are being mapped
  4003.     cmp    di,tv_sego        ; check this too
  4004.     jne    scrse2        ; ne = no too. Use TV's work buf as screen
  4005.     and    tv_mode,not 1        ; else no Topview or no mapping
  4006. scrse2:    mov    tv_segs,es        ; save segment
  4007.     mov    tv_sego,di        ; and offset
  4008.     ret
  4009. scrseg    endp
  4010.  
  4011. ; Synchronize a Topview provided virtual screen buffer with the image
  4012. ; seen by the user. Requires cx = number of words written to screen
  4013. ; (char & attribute bytes) and es:di = ENDING address of screen write.
  4014. ; Changes ax and di. Skip operations for DESQview
  4015. scrsync proc    near
  4016.     cmp    tv_mode,0        ; Topview mode active?
  4017.     je    scrsyn1            ; e = no, skip Bios call below
  4018.     push    ax
  4019.     push    cx
  4020.     push    di
  4021.     sub    di,cx            ; backup to start byte (cx = words)
  4022.     sub    di,cx            ;  after storing words to screen
  4023.     mov    ah,tvsynch        ; tell Topview we have changed screen
  4024.     int    screen            ;  so user sees updated screen
  4025.     pop    di
  4026.     pop    cx
  4027.     pop    ax
  4028. scrsyn1:ret
  4029. scrsync endp
  4030.  
  4031. ; The following two routines are used to turn off the display while we
  4032. ; are reading or writing the screen in one of the color card modes.
  4033. ; Turn screen off for (known) color card modes only. All regs preserved.
  4034. ; Includes code for old procedure scrwait. 16 June 1987 [jrd]
  4035. scroff    proc    near
  4036.     cmp    ega_mode,0        ; Extended Graphics Adapter in use?
  4037.     jne    scrofx            ; ne = yes, no waiting
  4038.     cmp    tv_mode,0        ; Topview mode?
  4039.     jne    scrofx            ; ne = yes, no waiting
  4040.     cmp    crt_mode,7        ; B&W card?
  4041.     jnb    scrofx            ; nb = yes - just return
  4042.     cmp    refresh,0        ; slow refresh?
  4043.     jne    scrofx            ; ne = no wait
  4044.     push    ax            ; save ax and dx
  4045.     push    dx
  4046.     mov    dx,crt_status        ; CGA: Wait for vertical retrace
  4047. scrof1:    in    al,dx
  4048.     test    al,disp_enb        ; display enabled?
  4049.     jnz    scrof1            ; yes, keep waiting
  4050. scrof2:    in    al,dx
  4051.     test    al,disp_enb        ; now wait for it to go off
  4052.     jz    scrof2            ; so can have whole cycle
  4053.     mov    dx,crtmset        ; output to CRT mode set port
  4054.     mov    al,25H            ; this shuts down the display
  4055.     out    dx,al
  4056.     pop    dx            ; restore regs
  4057.     pop    ax
  4058. scrofx: ret
  4059. scroff    endp
  4060.  
  4061.  
  4062. ; Turn screen on for (known) color card modes only
  4063. ; All registers are preserved.
  4064.  
  4065. scron    proc    near
  4066.     cmp    ega_mode,0        ; Extended Graphics Adapter in use?
  4067.     jne    scronx            ; ne = yes, no waiting
  4068.     cmp    tv_mode,0        ; Topview mode?
  4069.     jne    scronx            ; ne = yes, no waiting
  4070.     cmp    crt_mode,7        ; B&W card?
  4071.     jnb    scronx            ; nb = yes - just return
  4072.     cmp    refresh,0        ; slow refresh?
  4073.     jne    scronx            ; ne = no wait
  4074.     push    ax            ; save ax, dx, and si
  4075.     push    dx
  4076.     push    si
  4077.     mov    al,crt_mode        ; convert crt_mode to a word
  4078.     xor    ah,ah
  4079.     mov    si,ax            ; get it in a usable register
  4080.     mov    al,msets[si]        ; fetch the modeset byte
  4081.     mov    dx,crtmset        ; this port
  4082.     out    dx,al            ; flash it back on
  4083.     pop    si
  4084.     pop    dx
  4085.     pop    ax
  4086. scronx: ret
  4087. scron    endp
  4088.  
  4089.  
  4090. ; Determine screen roll back buffer parameters depending on current screen
  4091. ; dimensions and available memory. Each rollback screen line has its own
  4092. ; segment (lines start on segment boundaries for rollback). One full screen
  4093. ; must be allocated to hold the current display, deduct this from lmax.
  4094.  
  4095. bufadj    proc    near
  4096.     push    bx
  4097.     push    cx
  4098.     push    dx
  4099.     mov    bx,rollwidth        ; rollback line width
  4100.     add    bx,7            ; (BDT) round up to paragraph boundary
  4101.     mov    cl,3            ; (BDT) now convert to
  4102.     shr    bx,cl            ; (BDT) paragraphs / line
  4103.     mov    ppl,bx            ; (BDT) save this in buffer area
  4104.     xor    dx,dx            ; high order dividend, clear it
  4105.     cmp    emsrbhandle,0        ; using EMS?
  4106.     jle    bufadj2            ; le = no (-1 means not used)
  4107.     mov    ax,1024            ; 1024 paragraphs per ems 16KB page
  4108.     div    bx            ; divide by paragraphs per line
  4109.     mov    lineems,ax        ; lines per ems page, remember
  4110.     mul    inipara            ; times number of ems pages
  4111.     jmp    short bufadj3        ; ax has number of lines
  4112.                     ; conventional memory
  4113. bufadj2:mov    ax,inipara        ; (BDT) compute the number of lines
  4114.     div    bx            ; (BDT)  in the buffer
  4115.  
  4116. bufadj3:mov    lmax,ax            ; max line capacity of the buffer
  4117.     mov    linee,ax        ; (BDT) save as number of total lines
  4118.     or    ax,ax            ; have any lines?
  4119.     jz    bufadj1            ; z = yes, no space at all
  4120.     xor    bh,bh            ; (BDT) get lines / screen
  4121.     mov    bl,byte ptr low_rgt+1    ; (BDT) rows on user/host screen
  4122.     inc    bx            ; (BDT) adjust for counting from 0
  4123.     sub    lmax,bx            ; minus master "current" screen
  4124.     jg    bufadj1            ; g = have some rollback space
  4125.     mov    lmax,0            ; say none
  4126. bufadj1:mov     lcnt,0                  ; (BDT) # of lines filled in buffer
  4127.     mov    linef,0            ; (BDT) first filled in line
  4128.     mov    linec,0            ; (BDT) last  filled in line
  4129.     pop    dx
  4130.     pop    cx
  4131.     pop    bx
  4132.     ret
  4133. bufadj    endp
  4134.  
  4135. ; Test for DESQview in operation, set tv_mode bit 10h to non-zero if so.
  4136. dvtest    proc    near
  4137.     and    tv_mode,not 30h        ; assume no DV and no Japanese DOS
  4138.     push    ds
  4139.     mov    ax,ds            ; preset es:si to start of data seg
  4140.     mov    es,ax            ; as saftey factor after test
  4141.     xor    si,si
  4142.     mov    ax,6300h        ; get Doublebyte Char Set Lead Table
  4143.     int    dos            ; returns ptr in ds:si
  4144.     mov    bx,ds            ; cannot trust al as return status
  4145.     mov    es,bx
  4146.     pop    ds
  4147.     mov    ax,ds            ; current DS
  4148.     cmp    ax,bx            ; same seg?
  4149.     je    dvtest4            ; e = yes, test failed
  4150.     cmp    word ptr es:[si],0    ; see if both bytes are also zeros
  4151.     je    dvtest4            ; z = test failed
  4152.     or    tv_mode,20h        ; say Japanese DOS is active
  4153.     ret                ; do no Int 15h with Japanese DOS
  4154. dvtest4:xor    bx,bx            ; for version number
  4155.     mov    cx,'DE'            ; DV signature
  4156.     mov    dx,'SQ'
  4157.     mov    ax,2B01h        ; DOS set date (with illegal value)
  4158.     int    dos
  4159.     cmp    al,0ffh            ; DOS should say invalid if no DV
  4160.     je    dvtest2            ; e = yes, invalid so no DV
  4161.     cmp    bx,2            ; DV version 2.00?
  4162.     jne    dvtest1            ; ne = no
  4163.     xchg    bh,bl            ; get major version into bh
  4164. dvtest1:or    tv_mode,10h        ; say using DV
  4165. dvtest2:ret
  4166. dvtest    endp
  4167.  
  4168. ; Execute DESQview function call provided in BX.
  4169. dvcall    proc    near
  4170.     push    ax
  4171.     mov    ax,101ah        ; switch to DV stack
  4172.     int    15h
  4173.     mov    ax,bx            ; function to do
  4174.     int    15h
  4175.     mov    ax,1025h        ; switch from DV stack
  4176.     int    15h
  4177.     pop    ax
  4178.     ret
  4179. dvcall    endp
  4180.  
  4181. ; Call this to release the cpu during idle times
  4182. dvpause    proc    near
  4183.     test    tv_mode,10h        ; in DV?
  4184.     jz    dvpaus1            ; z = no
  4185.     push    bx
  4186.     mov    bx,1000h        ; say release control
  4187.     call    dvcall            ; to DV
  4188.     pop    bx
  4189. dvpaus1:cmp    byte ptr dosnum+1,5    ; DOS verson, major high, minor low
  4190.     jb    dvpaus2            ; b = too old for this operation
  4191.     mov    ax,1680h        ; release current virtual machine
  4192.     int    2fh            ;  time slice (Windows, OS/2, DPMI)
  4193. dvpaus2:ret
  4194. dvpause    endp
  4195.  
  4196. ; Screen clearing routine
  4197. ; Call:    ax = coordinates of first screen location to be cleared.
  4198. ;    bx = coordinates of last location to be cleared.
  4199. ; Coord: ah = row [0-24], al = column [0-206]. Preserves all registers.
  4200.  
  4201. atsclr    proc    near
  4202.     push    ax            ; save regs 
  4203.     push    cx
  4204.     mov    ch,scbattr        ; save current screen background attr
  4205.     push    cx
  4206.     push    dx
  4207.     mov    dx,bx            ; compute last screen offset from bx
  4208.     push    ax
  4209.     call    scrloc            ; get screen start address in ax
  4210.     mov    cx,ax            ; save it in cx for a minute
  4211.     pop    dx            ; compute first screen offset in ax
  4212.     call    scrloc
  4213.     sub    cx,ax            ; compute number of locs to clear
  4214.     add    cx,2            ; +1 for span, +1 for round up
  4215.     sar    cx,1            ; make byte count a word count
  4216.     jle    atscl3            ; le = nothing to clear
  4217.     push    di            ; save regs
  4218.     push    es            ; save es
  4219.     cmp    inemulator,0        ; in terminal emulator now?
  4220.     je    atscl1            ; e = no
  4221.     cmp    flags.vtflg,0        ; emulating anything?
  4222.     je    atscl1            ; e = no, using DOS
  4223.     les    di,vs_ptr        ; es:di is virtual screen
  4224.     jmp    short atscl2
  4225. atscl1:    push    ax            ; save displacement
  4226.     call    scroff            ; turn screen off if color card
  4227.     call    scrseg            ; get address of screen into es:di
  4228.     pop    ax
  4229. atscl2:    add    di,ax            ; location in buffer
  4230.     mov    ah,scbattr        ; use current screen background attr
  4231.     mov    al,' '            ; use space for fill
  4232.     push    cx            ; save word count for Topview
  4233.     cld
  4234.     rep    stosw            ; copy to screen
  4235.     pop    cx            ; recover word count
  4236.     cmp    inemulator,0        ; in terminal emulator now?
  4237.     je    atscl2a            ; e = no
  4238.     cmp    flags.vtflg,0        ; emulating anything?
  4239.     jne    atscl2b            ; ne = yes
  4240. atscl2a:call    scrsync            ; synch Topview
  4241.     call    scron            ; turn screen back on if color card
  4242. atscl2b:pop    es
  4243.     pop    di
  4244. atscl3:    pop    dx
  4245.     pop    cx
  4246.     mov    scbattr,ch        ; recover current screen bkg attr
  4247.     pop    cx
  4248.     pop    ax            ; back to regs at call time
  4249.     cmp    inemulator,0        ; in terminal emulator now?
  4250.     je    atscl6            ; e = no
  4251.     cmp    flags.vtflg,0        ; emulating anything?
  4252.     je    atscl6            ; e = no, using DOS
  4253.     push    dx            ; do extended attributes
  4254.     push    ax
  4255.     push    bx
  4256.     push    cx
  4257.     mov    dx,ax            ; starting place
  4258.     mov    al,dh            ; row
  4259.     mov    cl,((vswidth+1)/2)*2    ; row char cells
  4260.     mul    cl
  4261.     add    al,dl            ; plus starting column
  4262.     adc    ah,0            ; char cells to starting place
  4263.     mov    dx,ax            ; save here
  4264.     mov    al,bh            ; ending row
  4265.     mul    cl
  4266.     add    al,bl            ; plus ending column
  4267.     adc    ah,0
  4268.     mov    bx,ax
  4269.     sub    bx,dx            ; number of cells -1 to clear
  4270.     inc    bx
  4271.     mov    cx,bx            ; cx = cells to clear
  4272.     xchg    bx,dx            ; bx = start offset, dx=cells
  4273.     push    es
  4274.     push    di
  4275.     les    di,vsat_ptr        ; where attributes are stored
  4276.     shr    cx,1            ; cells to bytes, rounded down
  4277.     inc    bx            ; round up
  4278.     shr    bx,1            ; cells to bytes
  4279.     jc    atscl4            ; c = no odd start, can do whole bytes
  4280.     and    byte ptr es:[di+bx-1],0fh ; clear initial (high) nibble
  4281.     dec    dx            ; one less cell
  4282. atscl4:    add    di,bx            ; offset plus start byte
  4283.     xor    al,al
  4284.     cld
  4285.     rep    stosb            ; clear those bytes
  4286.     test    dl,1            ; odd nibble at the end?
  4287.     jz    atscl5            ; z = no, done
  4288.     and    byte ptr es:[di],0f0h    ; clear last (low) nibble
  4289. atscl5:    pop    di
  4290.     pop    es
  4291.     pop    cx
  4292.     pop    bx
  4293.     pop    ax
  4294.     mov    dl,ah            ; first row
  4295.     mov    dh,bh            ; last row
  4296.     call    touchup            ; repaint this part of the screen
  4297.     pop    dx            ; finish cleaning stack
  4298. atscl6:    ret
  4299. atsclr    endp
  4300.  
  4301.  
  4302. ; Screen-scrolling routines.
  4303.      
  4304. fhomwnd    proc    far            ; "home" to start of the buffer
  4305.     mov    cl,byte ptr low_rgt+1    ; save this many lines
  4306.     inc    cl            ; full text screen
  4307.     xor    ch,ch
  4308.     call    putcirc            ; save them
  4309.     mov    linec,0            ; reset the current pointer
  4310.     call    getcirc            ; now get the new screen
  4311.     clc
  4312.     ret
  4313. fhomwnd    endp
  4314.      
  4315. fendwnd    proc    far            ; "end" to end of the buffer
  4316.     mov    cl,byte ptr low_rgt+1    ; save this many lines
  4317.     inc    cl            ; full text screen
  4318.     xor    ch,ch
  4319.     call    putcirc            ; save them
  4320.     mov    ax,lcnt            ; reset the current pointer
  4321.     mov    linec,ax        ; save the results
  4322.     call    getcirc            ; now get the new screen
  4323.     clc
  4324.     ret
  4325. fendwnd    endp
  4326.      
  4327. fdnwpg    proc    far            ; scroll down 1 page
  4328.     mov    cl,byte ptr low_rgt+1    ; save this many lines
  4329.     inc    cl            ; full text screen
  4330.     xor    ch,ch
  4331.     call    putcirc            ; save them
  4332.     mov    ax,linec        ; reset the current pointer
  4333.     add    ax,cx
  4334.     cmp    ax,lcnt            ; did we go past the end?
  4335.     jbe    dnwpg1            ; be = no, we're OK
  4336.     mov    ax,lcnt            ; yup, back up
  4337. dnwpg1:    mov    linec,ax        ; save the results
  4338.     call    getcirc            ; now get the new screen
  4339.     clc
  4340.     ret
  4341. fdnwpg    endp
  4342.      
  4343. fdnone    proc    far            ; scroll down 1 line
  4344.     mov    cl,byte ptr low_rgt+1    ; save this many lines
  4345.     inc    cl            ; full text screen
  4346.     xor    ch,ch
  4347.     call    putcirc            ; save them
  4348.     mov    ax,linec        ; reset the current pointer
  4349.     inc    ax            ;  to the next line
  4350.     cmp    ax,lcnt            ; oops, did we go past the end?
  4351.     jbe    dnone1            ; be = no, we're OK
  4352.     mov    ax,lcnt            ; yup, back up
  4353. dnone1:    mov    linec,ax        ; save the results
  4354.     call    getcirc            ; now get the new screen
  4355.     clc
  4356.     ret
  4357. fdnone    endp
  4358.      
  4359. fupwpg    proc    far            ; scroll up 1 page
  4360.     mov    cl,byte ptr low_rgt+1    ; save this many lines
  4361.     inc    cl            ; full text screen
  4362.     xor    ch,ch
  4363.     call    putcirc            ; save a full screen
  4364.     mov    ax,linec        ; reset the current pointer
  4365.     sub    ax,cx            ;  to the previous page
  4366.     jge    upwpg1            ; ge = not past end, we're OK
  4367.     xor    ax,ax            ; stop at the beginning of the buffer
  4368. upwpg1:    mov    linec,ax        ; line counter to use
  4369.     call    getcirc            ; get the new screen
  4370.     clc
  4371.     ret
  4372. fupwpg    endp
  4373.      
  4374. fupone    proc    far            ; scroll up 1 line
  4375.     mov    cl,byte ptr low_rgt+1    ; save this many lines
  4376.     inc    cl            ; full text screen
  4377.     xor    ch,ch
  4378.     call    putcirc            ; save them
  4379.     mov    ax,linec        ; reset the current pointer
  4380.     sub    ax,1            ;  to the previous line
  4381.     jge    upone1            ; ge = not past end, we're OK
  4382.     xor    ax,ax            ; yup, back up
  4383. upone1:    mov    linec,ax        ; save the results
  4384.     call    getcirc            ; now get the new screen
  4385.     clc
  4386.     ret
  4387. fupone    endp
  4388.  
  4389. ; Horizontal scrolling keyboard verbs
  4390. frtpage    proc    far
  4391.     mov    cx,20            ; step size
  4392.     call    rtcommon
  4393.     ret
  4394. frtpage    endp
  4395.  
  4396. frtone    proc    far
  4397.     mov    cx,1
  4398.     call    rtcommon
  4399.     ret
  4400. frtone    endp
  4401.  
  4402. ; Move screen to the right margin by CX columns
  4403. rtcommon proc    near
  4404.     push    bx
  4405.     mov    bl,byte ptr cursor+1    ; current cursor row
  4406.     xor    bh,bh
  4407.     mov    al,linescroll[bx]    ; horz scroll in effect for this line
  4408.     pop    bx
  4409.     add    al,handhsc         ; plus hand scrolling now present
  4410.     add    al,crt_cols        ; right most char on visible screen
  4411.     adc    ah,0
  4412.     cmp    ax,vswidth        ; too far already?
  4413.     ja    rtcomm2            ; a = yes, do nothing
  4414.     sub    ax,vswidth        ; available distance
  4415.     neg    ax
  4416.     cmp    ax,cx            ; space vs desired scroll
  4417.     jbe    rtcomm1            ; be = less than desired, use space
  4418.     mov    ax,cx            ; enough room, use desired scroll
  4419. rtcomm1:add    handhsc,al        ; indicate how much done by hand
  4420.     call    repaint
  4421. rtcomm2:clc
  4422.     ret
  4423. rtcommon endp
  4424.  
  4425. flfpage    proc    far
  4426.     mov    cx,20            ; step size
  4427.     call    lfcommon
  4428.     ret
  4429. flfpage    endp
  4430.  
  4431. flfone    proc    far
  4432.     mov    cx,1            ; step size
  4433.     call    lfcommon
  4434.     ret
  4435. flfone    endp
  4436.  
  4437. ; Move screen toward left margin by CX columns
  4438. lfcommon proc    near
  4439.     push    bx
  4440.     mov    bl,byte ptr cursor+1    ; current cursor row
  4441.     xor    bh,bh
  4442.     mov    al,linescroll[bx]    ; horz scroll in effect for this line
  4443.     pop    bx
  4444.     add    al,handhsc        ; available distance to move
  4445.     jz    lfcomm2            ; z = no space to mov
  4446.     sub    al,cl            ; minus out desired jump
  4447.     jge    lfcomm1            ; ge = no overscroll the wrong way
  4448.     add    cl,al            ; reduce cx request by overage
  4449. lfcomm1:sub    handhsc,cl        ; successful, new handhsc
  4450.     call    repaint
  4451. lfcomm2:clc
  4452.     ret
  4453. lfcommon endp
  4454.  
  4455. ; Scrolling routines.  vtscru scrolls up, vtscrd scrolls down 'scroll'
  4456. ; rows. Top lines are saved in the circular buffer before scrolling up.
  4457. ; When running under an Environment control number of line positions moved
  4458. ; to be less than scrolling region.
  4459. ; All registers are preserved.
  4460. ;
  4461. ; Screen scroll up "scroll" lines (text moves up) for terminal emulator use.
  4462.      
  4463. vtscru    proc    near
  4464.     push    ax
  4465.     push    bx
  4466.     push    cx
  4467.     push    dx
  4468.     push    si
  4469.     push    di
  4470.     mov    al,mar_bot        ; compute size of scroll
  4471.     sub    al,mar_top
  4472.     inc    al            ; lines in scrolling region
  4473.     mov    dl,scroll        ; desired scroll
  4474.     xor    dh,dh
  4475.     cmp    dl,al            ; scrolling more than needed?
  4476.     jbe    vtscru1            ; be = no
  4477.     mov    dl,al            ; limit scrolling
  4478.     mov    scroll,al
  4479. vtscru1:or    dl,dl
  4480.     jnz    vtscru2    
  4481.     jmp    vtscru9            ; z = nothing to do
  4482.  
  4483. vtscru2:cmp    mar_top,0        ; scrolling the top screen line?
  4484.     jne    vtscru5            ; ne = no, do not save in roll back
  4485.     mov    cx,dx            ; cx is how many lines
  4486.     call    putcirc            ; put screen lines in circular buffer
  4487.     
  4488.     add    linec,cx        ; (BDT) increment the current line
  4489.     mov    cx,linec        ; new current line number
  4490.     sub    cx,lcnt            ; minus # in buf = qty new lines added
  4491.     jc    vtscru3            ; c = not extending buffer
  4492.     add    lcnt,cx            ; (BDT) increment the line counter
  4493. vtscru3:mov    cx,lcnt            ; (BDT) check: are we
  4494.     cmp    cx,lmax            ; (BDT) beyond the end?
  4495.     jb    vtscru5            ; (BDT) b = no
  4496.     sub    cx,lmax            ; (BDT) compute overflow count
  4497.     add    linef,cx        ; (BDT) adjust the "first" line
  4498.     mov    cx,linef        ; (BDT) check: time to wrap?
  4499.     cmp    cx,linee        ; (BDT) ...
  4500.     jb    vtscru4            ; (BDT) b = no
  4501.     sub    cx,linee        ; (BDT) yup
  4502.     mov    linef,cx        ; (BDT) adjust it
  4503. vtscru4:mov    cx,lmax            ; (BDT) get the maximum line count
  4504.     mov    lcnt,cx            ; (BDT) reset the line counter
  4505.     mov    linec,cx        ; (BDT) reset the current line
  4506.  
  4507. vtscru5:mov    di,word ptr vs_ptr    ; offset of virtual screen
  4508.     mov    cl,vswidth
  4509.     mov    al,mar_top        ; top line number (from 0)
  4510.     mul    cl            ; times chars/line
  4511.     add    ax,ax            ; char + attribute
  4512.     add    di,ax            ; destination (mar_top)
  4513.     mov    al,dl            ; number of lines to scroll
  4514.     mov    cl,vswidth
  4515.     mul    cl            ; vswidth * total lines to scroll
  4516.     mov    bx,ax            ; number of cells to clear
  4517.     add    ax,ax            ; bytes
  4518.     mov    si,di
  4519.     add    si,ax            ; src is that many bytes down screen
  4520.     mov    al,mar_bot        ; lines in scrolling region
  4521.     sub    al,mar_top
  4522.     inc    al
  4523.     sub    al,dl            ; minus scrolled portion
  4524.     mul    cl            ; times words per line
  4525.     mov    cx,ax            ; number of cells to copy
  4526.     mov    dh,scbattr        ; need this for later (in seg data)
  4527.     push    cx            ; save number of words for attribute
  4528.     push    es
  4529.     push    ds
  4530.     mov    ax,word ptr vs_ptr+2    ; segment of vscreen
  4531.     mov    ds,ax
  4532.     mov    es,ax
  4533.     cld
  4534.     rep    movsw            ; copy src to dest
  4535.     mov    cx,bx            ; count of words to clear
  4536.     mov    ah,dh            ; default attriubte
  4537.     mov    al,' '            ; filler for clearing a line
  4538.     rep    stosw            ; store after new src
  4539.     pop    ds
  4540.     pop    es
  4541.                     ; bx is number of words cleared
  4542.     mov    di,word ptr vsat_ptr    ; offset of attributes
  4543.     mov    cl,((vswidth+1)/2)*2    ; char cells per attributes line
  4544.     mov    al,mar_top        ; top line number (from 0)
  4545.     mul    cl            ; times cells per line
  4546.     shr    ax,1            ; two char's of attributes per byte
  4547.     add    di,ax            ; destination (mar_top)
  4548.     mov    si,di
  4549.  
  4550.     mov    al,dl            ; number of lines to scroll
  4551.     mov    cl,((vswidth+1)/2)*2    ; cells/line for attributes
  4552.     mul    cl            ; vswidth * total lines to scroll
  4553.     mov    bx,ax            ; number of cells to clear
  4554.     shr    bx,1            ; was char cells, now use bytes
  4555.     add    si,bx            ; src is that many bytes down screen
  4556.     pop    cx            ; number of vscreen cells copied
  4557.     shr    cx,1            ; two cells per byte of attributes
  4558.     push    es
  4559.     push    ds
  4560.     mov    ax,word ptr vsat_ptr+2    ; segment of vsatt
  4561.     mov    ds,ax
  4562.     mov    es,ax
  4563.     cld
  4564.     rep    movsb            ; copy src to dest
  4565.     mov    cx,bx            ; count of bytes to clear
  4566.     xor    al,al            ; default attributes of none
  4567.     rep    stosb            ; store after new src
  4568.     pop    ds
  4569.     pop    es
  4570.     cmp    writemode,0        ; use direct screen writing?
  4571.     je    vscru5a            ; e = yes
  4572.     cmp    tekflg,tek_active+tek_sg ; special graphics mode?
  4573.     jne    vscru5b            ; ne = no
  4574.  
  4575. vscru5a:cmp    tekflg,tek_active+tek_sg ; special graphics mode?
  4576.     jne    vtscru8            ; ne = no
  4577.     call    tekremcursor        ; turn off text cursor
  4578. vscru5b:mov    dosetcursor,-1        ; don't turn on automatically
  4579.     mov    al,' '            ; write space
  4580.     mov    ah,scbattr        ; in normal colors
  4581.     xor    dl,dl            ; at mar_top, left margin
  4582.     mov    dh,mar_top        ; to set normal text mode for the
  4583.     cmp    tekflg,tek_active+tek_sg ; special graphics mode?
  4584.     jne    vscru5d            ; ne = no
  4585.     call    ttxtchr            ; graphics adapter
  4586. vscru5d:mov    ax,0600h        ; scroll up whole region
  4587.     mov    dh,mar_bot        ; bottom row
  4588.     mov    dl,crt_cols
  4589.     cmp    dl,80            ; more than physical screen?
  4590.     jbe    vscru5e            ; be = no
  4591.     mov    dl,80
  4592. vscru5e:dec    dl            ; right most physical col for scroll
  4593.     mov    ch,mar_top        ; top row of scrolling region
  4594.     xor    cl,cl            ; left most column
  4595.     mov    bh,scbattr        ; attributes
  4596.     mov    bl,dh
  4597.     sub    bl,ch            ; region size - 1 line
  4598.     jz    vscru2b            ; z = region is 1 line, do one scroll
  4599.     mov    al,scroll        ; number of lines to scroll, from msz
  4600. vscru2a:cmp    al,bl            ; want to scroll more that than?
  4601.     jbe    vscru2b            ; be = no
  4602.     push    ax
  4603.     mov    al,bl            ; limit to region - 1 for Windows
  4604.     int    screen            ;  and do in parts
  4605.     pop    ax
  4606.     sub    al,bl            ; al = amount yet to scroll
  4607.     jmp    short vscru2a        ; do next part
  4608. vscru2b:int    screen            ; scroll up that region
  4609.     mov    dx,cursor
  4610.     mov    dosetcursor,dx        ; reminder of where to set cursor
  4611.     jmp    short vtscru9
  4612.  
  4613. vtscru8:mov    dh,mar_bot        ; real text mode
  4614.     mov    dl,mar_top        ; setup touchup, lines changed
  4615.     call    touchup            ; touch up real screen
  4616. vtscru9:pop    di
  4617.     pop    si
  4618.     pop    dx
  4619.     pop    cx
  4620.     pop    bx
  4621.     pop    ax
  4622.     ret
  4623. vtscru    endp
  4624.  
  4625. ; Screen-roll down. Move text down scroll lines, for terminal emulator only.
  4626. vtscrd    proc    near
  4627.     push    ax
  4628.     push    bx
  4629.     push    cx
  4630.     push    dx
  4631.     push    si
  4632.     push    di
  4633.     push    bp
  4634.     push    es
  4635.     les    si,vs_ptr        ; source is top line of virtual screen
  4636.     mov    al,mar_top        ; top margin line (0..)
  4637.     mov    cl,vswidth        ; chars across vscreen
  4638.     mul    cl
  4639.     add    ax,ax            ; words to bytes
  4640.     add    si,ax            ; offset of start of top line
  4641.     mov    bp,si            ; remember top line for later
  4642.     mov    cl,mar_bot        ; compute number of lines to move
  4643.     sub    cl,mar_top
  4644.     inc    cl            ; qty of lines in region
  4645.     mov    ch,scroll
  4646.     cmp    ch,cl            ; want to scroll more than region?
  4647.     jbe    vtscrd1            ; be = no
  4648.     mov    ch,cl            ; set scroll to whole region
  4649.     mov    scroll,ch        ; remember for attributes
  4650. vtscrd1:sub    cl,ch             ; less lines to be skipped
  4651.     mov    bl,ch            ; save effective scroll for below
  4652.     mov    al,vswidth        ; number of character cells
  4653.     mul    cl
  4654.     mov    cx,ax            ; number of words in the movement
  4655.     dec    ax            ; compute to end word
  4656.     add    ax,ax            ; number of bytes
  4657.     add    si,ax            ; go to the end
  4658.     mov    di,si
  4659.     mov    al,vswidth        ; words in a line buffer
  4660.     mul    bl            ; number of chars dest is below src
  4661.     mov    bx,ax            ; save number of chars here for clear
  4662.     add    ax,ax            ; number of bytes (char + attribute)
  4663.     add    di,ax            ; destination offset
  4664.     push    ds
  4665.     mov    ax,es
  4666.     mov    ds,ax
  4667.     std
  4668.     rep    movsw            ; copy down the lines
  4669.     cld
  4670.     pop    ds
  4671.     mov    di,bp            ; fill top line in scrolling region
  4672.     mov    ah,scbattr
  4673.     mov    al,' '
  4674.     mov    cx,bx            ; number of char cells to clear
  4675.     rep    stosw            ; fill top line(s) with spaces
  4676.                     ; do extended attributes the same way
  4677.     les    si,vsat_ptr        ; source of extended attributes
  4678.     mov    al,mar_top        ; top margin line (0..)
  4679.     mov    cl,((vswidth+1)/2)*2    ; attribute cells/line
  4680.     mul    cl
  4681.     shr    ax,1            ; two attributes per byte
  4682.     add    si,ax            ; offset of start of top line
  4683.     mov    bp,si            ; remember top line for later
  4684.     mov    cl,mar_bot        ; compute number of lines to move
  4685.     sub    cl,mar_top
  4686.     inc    cl            ; qty of lines in region
  4687.     mov    ch,scroll
  4688.     sub    cl,ch             ; less lines to be skipped
  4689.     mov    bl,ch            ; save effective scroll for below
  4690.     mov    al,((vswidth+1)/2)*2    ; number of attribute cells/line
  4691.     mul    cl
  4692.     shr    ax,1            ; two attributes per byte
  4693.     mov    cx,ax            ; number of bytes in the movement
  4694.     dec    ax            ; compute to end byte
  4695.     add    si,ax            ; go to the end
  4696.     mov    di,si
  4697.     mov    al,((vswidth+1)/2)*2    ; number of attribute cells/line
  4698.     mul    bl            ; number of cells dest is below src
  4699.     shr    ax,1            ; two attributes per byte
  4700.     mov    bx,ax            ; save number of bytes here for clear
  4701.     add    di,ax            ; destination offset
  4702.     push    ds
  4703.     mov    ax,es
  4704.     mov    ds,ax
  4705.     std
  4706.     rep    movsb            ; copy down the lines
  4707.     cld
  4708.     pop    ds
  4709.     mov    di,bp            ; fill top line in scrolling region
  4710.     xor    al,al            ; null attributes for filler
  4711.     mov    cx,bx            ; number of attributes bytes to clear
  4712.     rep    stosb            ; fill top line(s) with spaces
  4713.     pop    es
  4714.     pop    bp
  4715.     cmp    writemode,0        ; use direct screen writing?
  4716.     je    vscrd1            ; e = yes
  4717.     cmp    tekflg,tek_active+tek_sg ; special graphics mode?
  4718.     jne    vscrd3a            ; ne = no
  4719. vscrd1:    cmp    tekflg,tek_active+tek_sg ; special graphics mode?
  4720.     je    vscrd3            ; e = yes
  4721.     mov    dl,mar_top        ; setup touchup, lines changed
  4722.     mov    dh,mar_bot
  4723.     call    touchup            ; touch up real screen
  4724.     jmp    short vscrd8
  4725.  
  4726. vscrd3:    call    tekremcursor        ; turn off text cursor
  4727. vscrd3a:mov    dosetcursor,-1        ; don't turn on automatically
  4728.     mov    al,' '            ; write space
  4729.     mov    ah,scbattr        ; in normal colors
  4730.     xor    dl,dl            ; at mar_bot, left margin
  4731.     mov    dh,mar_bot        ; to set normal text mode for the
  4732.     cmp    tekflg,tek_active+tek_sg ; special graphics mode?
  4733.     jne    vscrd3b            ; ne = no
  4734.     call    ttxtchr            ; graphics adapter
  4735. vscrd3b:mov    ax,0700h        ; scroll down whole region
  4736.     mov    ch,mar_top        ; top margin line
  4737.     xor    cl,cl            ; left most column
  4738.     mov    dh,mar_bot        ; bottom margin line
  4739.     mov    dl,crt_cols
  4740.     cmp    dl,80            ; more than physical screen?
  4741.     jbe    vscrd3c            ; be = no
  4742.     mov    dl,80
  4743. vscrd3c:dec    dl            ; right most physical col for scroll
  4744.     mov    bh,scbattr        ; attributes
  4745.     mov    bl,dh
  4746.     sub    bl,ch            ; region size - 1 line
  4747.     jz    vscrd7             ; z = region is 1 line, do one scroll
  4748.     mov    al,scroll        ; number of lines to scroll, from msz
  4749. vscrd7:    cmp    al,bl            ; want to scroll more that than?
  4750.     jbe    vscrd2            ; be = no
  4751.     push    ax
  4752.     mov    al,bl            ; limit to region-1 for Windows
  4753.     int    screen            ;  and do in parts
  4754.     pop    ax
  4755.     sub    al,bl            ; get remainder
  4756.     jmp    short vscrd7        ; do next part
  4757. vscrd2:    int    screen            ; scroll it down
  4758.     mov    dx,cursor
  4759.     mov    dosetcursor,dx        ; reminder of where to set cursor
  4760. vscrd8:    pop    di
  4761.     pop    si
  4762.     pop    dx
  4763.     pop    cx
  4764.     pop    bx
  4765.     pop    ax
  4766.     ret
  4767. vtscrd    endp
  4768.  
  4769. ; Put the top cx lines from the virtual screen in to the circular buffer
  4770. ; starting at line index linec (counted from zero, modulo linee).
  4771. putcirc    proc    near
  4772.     jcxz    putcir6            ; z = no lines to save
  4773.     cmp    lmax,0            ; any buffer space?
  4774.     jne    putcir7            ; ne = yes, have some
  4775. putcir6:ret
  4776. putcir7:push    ax
  4777.     push    bx
  4778.     push    cx
  4779.     push    dx
  4780.     push    si
  4781.     push    di
  4782.     push    es
  4783.     cld
  4784.     mov    pageready,-1        ; ems page number currently active
  4785.     mov    si,word ptr vs_ptr    ; offset of screen buffer
  4786.     mov    bx,linef        ; index of the first line
  4787.     add    bx,linec        ; add the current line counter
  4788.     dec    bx
  4789. putcir1:inc    bx
  4790.     cmp    bx,linee        ; at the end of the buffer now?
  4791.     jb    putcir2            ; b = no
  4792.     sub    bx,linee        ; backup to start of buffer
  4793. putcir2:mov    ax,bx            ; line index
  4794.     call    emsfixup        ; do expanded memory conversion work
  4795.     mul    ppl            ; times paragraphs per line
  4796.     add    ax,iniseg        ; plus initial seg of buffer
  4797.     mov    es,ax            ; now we have the segment pointer
  4798.     xor    di,di            ; buffer offset is always 0
  4799.     push    cx            ; save the number of lines
  4800.     mov    cx,rollwidth        ; get the number of characters to move
  4801.     push    si            ; save starting vscreen offset
  4802.     push    ds            ; get the offset of the screen
  4803.     cld
  4804.     mov    ds,word ptr vs_ptr+2    ; seg of vscreen
  4805.     rep    movsw            ; move them
  4806.     pop    ds            ; restore DS
  4807.     pop    si            ; vscreen offset
  4808.     add    si,vswidth*2        ; inc to next vscreen line
  4809.     pop    cx            ; restore the line count
  4810.     loop    putcir1            ; go back for more
  4811.     pop    es
  4812.     pop    di
  4813.     pop    si
  4814.     pop    dx
  4815.     pop    cx
  4816.     pop    bx
  4817.     pop    ax
  4818.     clc
  4819.     ret
  4820. putcirc    endp
  4821.  
  4822. ; Get CX lines from the circular buffer, non destructively, starting at
  4823. ; line index linec (counted from zero, modulo linee) and put them at
  4824. ; the top of the virtual screen. Fewer lines are written if the buffer
  4825. ; holds fewer than CX.
  4826. getcirc    proc    near
  4827.     or    cx,cx            ; check on qty
  4828.     jnz    getcir0            ; nz = some
  4829.     ret
  4830. getcir0:push    ax
  4831.     push    bx
  4832.     push    cx
  4833.     push    dx
  4834.     push    si
  4835.     push    di
  4836.     push    es
  4837.     mov    pageready,-1        ; ems page number currently active
  4838.     les    di,vs_ptr        ; seg and offset of vscreen
  4839.     mov    bx,linef        ; get the first line pointer
  4840.     add    bx,linec        ; add the current line counter
  4841.     dec    bx
  4842.     cld
  4843. getcir1:inc    bx
  4844.     cmp    bx,linee        ; at the end of the buffer now?
  4845.     jb    getcir2            ; b = no
  4846.     sub    bx,linee        ; backup to start of buffer
  4847. getcir2:mov    ax,bx            ; line index
  4848.     call    emsfixup        ; do expanded memory conversion work
  4849.     mul    ppl            ; times paragraphs per line
  4850.     add    ax,iniseg        ; plus initial seg of buffer
  4851.     xor    si,si            ; initial offset is always 0
  4852.     push    cx            ; save the number of lines
  4853.     mov    cx,rollwidth        ; get the number of characters to move
  4854.     push    di            ; save vscreen offset
  4855.     push    ds            ; save DS for a tad
  4856.     mov    ds,ax            ; now we have the segment pointer
  4857.     rep    movsw            ; move them
  4858.     pop    ds            ; restore DS
  4859.     pop    di            ; recover vscreen offset
  4860.     add    di,vswidth*2        ; next vscreen line
  4861.     pop    cx            ; restore the line count
  4862.     loop    getcir1            ; go back for more
  4863.     call    repaint            ; repaint screen
  4864.     pop    es
  4865.     pop    di
  4866.     pop    si
  4867.     pop    dx
  4868.     pop    cx
  4869.     pop    bx
  4870.     pop    ax
  4871.     clc
  4872.     ret
  4873. getcirc    endp
  4874.  
  4875. ; Convert rollback line number in AX to line number in ems page, and invoke 
  4876. ; that page. Destroys dx, returns ax as line number in page.
  4877. emsfixup proc    near
  4878.     cmp    emsrbhandle,0        ; EMS in use?
  4879.     jg    emsfix1            ; g = yes (-1 is not in use)
  4880.     ret
  4881. emsfix1:xor    dx,dx
  4882.     div    lineems            ; line number / lines per ems page
  4883.     push    bx
  4884.     mov    bx,ax            ; quotient, page number
  4885.     mov    ax,dx            ; remainder, line in page
  4886.     cmp    bx,pageready        ; is this page now present?
  4887.     je    emsfix2            ; e = yes
  4888.     mov    pageready,bx        ; remember
  4889.     push    ax
  4890.     mov    ah,emsmapmem        ; map logical page in bx
  4891.     xor    al,al            ;  to physical page zero
  4892.     mov    dx,emsrbhandle        ; our ems rollback handle
  4893.     int    emsint
  4894.     pop    ax            ; return ax as line in page
  4895. emsfix2:pop    bx
  4896.     ret
  4897. emsfixup endp
  4898.  
  4899. ; Repaint screen from the vscreen buffer
  4900. repaint    proc    near
  4901.     push    dx
  4902.     xor    dl,dl            ; top row
  4903.     mov    dh,crt_lins        ; physical screen rows-1, incl status
  4904.     call    touchup
  4905.     pop    dx
  4906.     ret
  4907. repaint    endp
  4908.  
  4909. ; Repaint part of screen from the vscreen buffer, with linescroll offset
  4910. ; dh is bottom line number, dl is top line number (dh >= dl)
  4911. ftouchup proc    far
  4912.     call    touchup
  4913.     ret
  4914. ftouchup endp
  4915.  
  4916. touchup    proc    near            ; get lines from virtual screen
  4917.     cmp    flags.vtflg,ttgenrc    ; terminal type of none?
  4918.     jne    touch1            ; ne = no
  4919.     ret
  4920. touch1:    push    ax
  4921.     push    bx
  4922.     push    cx
  4923.     push    dx
  4924.     push    si
  4925.     push    di
  4926.     push    es
  4927.     mov    cl,dh            ; last row to change
  4928.     sub    cl,dl            ; number of lines -1
  4929.     cmp    cl,crt_lins        ; out of bounds value?
  4930.     jbe    touch1b            ; be = no
  4931.     xor    cl,cl            ; stay sane
  4932. touch1b:inc    cl            ; number of lines to update
  4933.     xor    ch,ch
  4934.     cmp    tekflg,tek_active+tek_sg ; special graphics mode?
  4935.     je    touch1c            ; e = yes, skip text screen update
  4936.     test    tekflg,tek_active    ; other graphics mode?
  4937.     jnz    touch9            ; nz = yes, no touchup
  4938.  
  4939.     call    scroff            ; turn off text screen
  4940.     mov    es,tv_segs        ; get the segment of the screen
  4941.     mov    di,tv_sego        ; initial screen offset
  4942. touch1c:mov    al,crt_cols        ; physical screen width
  4943.     mul    dl            ; chars into physical screen
  4944.     add    ax,ax            ; chars to bytes
  4945.     add    di,ax            ; offset of start of phy update area
  4946.     mov    si,word ptr vs_ptr
  4947.     mov    al,vswidth        ; chars per line
  4948.     mul    dl            ; ax = bytes to first vscreen line
  4949.     add    ax,ax            ; chars to bytes
  4950.     add    si,ax            ; si = starting vscreen line offset
  4951.     mov    bl,dl            ; top line number
  4952.     xor    bh,bh            ; index for linescroll
  4953.     cld
  4954.     push    dx
  4955.     mov    dh,dl            ; set row into dh, temporarily
  4956. touch2:    push    si            ; save the current line pointer
  4957.     push    cx            ; save the number of lines
  4958.     mov    cl,crt_cols        ; get the number of characters to move
  4959.     xor    ch,ch
  4960.     mov    al,linescroll[bx]    ; get horiz scroll for this line
  4961.     add    al,handhsc        ; hand done shift
  4962.     xor    ah,ah
  4963.     add    ax,ax            ; char cells to words
  4964.     add    si,ax            ; offset into vscreen
  4965.     cmp    writemode,0        ; use direct writing?
  4966.     je    touch2a            ; e = yes
  4967.     cmp    tekflg,tek_active+tek_sg ; special graphics mode?
  4968.     je    touch2a            ; e = yes
  4969.     call    tchbios            ; Bios writing
  4970.     jmp    short touch4
  4971. touch2a:cmp    tekflg,tek_active+tek_sg ; special graphics mode?
  4972.     jne    touch3            ; ne = no
  4973.     push    es
  4974.     mov    es,word ptr vs_ptr+2    ; es:si is source of data
  4975.     call    ttxtline        ; display whole line
  4976.     pop    es
  4977.     jmp    short touch4
  4978.  
  4979. touch3:    push    ds
  4980.     mov    ds,word ptr vs_ptr+2    ; segment of vscreen
  4981.     rep    movsw            ; from vscreen+hsc to real screen+0
  4982.     pop    ds
  4983.  
  4984. touch4:    pop    cx            ; restore the line count
  4985.     pop    si            ; restore the buffer counter
  4986.     inc    bx            ; for next line
  4987.     add    si,vswidth*2        ; point to next line
  4988.     inc    dh
  4989.     loop    touch2            ; go back for more
  4990.     pop    dx
  4991.     cmp    writemode,0        ; direct screen writing?
  4992.     jne    touch4a            ; ne = no, Bios
  4993.     cmp    tekflg,tek_active+tek_sg ; special graphics mode?
  4994.     jne    touch5            ; ne = no
  4995. touch4a:mov    ah,byte ptr cursor+1    ; row of cursor
  4996.     cmp    ah,dl            ; cursor before this line?
  4997.     jb    touch9            ; b = yes, skip cursor
  4998.     cmp    ah,dh            ; cursor after this line?
  4999.     ja    touch9            ; a = yes, skip cursor
  5000.     mov    cursorst,0        ; say cursor has been zapped off
  5001.     mov    dx,cursor
  5002.     call    setpcur            ; reset the cursor
  5003.     jmp    short touch9        ; and all done here
  5004.  
  5005. touch5:    cmp    tv_mode,0h        ; TV active?
  5006.     je    touch8            ; e = no
  5007.     mov    cl,dh            ; tell Topview/Desqview
  5008.     sub    cl,dl            ; number of lines -1
  5009.     cmp    cl,crt_lins        ; out of bounds value?
  5010.     jbe    touch7            ; be = no
  5011.     xor    cl,cl            ; stay sane
  5012. touch7:    inc    cl            ; number of lines to update
  5013.     mov    al,crt_cols        ; chars/line
  5014.     mul    cl
  5015.     mov    cx,ax            ; cx = words changed
  5016.     call    scrsync            ; synch Topview
  5017. touch8:    call    scron            ; turn on the screen
  5018. touch9:    pop    es
  5019.     pop    di
  5020.     pop    si
  5021.     pop    dx
  5022.     pop    cx
  5023.     pop    bx
  5024.     pop    ax
  5025.     ret
  5026. touchup    endp
  5027.  
  5028. ; Write screen via Bios. Enter with SI pointing at starting screen buffer
  5029. ; offset, dh is current screen row, cx has chars to write across a line.
  5030.  
  5031. tchbios proc    near
  5032.     push    bx
  5033.     xor    bh,bh            ; video page zero
  5034.     push    dx
  5035.     mov    ah,3
  5036.     int    screen
  5037.     mov    temp,dx            ; save current cursor
  5038.     pop    dx
  5039.     mov    cl,crt_cols
  5040.     xor    ch,ch
  5041.     xor    dl,dl            ; column zero
  5042.     cld
  5043.     push    ds
  5044.     mov    ds,word ptr vs_ptr+2    ; source is virtual screen buffer
  5045.     
  5046. tchbios1:push    cx
  5047.     mov    ah,2            ; set cursor position to dx
  5048.     int    screen
  5049.     lodsw                ; char+attribute
  5050.     mov    bl,ah            ; attribute
  5051.     mov    cx,1            ; one char
  5052.     mov    ah,9            ; write char at cursor position
  5053.     int    screen            ; do the Bios Int 10h call
  5054.     inc    dl            ; next column
  5055.     pop    cx
  5056.     loop    tchbios1
  5057.     pop    ds
  5058.     push    dx
  5059.     mov    dx,temp            ; starting cursor position
  5060.     mov    ah,2            ; set it back there
  5061.     int    screen
  5062.     pop    dx
  5063.     pop    bx
  5064.     ret
  5065. tchbios    endp
  5066.  
  5067. ; Character write/read and cursor manipulation routines for terminal emulator
  5068. ; All registers other than returned values are preserved.
  5069.  
  5070. ; Read char and attributes under virtual cursor (DH = row, DL = column).
  5071. ; Returns AL = character, AH = video attributes, CL = logical attribute bit
  5072. ; pair.
  5073. getatch    proc    near
  5074.     push    bx
  5075.     push    si
  5076.     push    es
  5077.     mov    al,vswidth        ; width of vscreen line
  5078.     mul    dh            ; count down rows (0..)
  5079.     add    al,dl            ; add column
  5080.     adc    ah,0
  5081.     add    ax,ax            ; times two for char and attrib
  5082.     mov    bx,ax            ; address subscript
  5083.     les    si,vs_ptr        ; main vscreen
  5084.     mov    ax,es:[si+bx]        ; obtain char and attribute
  5085.  
  5086.     push    ax            ; save ah attributes
  5087.     mov    al,((vswidth+1)/2)*2    ; char cells/line for attributes
  5088.     mul    dh            ; times rows
  5089.     add    al,dl            ; add column
  5090.     adc    ah,0
  5091.     shr    ax,1            ; two attributes per byte
  5092.     mov    bx,ax
  5093.     pop    ax
  5094.     les    si,vsat_ptr        ; extended attributes
  5095.     mov    bh,es:[bx+si]        ; obtain extended attribute byte
  5096.     test    dl,1            ; odd column (needs shift)?
  5097.     jz    getatch1        ; z = no, use lower nibble
  5098.     mov    cl,4            ; four bits of shift
  5099.     shr    bh,cl
  5100. getatch1:and    bh,0fh            ; have four extended attribute bits
  5101.     mov    cl,bh            ; return in cl
  5102.     pop    es
  5103.     pop    si
  5104.     pop    bx
  5105.     ret
  5106. getatch    endp
  5107.  
  5108. ; Set virtual cursor postion
  5109. ; DL = column, DH = row, both counted from 0,0 at upper left corner.
  5110. ; If not displaced, handhsc = 0, then scroll left if virtual > crt_cols.
  5111. ; If displaced, handhsc != 0, then scroll right if virtual < handhsc.
  5112. ; For the D463/D470 only, set carry bit (for setatch) if the cursor is off
  5113. ; the visible screen and horizontal scrolling is disabled.
  5114.  
  5115. setpos    proc    near
  5116.     push    ax
  5117.     push    es
  5118.     mov    ax,40h            ; look in Bios work area for phy cur
  5119.     mov    es,ax
  5120.     mov    ax,es:[50h]        ; page zero cursor postion is here
  5121.     pop    es
  5122.     cmp    ax,dx            ; same as where we are commanded?
  5123.     jne    setpos0            ; ne = no, do the work
  5124.     pop    ax
  5125.     ret
  5126. setpos0:push    bx
  5127.     push    cx
  5128.     push    dx            ; save outside virtual cursor
  5129.     mov    cl,crt_cols        ; physical screen width
  5130.     push    cx            ; save here
  5131.     cmp    inemulator,0        ; emulating?
  5132.     je    setpos9            ; e = no, no virtual screen
  5133.     cmp    tekflg,tek_active+tek_sg ; special graphics mode?
  5134.     jne    setpos1            ; ne = no
  5135.     test    flags.vtflg,ttd463+ttd470 ; doing DG D463/D470 emulation?
  5136.     jz    setpos1            ; z = no
  5137.     mov    bl,dh            ; get row
  5138.     xor    bh,bh
  5139.     cmp    dgwindcomp[bx],0    ; is this line compressed?
  5140.     je    setpos1            ; e = no
  5141.     mov    crt_cols,128        ; DG graphics, 5 dot chars, 128/line
  5142. setpos1:mov    ch,vswidth-1        ; leftmost legal margin (207-1)
  5143.     sub    ch,crt_cols        ; minus screen physical width
  5144.     xor    cl,cl        ; cl is flag for repainting needed (if != 0)
  5145.     xchg    handhsc,cl        ; hand-done horiz scroll, clear it
  5146.     or    cl,cl            ; need to undo it?
  5147.     jz    setpos2            ; z = no
  5148.     call    repaint            ; repaint screen without hand scroll
  5149.     xor    cl,cl            ; remove repaint indicator
  5150. setpos2:mov    bl,dh            ; current row
  5151.     xor    bh,bh
  5152.     mov    ah,linescroll[bx]    ; current horz scroll
  5153.  
  5154. setpos3:mov    al,dl            ; virtual column where we ought to be
  5155.     sub    al,ah            ; virtual - already scrolled    
  5156.     jc    setpos4            ; c = cursor off screen to the left
  5157.     cmp    al,crt_cols        ; beyond right physical screen?
  5158.     jb    setpos5            ; b = no, use this
  5159.     mov    cl,1            ; say need repaint
  5160.     inc    ah
  5161.     jc    setpos3a        ; c = over did it
  5162.     cmp    ah,ch            ; going beyond largest scroll?
  5163.     jbe    setpos3            ; be = no
  5164. setpos3a:mov    ah,ch            ; yes, stay here
  5165.     jmp    short setpos5        ; done, do real operation
  5166.  
  5167. setpos4:mov    cl,1            ; say repaint needed
  5168.     mov    ah,dl            ; reduce horz scroll
  5169.  
  5170. setpos5:or    cl,cl            ; repaint needed?
  5171.     jz    setpos8            ; z = no
  5172.     test    flags.vtflg,ttd463+ttd470 ; D463/D470?
  5173.     jz    setpos5a        ; z = no
  5174.     cmp    dghscrdis,0        ; D463/D470 horz scroll disabled?
  5175.     je    setpos5a        ; e = no, check auto vs manual
  5176.     stc                ; c = do not show on real screen
  5177.     jmp    short setposx        ; skip screen update
  5178.  
  5179. setpos5a:test    vtemu.vtflgop,vshscroll    ; horizontal scrolling, manual?
  5180.     jnz    setpos9            ; nz = yes, else auto
  5181.  
  5182. setpos5b:mov    bl,mar_top        ; auto scrolling, top row
  5183.     xor    bh,bh
  5184.     mov    cl,mar_bot
  5185.     sub    cl,bl
  5186.     xor    ch,ch
  5187.     inc    cx            ; lines in scrolling region
  5188. setpos6:cmp    linescroll[bx],ah    ; any change?
  5189.     je    setpos7            ; e = no
  5190.     mov    linescroll[bx],ah    ; set scroll for this line
  5191.     push    dx
  5192.     mov    dl,bl
  5193.     mov    dh,bl
  5194.     call    touchup            ; repaint this line
  5195.     pop    dx
  5196. setpos7:inc    bx
  5197.     loop    setpos6            ; do all lines in window
  5198.  
  5199. setpos7a:push    ax            ; now do status line
  5200.     push    si
  5201.     mov    cl,byte ptr low_rgt+1    ; examine whole screen
  5202.     inc    cl            ; lines in emulation part
  5203.     xor    ch,ch
  5204.     mov    bx,cx            ; remember for status line
  5205.     mov    si,offset linescroll
  5206.     mov    ah,[si]            ; smallest horizontal shift found
  5207.     cld
  5208. setpos10:lodsb                ; current line scroll to al
  5209.     cmp    al,ah            ; smaller than smallest?
  5210.     ja    setpos11        ; a = no
  5211.     mov    ah,al            ; remember smallest
  5212.     or    ah,ah            ; zero?
  5213.     jz    setpos11a        ; can't get any smaller than this
  5214. setpos11:loop    setpos10
  5215.  
  5216. setpos11a:cmp    linescroll[bx],ah    ; status line, need to scroll?
  5217.     je    setpos12        ; e = already smallest
  5218.     mov    linescroll[bx],ah    ; modify status line
  5219.     push    dx
  5220.     mov    dl,bl
  5221.     mov    dh,bl
  5222.     call    touchup            ; redraw status line
  5223.     pop    dx
  5224. setpos12:pop    si
  5225.     pop    ax
  5226. setpos8:sub    dl,ah            ; virtual - horz scrolled column
  5227.  
  5228. setpos9:call    setpcur            ; set physical cursor
  5229.     clc                ; set status for ok to show
  5230. setposx:pop    cx
  5231.     mov    crt_cols,cl
  5232.     pop    dx
  5233.     pop    cx
  5234.     pop    bx
  5235.     pop    ax
  5236.     ret
  5237. setpos    endp
  5238.  
  5239. ; Read physical cursor position
  5240. ; DL = column, DH = row, both counted from 0,0 at upper left corner
  5241. ; CX = cursor lines
  5242. getpcur    proc    near
  5243.     push    ax
  5244.     push    bx
  5245.     mov    ah,3            ; get cursor position
  5246.     xor    bh,bh            ; page 0
  5247.     int    screen
  5248.     pop    bx
  5249.     pop    ax
  5250.     ret
  5251. getpcur    endp
  5252.  
  5253. fgetpcur proc    far
  5254.     call    getpcur
  5255.     ret
  5256. fgetpcur endp
  5257.  
  5258. ; Set physical cursor postion
  5259. ; DL = column, DH = row, both counted from 0,0 at upper left corner
  5260. setpcur    proc    near
  5261.     push    dx
  5262.     cmp    dl,crt_cols        ; out of bounds?
  5263.     jb    setpcur1        ; b = ok
  5264.     mov    dl,crt_cols        ; physical cols on screen
  5265.     dec    dl            ; count from zero
  5266. setpcur1:cmp    inemulator,0        ; emulating?
  5267.     je    setpcur4        ; e = no, no virtual screen
  5268.     cmp    tekflg,tek_active+tek_sg ; special graphics mode?
  5269.     jne    setpcur4        ; ne = no
  5270.     push    ax
  5271.     push    es
  5272.     mov    ax,40h
  5273.     mov    es,ax
  5274.     mov    ax,es:[50h]        ; current position
  5275.     mov    es:[50h],dx        ; text page 0 cursor, keep it tracking
  5276.     cmp    ax,dx            ; same?
  5277.     pop    es
  5278.     pop    ax
  5279.     jne    setpcur2        ; not same, draw cursor
  5280.     cmp    cursorst,0        ; is cursor off now?
  5281.     jne    setpcur3        ; ne = no, skip redrawing
  5282. setpcur2:mov    dosetcursor,dx        ; reminder of where to set cursor
  5283.     call    tekremcursor        ; ensure it's off
  5284. setpcur3:pop    dx
  5285.     ret
  5286.  
  5287. setpcur4:push    ax
  5288.     push    es
  5289.     mov    ax,40h
  5290.     mov    es,ax
  5291.     mov    ax,es:[50h]        ; current position
  5292.     cmp    ax,dx            ; same?
  5293.     pop    es
  5294.     jne    setpcur5        ; ne = no
  5295.     pop    ax
  5296.     pop    dx
  5297.     ret
  5298. setpcur5:push    bx
  5299.     mov    ah,2            ; set cursor
  5300.     xor    bh,bh            ; page 0
  5301.     int    screen
  5302.     pop    bx
  5303.     pop    ax
  5304.     pop    dx
  5305.     ret
  5306. setpcur    endp
  5307.  
  5308. ; Read char and attributes under physical cursor.
  5309. ; Returns AL = character, AH = video attributes
  5310. getpcha    proc    near
  5311.     push    bx
  5312.     mov    ah,8            ; read char and attributes
  5313.     xor    bh,bh            ; page 0
  5314.     int    screen            ; Bios video call
  5315.     pop    bx
  5316.     ret
  5317. getpcha    endp
  5318.  
  5319. ; Write char and attribute to screen at cursor position, do not move cursor.
  5320. ; AL = char, AH = video attribute, DL = column, DH = row, CL = logical 
  5321. ; attribute bits. Does not update physical screen.
  5322. qsetatch proc    near
  5323.     mov    setnoshow,1        ; turn off physical screen update
  5324.     jmp    setatch            ; call with same args
  5325. qsetatch endp
  5326.  
  5327. ; Write char and attribute to screen at cursor position, do not move cursor.
  5328. ; AL = char, AH = video attribute, DL = column, DH = row, CL = logical 
  5329. ; attribute bits. Turns off setnoshow at the end.
  5330.  
  5331. setatch    proc    near
  5332.     push    bx
  5333.     push    es
  5334.     push    cx            ; save logical attribute
  5335.     push    ax            ; save char and attribute
  5336.     cmp    setnoshow,0        ; show on real screen?
  5337.     jne    setatc1            ; ne = no, do just virtual screen
  5338.     call    setpos            ; set cursor at dx location
  5339.     jc    setatc1            ; c = do not show character
  5340.     cmp    inemulator,0        ; emulating a terminal now?
  5341.     je    setatc4            ; e = no
  5342.     cmp    tekflg,tek_active+tek_sg ; special graphics mode?
  5343.     jne    setatc4            ; ne = no, text mode
  5344.     push    dx
  5345.     push    si
  5346.     push    di
  5347.     mov    bl,dh            ; get row
  5348.     xor    bh,bh
  5349.     sub    dl,linescroll[bx]     ; deduct horizontal scroll
  5350.     call    ttxtchr            ; display char in graphics mode
  5351.     pop    di
  5352.     pop    si
  5353.     pop    dx
  5354.     jmp    short setatc1
  5355. setatc4:
  5356.     mov    cx,1            ; one char
  5357.     mov    bl,ah            ; attribute
  5358.     xor    bh,bh            ; page 0
  5359.     mov    ah,9            ; write char, do not move cursor
  5360.     int    screen
  5361. setatc1:mov    setnoshow,0        ; always reset this automatically
  5362.                     ; write same material to vscreen
  5363.     mov    al,vswidth        ; width of vscreen line
  5364.     mul    dh            ; count across rows (0..)
  5365.     xor    bh,bh
  5366.     mov    bl,dl            ; get position
  5367.     add    bx,ax            ; add column
  5368.     add    bx,bx            ; times two for char and attrib
  5369.     pop    ax            ; recover char and attribute
  5370.     pop    cx            ; recover logical attribute
  5371.     cmp    inemulator,0        ; in terminal emulator?
  5372.     je    setatc2            ; e = no, so no virtual screen
  5373.     push    di
  5374.     les    di,vs_ptr        ; virtual screen
  5375.     mov    es:[di+bx],ax        ; store char and attribute
  5376.     push    ax            ; save ah attributes
  5377.     mov    al,((vswidth+1)/2)*2    ; char cells/line for attributes
  5378.     mul    dh            ; times rows
  5379.     add    al,dl            ; add column
  5380.     adc    ah,0
  5381.     shr    ax,1            ; two attributes per byte
  5382.     mov    bx,ax
  5383.     les    di,vsat_ptr        ; attributes nibble array
  5384.     mov    al,es:[bx+di]        ; get two nibbles
  5385.     mov    ah,cl            ; save extended attribute nibble
  5386.     xor    cl,cl            ; shift amount, assume zero
  5387.     test    dl,1            ; is this an odd column?
  5388.     jz    setatc3            ; z = no
  5389.     mov    cl,4            ; use only four lowest order bits
  5390. setatc3:ror    al,cl            ; bring pair to low order
  5391.     and    al,not 0fh        ; remove old
  5392.     and    ah,0fh            ; just the new
  5393.     or    al,ah            ; put new in place
  5394.     rol    al,cl            ; rotate back
  5395.     mov    es:[bx+di],al        ; store again
  5396.     pop    ax
  5397.     pop    di
  5398. setatc2:pop    es
  5399.     pop    bx
  5400.     ret
  5401. setatch    endp
  5402.  
  5403. ; Get bold video attribute bit
  5404. ; Returns AH = bold attribute bit (0 if not bold)
  5405. getbold    proc    near
  5406.     and    ah,att_bold
  5407.     test    flags.vtflg,ttd463+ttd470 ; D463/D470?
  5408.     jnz    getbold1        ; nz = yes
  5409.     xor    ah,userbold        ; invert with user bold
  5410. getbold1:ret
  5411. getbold endp
  5412.  
  5413. ; Set bold video attribute bit, current video attribute supplied in AH
  5414. setbold proc    near
  5415.     or    ah,att_bold
  5416.     test    flags.vtflg,ttd463+ttd470 ; D463/D470?
  5417.     jnz    setbold1        ; nz = yes
  5418.     xor    ah,userbold        ; invert with user bold
  5419. setbold1:ret
  5420. setbold endp
  5421.  
  5422. ; Clear bold video attribute bit, current video attribute supplied in AH
  5423. clrbold    proc    near
  5424.     and    ah,not att_bold
  5425.     test    flags.vtflg,ttd463+ttd470 ; D463/D470?
  5426.     jnz    clrbold1        ; nz = yes
  5427.     or    ah,userbold        ; invert with user bold
  5428. clrbold1:ret
  5429. clrbold    endp
  5430.  
  5431. ; Get blink video attribute bit
  5432. ; Returns AH = blink attribute bit
  5433. getblink proc    near
  5434.     and    ah,att_blink
  5435.     ret
  5436. getblink endp
  5437.  
  5438. ; Set blink video attribute bit, current video attribute supplied in AH
  5439. setblink proc    near
  5440.     or    ah,att_blink
  5441.     ret
  5442. setblink endp
  5443.  
  5444. ; Clear blink video attribute bit, current video attribute supplied in AH
  5445. clrblink proc    near
  5446.     and    ah,not att_blink
  5447.     ret
  5448. clrblink endp
  5449.  
  5450. ; Set extended attribute for protection in extattr and in CL.
  5451. setprot    proc    near            ; set protected mode
  5452.     or    extattr,att_protect
  5453.     or    cl,att_protect        ; and in cl
  5454.     ret
  5455. setprot    endp
  5456.  
  5457. ; Clear extended attribute for protection in extattr and in CL.
  5458. clrprot    proc    near            ; clear protected mode
  5459.     and    extattr,not att_protect
  5460.     and    cl,not att_protect
  5461.     ret
  5462. clrprot endp
  5463.  
  5464. ; Get underline video attribute bit from extattr
  5465. ; Returns CL = underline attribute bit
  5466. getunder proc    near
  5467.     mov    cl,extattr        ; get extended attribute
  5468.     and    cl,att_uline        ; return underline status bit
  5469.     ret
  5470. getunder endp
  5471.  
  5472. ; Set underline video attribute bit, current video attribute supplied in AH
  5473. ; and extended attributes in extattr. Returns new AH and extattr in CL.
  5474. setunder proc    near
  5475.     test    extattr,att_uline    ; extended attributes, on already?
  5476.     jz    setund1            ; z = no
  5477.     ret                ; else do nothing
  5478. setund1:or    extattr,att_uline    ; set underline attribute for MSZ
  5479.     or    cl,att_uline
  5480.     cmp    crt_mode,7        ; monochrome display adapter mode?
  5481.     je    setund6            ; e = yes, otherwise xor video
  5482.     push    bx
  5483.     push    dx
  5484.     mov    bh,al            ; preserve possible char in al
  5485.     mov    dl,scbattr        ; screen fill
  5486.     and    dl,70h            ; background colors
  5487.     mov    bl,extattr        ; extended attributes
  5488.     and    bl,att_rev        ; per char reversed video
  5489.     mov    dh,ah            ; current character attributes
  5490.     and    dh,not 77h        ; blink/bold attributes only
  5491.     and    ah,77h            ; colors only
  5492.     mov    al,ah
  5493.     shr    al,1
  5494.     shr    al,1
  5495.     shr    al,1
  5496.     shr    al,1            ; background to lower nibble
  5497.     and    ah,7            ; foreground only
  5498.     or    bl,bl            ; reversed video attribute?
  5499.     jz    setund3            ; z = no, normal
  5500.     xchg    ah,al            ; real background color to al
  5501. setund3:xor    al,ah            ; modify background
  5502.     or    dl,dl            ; case of black background?
  5503.     jnz    setund4            ; nz = no
  5504.     mov    al,ah
  5505.     dec    al
  5506.     and    al,7            ; background goes to (foreground-1)/8
  5507.     or    al,al            ; still black?
  5508.     jnz    setund4            ; nz = no
  5509.     mov    al,7            ; force non-black (white foreground)
  5510. setund4:shl    al,1            ; background to high nibble
  5511.     shl    al,1
  5512.     shl    al,1
  5513.     shl    al,1
  5514.     or    ah,al            ; or new background
  5515.     or    bl,bl            ; per char reversal?
  5516.     jz    setund5            ; z = no
  5517.     rol    ah,1            ; yes, flip fore/background again
  5518.     rol    ah,1
  5519.     rol    ah,1
  5520.     rol    ah,1
  5521. setund5:or    ah,dh            ; restore blink and bold
  5522.     pop    dx
  5523.     mov    al,bh            ; restore possible char
  5524.     pop    bx
  5525.     ret
  5526. setund6:call    brkatt            ; break apart attributes
  5527.     or    al,att_uline        ; set underline bit
  5528.     call    addatt            ; reassemble attributes into ah
  5529.     ret
  5530. setunder endp
  5531.  
  5532. ; Clear underline video attribute bit, current video attribute supplied in AH
  5533. ; and extended attributes in extattr. Returns new AH and extattr in CL.
  5534. clrunder proc    near
  5535.     test    extattr,att_uline    ; extended attributes, off already?
  5536.     jnz    clrund1            ; nz = no
  5537.     ret                ; else do nothing
  5538. clrund1:and    extattr,not att_uline    ; clear underline attribute for MSZ
  5539.     and    cl,not att_uline
  5540.     cmp    crt_mode,7        ; monochrome display adapter mode?
  5541.     je    clrund6            ; e = yes, otherwise reverse video
  5542.     push    bx
  5543.     push    dx
  5544.     mov    bh,al            ; save possible char in al
  5545.     xor    bl,bl
  5546.     mov    dl,scbattr        ; screen fill
  5547.     and    dl,70h            ; background colors
  5548.     mov    bl,extattr        ; extended attributes
  5549.     and    bl,att_rev        ; per char reversed video
  5550.     mov    dh,ah            ; current char attributes
  5551.     and    dh,not 77h        ; blink/bold attributes only
  5552.     and    ah,77h            ; colors only
  5553.     mov    al,ah
  5554.     shr    al,1
  5555.     shr    al,1
  5556.     shr    al,1
  5557.     shr    al,1            ; background to lower nibble
  5558.     and    ah,7            ; foreground only
  5559.     or    bl,bl            ; reversed video attribute?
  5560.     jz    clrund3            ; z = no, normal
  5561.     xchg    ah,al            ; real background color to al
  5562. clrund3:or    dl,dl            ; case of black background?
  5563.     jz    clrund4            ; z = yes, leave it black (empty)
  5564.     xor    al,ah
  5565.     shl    al,1            ; background to high nibble
  5566.     shl    al,1
  5567.     shl    al,1
  5568.     shl    al,1
  5569.     or    ah,al            ; or in new background
  5570. clrund4:or    bl,bl            ; per char reversal?
  5571.     jz    clrund5            ; z = no
  5572.     rol    ah,1            ; yes, reverse nibbles again
  5573.     rol    ah,1
  5574.     rol    ah,1
  5575.     rol    ah,1
  5576. clrund5:or    ah,dh            ; restore blink and bold
  5577.     pop    dx
  5578.     mov    al,bh            ; restore possible char
  5579.     pop    bx
  5580.     ret    
  5581. clrund6:call    brkatt            ; break apart attributes
  5582.     and    al,not att_uline    ; turn off underline bit
  5583.     call    addatt            ; reassemble attributes
  5584.     ret
  5585. clrunder endp
  5586.  
  5587. ; Compute reversed video attributes, given displayables in AH and extended
  5588. ; in extattr. Returns new attribute in AH and CL holding new extattr
  5589. setrev    proc    near
  5590.     test    extattr,att_rev        ; reversed now?
  5591.     jnz    setrev1            ; nz = yes
  5592.     call    revideo            ; do reversal
  5593.     or    extattr,att_rev        ; update extended attribute
  5594.     or    cl,att_rev
  5595. setrev1:ret
  5596. setrev    endp
  5597.  
  5598. ; Compute un-reversed video attributes, given displayables in AH and extended
  5599. ; in extattr. Returns new attribute in AH and CL holding new extattr
  5600. clrrev    proc    near
  5601.     test    extattr,att_rev        ; reversed now?
  5602.     jz    clrrev1            ; z = no
  5603.     call    revideo            ; do reversal
  5604.     and    extattr,not att_rev    ; update extended attribute
  5605.     and    cl,not att_rev        ; update extended attribute
  5606. clrrev1:ret
  5607. clrrev    endp
  5608.  
  5609.  
  5610. ; Compute reversed video attribute byte. Normally preserves blink/bold.
  5611. ; Enter with AH = video attribute byte, returns new attribute byte in AH.
  5612. revideo    proc    near
  5613.     call    brkatt            ; separate colors from blink/bold
  5614.     rol    ah,1            ; reverse foreground & background
  5615.     rol    ah,1            ; RGB bits
  5616.     rol    ah,1
  5617.     rol    ah,1
  5618.     call    addatt            ; reinsert bold/blink bits
  5619.     ret
  5620. revideo    endp
  5621.  
  5622. ; This routine picks an attribute apart into its component "parts" - the
  5623. ; base attribute for the screen and the "extras" - i.e., blink, intensity
  5624. ; and underline.
  5625. ; enter with    ah = a cursor attribute
  5626. ; return    ah = base attribute for screen (07H normal, 70H reverse).
  5627. ;        al = "extra" attributes
  5628. ; Note that there is a complementary routine, addatt, for putting attributes
  5629. ; back together.
  5630.  
  5631. brkatt:    mov    al,ah            ; copy displayables
  5632.     and    al,(att_blink+att_bold)    ; get modifiers
  5633.     and    ah,not (att_bold+att_blink) ; strip blink/bold, leave color
  5634.     cmp    crt_mode,7        ; monochrome display adapter mode?
  5635.     jne    brkat2            ; ne = no, cut this short for color
  5636.     test    ah,att_low_mask        ; are any of these on?
  5637.     jnz    brkat1            ; nz = yes, can't be underline
  5638.     test    ah,att_underline    ; underline?
  5639.     jz    brkat2            ; z = no, some kind of reverse video
  5640.     or    al,att_underline    ; say underline
  5641.     test    ah,70h             ; reverse video + underline?
  5642.     jz    brkat1            ; z = no, fix up low nibble
  5643.     and    ah,not 07h        ; clear the underline bit in ah
  5644.     ret
  5645. brkat1: or    ah,att_normal        ; normal, turn on all normal bits
  5646. brkat2:    ret
  5647.  
  5648. ; This routine builds a cursor attribute given the base attribute for the
  5649. ; screen background and the "extra" attributes we want (blink, etc.).
  5650. ; enter with    ah = base attribute for background (07H or 70H)
  5651. ;        al = "extra" attributes (89H for all three)
  5652. ; return    ah = base combined with "extras".
  5653.  
  5654. addatt: test    al,att_underline    ; want underline?
  5655.     jz    addat1            ; z = no, no need for hack
  5656.     cmp    crt_mode,7        ; monochrome display adapter mode?
  5657.     jne    addat1            ; ne = no, cut this short for color
  5658.     and    ah,not att_low_mask    ; clear background colors
  5659. addat1: or    ah,al            ; Or in the attributes
  5660.     ret
  5661.  
  5662.  
  5663. ; This routine is called when we want to reverse everything on the screen
  5664. ; from normal to reverse video, or vice versa.    It is called only when
  5665. ; the decscnm attribute is changed.
  5666. ; Call:    no arguments.
  5667.  
  5668. revscn    proc    near
  5669.     push    ax
  5670.     push    bx
  5671.     push    cx
  5672.     push    dx
  5673.     mov    dh,byte ptr low_rgt+1    ; compute last screen offset in ax
  5674.     inc    dh            ; one more row to catch mode line
  5675.     mov    dl,vswidth        ; logical screen buffer
  5676.     dec    dl            ; and we count from 0
  5677.     call    scrloc            ; get screen offset into ax
  5678.     mov    cx,ax            ; save it in cx for a minute
  5679.     add    cx,2
  5680.     sar    cx,1            ; in 16-bit words please
  5681.     push    di            ; Save some more acs
  5682.     push    es
  5683.     les    di,vs_ptr        ; seg and offset of vscreen
  5684.     cld
  5685. revsc1:    mov    ax,es:[di]        ; fetch a word
  5686.     mov    bl,al            ; save the character
  5687.     call    revideo            ; get reversed video attributes (AH)
  5688.     call    addatt            ; put attributes back together
  5689.     mov    al,bl            ; restore character
  5690.     stosw                ; stuff into screen memory
  5691.     loop    revsc1            ; loop for entire screen
  5692.     pop    es            ; restore segment register
  5693.     pop    di            ; and destination index
  5694.     pop    dx
  5695.     pop    cx
  5696.     pop    bx
  5697.     call    repaint
  5698.     pop    ax
  5699.     ret
  5700. revscn    endp
  5701.  
  5702. ; Set coloring attributes.
  5703. ; Enter with AH holding current video attribute byte,
  5704. ; BL holding ANSI color code (30-37 or 40-47) where 30's are foreground,
  5705. ; 40's are background. ANSI colors are 1 = red, 2 = green, 4 = blue.
  5706. ; Return new attribute byte in AH.
  5707.  
  5708. setcolor proc    near
  5709.     test    extattr,att_rev        ; normal video currently?
  5710.     jz    setcol0            ; z = yes
  5711.     mov    al,ah            ; make a copy
  5712.     and    ax,7788h        ; strip bold,blink, keep both in al
  5713.     rol    ah,1            ; get colors in right parts
  5714.     rol    ah,1            ;  of ah = back, al = foreground
  5715.     rol    ah,1
  5716.     rol    ah,1
  5717.     call    setcol0            ; set fore or background color
  5718.     rol    ah,1            ; reverse coloring again
  5719.     rol    ah,1
  5720.     rol    ah,1
  5721.     rol    ah,1
  5722.     or    ah,al            ; put back blink and bold
  5723.     ret
  5724.  
  5725. setcol0:cmp    bl,30            ; ANSI color series?
  5726.     jb    setcol7            ; b = no
  5727.     cmp    bl,37            ; foreground set (30-37)?
  5728.     ja    setcol4            ; a = no, try background set
  5729.     sub    bl,30            ; take away the bias
  5730.     and    ah,not 07H        ; clear foreground bits
  5731.     test    bl,1            ; ANSI red?
  5732.     jz    setcol1            ; z = no
  5733.     or    ah,4            ; IBM red foreground bit
  5734. setcol1:test    bl,2            ; ANSI & IBM green?
  5735.     jz    setcol2            ; z = no
  5736.     or    ah,2            ; IBM green foreground bit
  5737. setcol2:test    bl,4            ; ANSI blue?
  5738.     jz    setcol3            ; z = no
  5739.     or    ah,1            ; IBM blue foreground bit
  5740. setcol3:ret
  5741.  
  5742. setcol4:cmp    bl,40            ; background color set?
  5743.     jb    setcol7            ; b = no
  5744.     cmp    bl,47            ; background set is 40-47
  5745.     ja    setcol7            ; nb = no, not a color command
  5746.     sub    bl,40            ; take away the bias
  5747.     and    ah,not 70H        ; clear background bits
  5748.     test    bl,1            ; ANSI red?
  5749.     jz    setcol5            ; z = no
  5750.     or    ah,40h            ; IBM red background bit
  5751. setcol5:test    bl,2            ; ANSI & IBM green?
  5752.     jz    setcol6            ; z = no
  5753.     or    ah,20h            ; IBM green background bit
  5754. setcol6:test    bl,4            ; ANSI blue?
  5755.     jz    setcol7            ; z = no
  5756.     or    ah,10h            ; IBM blue background bit
  5757. setcol7:ret
  5758. setcolor endp
  5759.  
  5760. ; Save terminal emulator, session is in BX.
  5761. ; Delete older save buffer for this session, so that compressed vscreen
  5762. ; can be saved properly.
  5763. termswapout proc far
  5764.     cmp    bx,6            ; legal session number?
  5765.     jb    termso0            ; b = yes
  5766.     stc
  5767.     ret
  5768. termso0:push    ax
  5769.     push    bx
  5770.     push    cx
  5771.     push    si
  5772.     push    di
  5773.     shl    bx,1            ; to words
  5774.     mov    temp,bx            ; save session ident
  5775.     cmp    tsave[bx],0        ; have a storage buffer?
  5776.     je    termso9            ; ne = no, create one now
  5777.     shr    bx,1            ; get original BL session indicator
  5778.     call    termswapdel        ; delete old save area
  5779.     shl    bx,1            ; restore word indexing
  5780. termso9:call    getvssize        ; get size of vscreen, compressed
  5781.     mov    ax,bx            ; save bx
  5782.     call    getvasize        ; size of attributes
  5783.     add    bx,ax
  5784.     add    bx,savexlen        ; plus length of MSX save area
  5785.     add    bx,saveylen        ; plus MSY save area
  5786.     add    bx,savezlen        ; plus MSZ area
  5787.     add    bx,saveplen        ; plus parser in MSSCMD
  5788.     add    bx,saveulen        ; plus MSU area
  5789.     add    bx,saveglen        ; plus MSG area
  5790.     add    bx,15            ; round up
  5791.     mov    cl,4
  5792.     shr    bx,cl            ; convert to paragraphs
  5793.     mov    cx,bx            ; save request in cx
  5794.     mov    ah,alloc        ; please, more space
  5795.     int    dos            ; paragraph to ax, num paras to bx
  5796.     cmp    bx,cx            ; given vs wanted
  5797.     jae    termso1            ; ae = got it
  5798.     pop    di
  5799.     pop    si
  5800.     pop    cx
  5801.     pop    bx
  5802.     pop    ax
  5803.     stc                ; fail
  5804.     ret
  5805. termso1:
  5806.     push    temp
  5807.     push    ax
  5808.     call    tekend            ; exit graphics mode
  5809.     pop    ax
  5810.     pop    temp
  5811.     mov    bx,temp            ; get session number (sescur)
  5812.     mov    tsave[bx],ax        ; save starting paragraph
  5813.     push    es
  5814.     mov    cx,ds
  5815.     mov    es,cx
  5816.     mov    cx,size flginfo        ; length of saved flags array
  5817.     mov    di,offset saveflag    ; saved array
  5818.     mov    si,offset flags        ; working array
  5819.     rep    movsb            ; restore
  5820.     mov    ax,tsave[bx]        ; starting paragraph for save area
  5821.     mov    es,ax            ; save area is destination
  5822.     xor    di,di            ; offset of save area
  5823.  
  5824. ; virtual screen is saved as structure
  5825. ; scr-len    dw    text screen length (typically 24 lines)
  5826. ; with the items below repeated for each line (scr-len total lines)
  5827. ; per-line    dw    saved chars on this line
  5828. ;        dw    per-line dup (char & attribute)
  5829. ; with the last saved char on each line being repeated to endofline on screen
  5830.     push    bx            ; virtual screen saving
  5831.     mov    cl,byte ptr low_rgt+1    ; number of text lines - 1
  5832.     inc    cl
  5833.     cmp    flags.modflg,2        ; is mode line owned by host?
  5834.     jne    termso3a        ; ne = no
  5835.     inc    cl            ; yes, add it to the save material
  5836. termso3a:xor    ch,ch
  5837.     mov    ax,cx
  5838.     cld
  5839.     stosw                ; store screen length as first word
  5840.     xor    bx,bx            ; line counter
  5841.     mov    si,word ptr vs_ptr    ; offset of vscreen
  5842. termso3:push    cx            ; save line loop counter
  5843.     mov    cx,word ptr rdbuf[bx]    ; get number of saveable chars on line
  5844.     mov    ax,cx            ; store char count as first word
  5845.     stosw
  5846.     mov    ax,word ptr vs_ptr+2    ; get vscreen segment
  5847.     push    si
  5848.     push    ds
  5849.     mov    ds,ax
  5850.     rep    movsw            ; copy saveable chars
  5851.     pop    ds
  5852.     pop    si
  5853.     pop    cx            ; recover line counter
  5854.     add    bx,2            ; next line, get length info
  5855.     add    si,vswidth*2        ; next line, offset of vscreen line
  5856.     loop    termso3
  5857.     pop    bx            ; end of vscreen saving
  5858.                     ;
  5859.     push    bx            ; virtual screen saving
  5860.     mov    cl,byte ptr low_rgt+1    ; number of text lines - 1
  5861.     inc    cl
  5862.     cmp    flags.modflg,2        ; is mode line owned by host?
  5863.     jne    termso3b        ; ne = no
  5864.     inc    cl            ; yes, add it to the save material
  5865. termso3b:xor    ch,ch
  5866.     mov    ax,cx
  5867.     cld
  5868.     stosw                ; store screen length as first word
  5869.     xor    bx,bx            ; line counter
  5870.     mov    si,word ptr vsat_ptr    ; offset of vsattr
  5871. termso7:push    cx            ; save line loop counter
  5872.     mov    cx,word ptr rdbuf[bx+120]; get num of saveable bytes on line
  5873.     mov    ax,cx            ; store char count as first word
  5874.     stosw
  5875.     mov    ax,word ptr vsat_ptr+2    ; get vsattr segment
  5876.     push    si
  5877.     push    ds
  5878.     mov    ds,ax
  5879.     shr    cx,1            ; get odd byte count info
  5880.     jnc    termso7a        ; nc = even count
  5881.     movsb
  5882. termso7a:rep    movsw            ; copy saveable bytes
  5883.     pop    ds
  5884.     pop    si
  5885.     pop    cx            ; recover line counter
  5886.     add    bx,2            ; next line, get length info
  5887.     add    si,(vswidth+1)/2    ; next line, offset of vsattr line
  5888.     loop    termso7
  5889.     pop    bx            ; end of vsattr saving
  5890.                     ;
  5891.     mov    si,offset saveyoff    ; offset of MSY save area
  5892.     mov    cx,saveylen        ; length of MSY save area
  5893.     cld
  5894.     shr    cx,1            ; even/odd?
  5895.     jnc    termso4            ; nc = even
  5896.     movsb                ; the odd byte
  5897. termso4:rep    movsw
  5898.     mov    si,offset savezoff    ; offset of MSZ save area
  5899.     mov    cx,savezlen        ; length of MSZ save area
  5900.     shr    cx,1
  5901.     jnc    termso5
  5902.     movsb
  5903. termso5:rep    movsw
  5904.     mov    si,offset savexoff    ; offset of MSX save area
  5905.     mov    cx,savexlen        ; length of MSX save area
  5906.     cld
  5907.     cli                ; cautious about serial ints
  5908.     shr    cx,1            ; even/odd?
  5909.     jnc    termso6            ; nc = even
  5910.     movsb                ; the odd byte
  5911. termso6:rep    movsw
  5912.     sti
  5913.     mov    si,offset savepoff    ; offset of MSSCMD parser save area
  5914.     mov    cx,saveplen        ; length of the area
  5915.     shr    cx,1
  5916.     jnc    termso6a
  5917.     movsb
  5918. termso6a:rep    movsw
  5919.     mov    si,offset saveuoff    ; offset of MSUIBM kbd save area
  5920.     mov    cx,saveulen        ; length of the area
  5921.     shr    cx,1
  5922.     jnc    termso6b
  5923.     movsb
  5924. termso6b:rep    movsw
  5925.     mov    si,offset savegoff    ; offset of MSG save area
  5926.     mov    cx,saveglen        ; length of MSG save area
  5927.     shr    cx,1            ; graphics mode exited above
  5928.     jnc    termso6c
  5929.     movsb
  5930. termso6c:rep    movsw
  5931.     pop    es
  5932.     mov    ax,100h            ; assume using 80 col screen
  5933.     cmp    dos_cols,80        ; startup screen width
  5934.     jbe    termso8            ; be = assume 80 columns
  5935.     inc    al            ; say do 132 columns
  5936. termso8:push    vtemu.vtflgop
  5937.     or    vtemu.vtflgop,vscompress ; turn off compressed mode
  5938.     call    chgdsp            ; reset display width to startup
  5939.     pop    vtemu.vtflgop
  5940.     pop    di
  5941.     pop    si
  5942.     pop    cx
  5943.     pop    bx
  5944.     pop    ax
  5945.     clc
  5946.     ret
  5947. termswapout endp
  5948.  
  5949. ; Restore terminal emulator, session is BX
  5950. ; Delete save buffer after restoration.
  5951. termswapin proc    far
  5952.     cmp    bx,6            ; valid session?
  5953.     jb    termsi0            ; b = yes
  5954.     stc
  5955.     ret
  5956. termsi0:push    bx
  5957.     shl    bx,1            ; to words
  5958.     cmp    tsave[bx],0        ; have a storage buffer?
  5959.     pop    bx
  5960.     jne    termsi1            ; ne = yes, use it
  5961.     mov    vtinited,0        ; say not inited
  5962.     stc                ; fail
  5963.     ret
  5964.  
  5965. termsi1:push    ax
  5966.     push    bx
  5967.     push    cx
  5968.     push    si
  5969.     push    di
  5970.     push    es            ; virtual screen restore
  5971.     test    tekflg,tek_active    ; current graphics mode status
  5972.     jz    tswapin1a        ; z = not in graphics mode
  5973.     push    bx
  5974.     call    tekend
  5975.     pop    bx
  5976. tswapin1a:
  5977.     les    di,vs_ptr        ; seg and offset of vscreen
  5978.     shl    bx,1            ; to words
  5979.     mov    ax,tsave[bx]        ; starting paragraph of save area
  5980.     push    ds
  5981.     mov    ds,ax            ; source segment is save area
  5982.     xor    si,si            ; source offset is always zero
  5983.     cld
  5984.     lodsw                ; get screen length
  5985.     mov    cx,ax            ; counter of vscreen lines to do
  5986. tswapi2:push    cx            ; save line counter
  5987.     lodsw                ; get count of saved chars of line
  5988.     dec    ax            ; omit repeated char til next step
  5989.     mov    cx,ax            ; count for saved char writes
  5990.     rep    movsw            ; copy saved chars except last one
  5991.     mov    cx,vswidth        ; total line width (chars)
  5992.     sub    cx,ax            ; minus those done
  5993.     lodsw                ; get last char (this repeats to end)
  5994.     rep    stosw            ; repeat last char
  5995.     pop    cx            ; recover line counter
  5996.     loop    tswapi2            ; do all text lines (omit status)
  5997.     pop    ds            ; restore DS, SI is ready for nxt grp
  5998.                     ; end of virtual screen restoration
  5999.                     ; attributes, vsatt, for vscreen
  6000.     les    di,vsat_ptr        ; seg and offset of vsatt
  6001.     mov    ax,tsave[bx]        ; starting paragraph of save area
  6002.     push    ds
  6003.     mov    ds,ax            ; source segment is save area
  6004.     lodsw                ; get screen length
  6005.     mov    cx,ax            ; counter of vsattr lines to do
  6006. tswapi7:push    cx            ; save line counter
  6007.     lodsw                ; get count of saved bytes of line
  6008.     dec    ax            ; omit repeated byte til next step
  6009.     mov    cx,ax            ; count for saved byte writes
  6010.     shr    cx,1            ; do odd byte copy
  6011.     jnc    tswapi7a        ; nc = even count
  6012.     movsb
  6013. tswapi7a:rep    movsw            ; copy saved bytes except last one
  6014.     mov    cx,(vswidth+1)/2    ; total line width (bytes)
  6015.     sub    cx,ax            ; minus those done
  6016.     lodsb                ; get last byte (this repeats to end)
  6017.     rep    stosb            ; repeat last byte
  6018.     pop    cx            ; recover line counter
  6019.     loop    tswapi7            ; do all text lines (omit status)
  6020.     pop    ds            ; restore DS, SI is ready for nxt grp
  6021.                     ; end of virtual screen restoration
  6022.  
  6023.     mov    ax,ds            ; regular data seg "data"
  6024.     mov    es,ax            ; new data seg
  6025.     mov    di,offset saveyoff    ; offset of MSY save area
  6026.     mov    cx,saveylen        ; length of MSY save area
  6027.     mov    ax,tsave[bx]        ; starting paragraph of save area
  6028.     push    ds
  6029.     mov    ds,ax            ; source segment is save area
  6030.     cld
  6031.     shr    cx,1            ; even/odd?
  6032.     jnc    termsi3            ; nc = even
  6033.     movsb                ; the odd byte
  6034. termsi3:rep    movsw
  6035.     mov    di,offset savezoff    ; offset of MSZ save area
  6036.     mov    cx,es:savezlen        ; length of MSZ save area
  6037.     shr    cx,1
  6038.     jnc    termsi4
  6039.     movsb
  6040. termsi4:rep    movsw
  6041.     mov    di,offset savexoff    ; offset of MSX save area
  6042.     mov    cx,es:savexlen        ; length of MSX save area
  6043.     cli                ; cautious about serial ints
  6044.     shr    cx,1
  6045.     jnc    termsi5
  6046.     movsb
  6047. termsi5:rep    movsw
  6048.     sti
  6049.     mov    di,offset savepoff    ; offset of MSSCMD parser area
  6050.     mov    cx,es:saveplen        ; length
  6051.     shr    cx,1
  6052.     jnc    termsi6
  6053.     movsb
  6054. termsi6:rep    movsw
  6055.     mov    di,offset saveuoff    ; offset of MSUIBM kbd area
  6056.     mov    cx,es:saveulen        ; length
  6057.     shr    cx,1
  6058.     jnc    termsi6a
  6059.     movsb
  6060. termsi6a:rep    movsw
  6061.     mov    di,offset savegoff    ; offset of MSGIBM area
  6062.     mov    cx,es:saveglen        ; length
  6063.     shr    cx,1
  6064.     jnc    termsi8
  6065.     movsb
  6066. termsi8:rep    movsw
  6067.     pop    ds
  6068.     mov    cx,ds
  6069.     mov    es,cx
  6070.     mov    cx,size flginfo        ; length of saved flags array
  6071.     mov    si,offset saveflag    ; saved array
  6072.     mov    di,offset flags        ; working array
  6073.     rep    movsb            ; restore
  6074.     mov    ah,savattr        ; get saved coloring
  6075.     mov    scbattr,ah        ; replace what DOS may have used
  6076.     and    tekflg,not tek_active    ; say graphics is not active
  6077.     pop    es
  6078.     pop    di
  6079.     pop    si
  6080.     pop    cx
  6081.     pop    bx
  6082.     pop    ax
  6083.     call    termswapdel        ; delete this saved area, BL=session
  6084.     clc
  6085.     ret
  6086. termswapin endp
  6087.  
  6088. ; Remove saved terminal emulator buffers, BX is sescur (-1 means all)
  6089. termswapdel proc far
  6090.     push    ax
  6091.     push    bx
  6092.     shl    bx,1            ; to words
  6093.     xor    ax,ax            ; clearing indicator
  6094.     xchg    ax,tsave[bx]        ; paragraph of save area
  6095.     or    ax,ax            ; anything there?
  6096.     jnz    tswapd1            ; nz = yes
  6097.     pop    bx
  6098.     pop    ax
  6099.     stc                ; fail
  6100.     ret
  6101. tswapd1:push    es
  6102.     mov    es,ax            ; set paragraph to es for DOS
  6103.     mov    ah,freemem
  6104.     int    dos
  6105.     pop    es
  6106.     pop    bx
  6107.     pop    ax
  6108.     clc                ; succeed
  6109.     ret
  6110. termswapdel endp
  6111.  
  6112. ; Examine vscreen line by line. Count number of characters by excluding the
  6113. ; trailing repetitions (keep first example) on each line, sum them. Add to 
  6114. ; the sum a word per line to hold the count of such characters and one more 
  6115. ; word to hold the screen length.
  6116. ; Return the number of bytes in register bx for malloc-ing.
  6117. getvssize proc    near
  6118.     push    cx
  6119.     push    dx
  6120.     push    di
  6121.     push    es
  6122.     les    di,vs_ptr        ; pointer to vscreen
  6123.     xor    bx,bx            ; line counter
  6124.     mov    cl,crt_lins        ; lines on screen
  6125.     xor    ch,ch
  6126.     mov    dx,cx            ; accumulated count <cnt, line>
  6127.     inc    dx            ; count screen size word itself
  6128.     add    di,(vswidth - 1) * 2    ; offset of last char on the line
  6129. getvssi1:push    cx            ; save line counter
  6130.     mov    cx,vswidth-1        ; chars on line - 1
  6131.     mov    ax,es:[di]        ; get last char+attrib on the line
  6132.     push    di
  6133.     sub    di,2
  6134.     std                ; scan backward
  6135.     repe    scasw            ; scan while equal (trim trailing rpt)
  6136.     cld
  6137.     pop    di
  6138.     je    getvssi2        ; e = ended on all same char
  6139.     inc    cx            ; ne case gobbles extra char
  6140. getvssi2:inc    cx            ; count the trailing char
  6141.     mov    word ptr rdbuf[bx],cx    ; store number of words here
  6142.     add    dx,cx            ; accumulate count of chars
  6143.     add    bx,2            ; next line
  6144.     add    di,vswidth*2        ; end of next line
  6145.     pop    cx            ; line counter
  6146.     loop    getvssi1
  6147.  
  6148.     add    dx,dx            ; chars to bytes accumulated
  6149.     mov    bx,dx            ; return it in bx
  6150.     pop    es
  6151.     pop    di
  6152.     pop    dx
  6153.     pop    cx
  6154.     ret
  6155. getvssize endp
  6156.  
  6157. ; Examine vsattr line by line. Count number of attributes by excluding the
  6158. ; trailing repetitions (keep first example) on each line, sum them. Add to 
  6159. ; the sum a word per line to hold the count of such characters and one more 
  6160. ; word to hold the screen length. Stores temp length indicator in
  6161. ; words rdbuf+120 et seq (one word per line).
  6162. ; Return the number of bytes in register bx for malloc-ing.
  6163. getvasize proc    near
  6164.     push    ax
  6165.     push    cx
  6166.     push    dx
  6167.     push    di
  6168.     push    es
  6169.     les    di,vsat_ptr        ; pointer to vsattr
  6170.     xor    bx,bx            ; line counter
  6171.     mov    cl,byte ptr low_rgt+1    ; lines on normal screen - 1
  6172.     add    cl,2            ; include status line
  6173.     xor    ch,ch
  6174.     mov    dx,cx            ; accumulated count <cnt, line>
  6175.     inc    dx            ; count screen size word itself
  6176.     add    dx,dx            ; convert to bytes used
  6177.     add    di,(((vswidth+1)/2) -1) ; offset of last attrib on the line
  6178. getvasi1:push    cx            ; save line counter
  6179.     mov    cx,(((vswidth+1)/2) -1)    ; bytes on line - 1
  6180.     mov    ax,es:[di]        ; get last attribute byte on the line
  6181.     push    di
  6182.     dec    di
  6183.     std                ; scan backward
  6184.     repe    scasb            ; scan while equal (trim trailing rpt)
  6185.     cld
  6186.     pop    di
  6187.     je    getvasi2        ; e = ended on all same byte
  6188.     inc    cx            ; ne case gobbles extra byte
  6189. getvasi2:inc    cx            ; count the trailing byte
  6190.     mov    word ptr rdbuf[bx+120],cx; store number of bytes here
  6191.     add    dx,cx            ; accumulate count of bytes
  6192.     add    bx,2            ; next line
  6193.     add    di,(vswidth+1)/2    ; end of next line
  6194.     pop    cx            ; line counter
  6195.     loop    getvasi1
  6196.     mov    bx,dx            ; return bytes needed in bx
  6197.     pop    es
  6198.     pop    di
  6199.     pop    dx
  6200.     pop    cx
  6201.     pop    ax
  6202.     ret
  6203. getvasize endp
  6204.  
  6205. ;
  6206. ; CHKDSP - procedure to check for hardware support of 132 cols
  6207. ;  Supported hardware:
  6208. ;  ATI EGA and VGA Wonder
  6209. ;  AT&T
  6210. ;  Everex Viewpoint EV-659, FVGA-673, EV-678, Micro Enhancer Deluxe
  6211. ;  IBM XGA
  6212. ;  Paradise AutoSwitch EGA Mono, VGA Professional, VGA Plus, VGA Plus 16
  6213. ;  STB VGA/EM (Tseng TVGA)
  6214. ;  STB VGA/EM Plus (Tseng 4000), VGA/EM-16, VGA/EM-16 Plus
  6215. ;  Tseng Labs EVA board w/132-col kit installed
  6216. ;  Tseng Labs UltraPAK mono/Herc board w/132 column modes.
  6217. ;  Tseng Labs ET4000 SVGA.
  6218. ;  VESA compatible Bios'.
  6219. ;  Video 7 Vega Deluxe w/ 132X25.COM driver installed and VGA board.
  6220. ; The routine checks for the presence of a 132-column-capable adapter. If
  6221. ; one is found its handler executes the desired mode setting and returns
  6222. ; carry clear; it returns carry set otherwise.
  6223. ; Adding new boards - place an identification string in the data segment,
  6224. ; construct a mode setting routine and insert it in the call list below
  6225. ; (setting 132 column mode is byte AL non-zero). Byte AH is non-zero to
  6226. ; avoid saving old screen and running scrini; it is used to set the screen
  6227. ; width when starting/exiting Connect mode
  6228. ;
  6229. chgdsp    proc    near
  6230.     or    al,al            ; 80 column mode?
  6231.     jnz    chgdsg1            ; nz = no, want 132 cols
  6232.     test    tekflg,tek_active    ; graphics mode active?
  6233.     jz    chgdsp_start        ; z = no
  6234.     push    ax
  6235.     push    dx
  6236.     call    tekend            ; exit special graphics
  6237.     call    scrmod            ; update video mode info
  6238.     pop    dx
  6239.     pop    ax
  6240.     jmp    short chgdsp_start    ; set 80 col mode
  6241.  
  6242. chgdsg1:test    vtemu.vtflgop,vscompress ; allowed to use graphics for it?
  6243.     jnz    chgdsp_start        ; nz = no, use 132 column text mode
  6244.     cmp    tekflg,tek_active+tek_sg ; special graphics mode active?
  6245.     je    chgdsg3            ; e = yes, no change needed
  6246.     mov    cl,byte ptr low_rgt+1    ; examine whole screen
  6247.     add    cl,2            ; lines in emulation part + status
  6248.     xor    ch,ch
  6249.     xor    bx,bx
  6250. chgdsg2:mov    dgwindcomp[bx],1    ; set compressed mode flag non-zero
  6251.     inc    bx
  6252.     loop    chgdsg2
  6253.     call    dgsettek        ; setup special graphics mode
  6254.     mov    byte ptr low_rgt,131    ; 132 columns in special graphics
  6255.     mov    crt_cols,128        ; but 128 physical columns
  6256. chgdsg3:ret
  6257.  
  6258. chgdsp_start:
  6259.     push    es            ; save all we use
  6260.     push    ax
  6261.     push    bx
  6262.     push    cx
  6263.     push    dx
  6264.     push    si
  6265.     push    di
  6266.     mov    temp,ax            ; save set/reset flag from msz
  6267.     mov    ax,sp            ; do push sp test for XT vs AT/386
  6268.     push    sp            ; XT pushes sp-2, AT's push old sp
  6269.     pop    cx            ; recover pushed value, clean stack
  6270.     xor    ax,cx            ; same?
  6271.     jne    chgdspnw        ; ne = no, XT. Don't do Int 2fh
  6272.     test    tv_mode,10h        ; DESQview active?
  6273.     jz    chgdspndv        ; z = no
  6274.     jmp    chgdsx1            ; exit without screen change
  6275. chgdspndv:
  6276.     mov    ax,1683h        ; Windows 3, get current virt machine
  6277.     int    2fh
  6278.     cmp    ax,1683h        ; virtual machine, if any
  6279.     je    chgdspnw        ; e = no Windows, do the video mode
  6280.     jmp    chgdsx1            ; exit without screen change
  6281. chgdspnw:mov    ax,temp
  6282.     cmp    crt_cols,80        ; are we narrow?
  6283.     jbe    chgds3            ; be = narrow width now
  6284.     or    al,al            ; resetting to narrow width?
  6285.     jz    chgds4            ; z = yes, do it
  6286.     jmp    chgdsx1            ; else we are there now
  6287. chgds3:    or    al,al            ; resetting to narrow width?
  6288.     jnz    chgds4            ; nz = no, setting to wide
  6289.     jmp    chgdsx1            ; narrow width, we are there now
  6290. chgds4:    or    ah,ah            ; are we connected now?
  6291.     jnz    chgds0            ; nz = no, skip flow control etc
  6292.     mov    ah,flowoff        ; get xoff
  6293.     or    ah,ah            ; flow control?
  6294.     jz    chgds4a            ; z = none
  6295.     call    foutchr            ; send it
  6296. chgds4a:cmp    byte ptr temp+1,0    ; exiting Connect mode?
  6297.     jne    chgds0            ; ne = yes
  6298.     mov    ax,200            ; wait 200 millisec before video tests
  6299.     call    fpcwait            ; so don't mix screen and port intrpts
  6300.  
  6301. chgds0:    call    ckteva            ; try Tseng Labs EVA
  6302.     jnc    chgds1            ; nc = found
  6303.     call    ckstbv            ; try STB VEGA/EM
  6304.     jnc    chgds1            ; nc = found
  6305.     call    ckv7vd            ; try Video 7 EGA Deluxe and VGA
  6306.     jnc    chgds1            ; nc = found
  6307.     call    ckatiw            ; try ATI EGA Wonder
  6308.     jnc    chgds1            ; nc = found
  6309.     call    ckevrx                  ; try Everex Micro Enhancer Deluxe
  6310.     jnc     chgds1                  ; nc = found
  6311.     call    ckevga            ; try Everex EVGA-673
  6312.     jnc     chgds1                  ; nc = found
  6313.     call    ckatt            ; ATT boards
  6314.     jnc    chgds1            ; nc = found
  6315.     call    chkpa            ; Paradise EGA/VGA boards
  6316.     jnc    chgds1            ; nc = found
  6317.     call    chkvesa            ; VESA compatibles
  6318.     jnc    chgds1            ; nc = found
  6319.     call    ckxga            ; IBM XGA
  6320.     jnc    chgds1            ; nc = found
  6321.     mov    si,offset cols80    ; name of 80 column file
  6322.     cmp    byte ptr temp,0        ; setting 80 cols?
  6323.     je    chgdsx2            ; e = yes
  6324.     mov    si,offset cols132    ; use 132 column file
  6325. chgdsx2:mov    di,offset decbuf    ; a temp buffer for path= usage
  6326.     call    fstrcpy
  6327.     mov    ax,di            ; spath wants ptr in ax
  6328.     call    fspath
  6329.     jc    chgdsx            ; c = file not found
  6330.     mov    si,ax            ; crun wants ptr in si
  6331.     call    fcrun            ; run the batch file, si = filespec
  6332.     call    fserini            ; reengage serial port, mode changes
  6333.     mov    ax,0c06h        ; clear kbd buffer and do function
  6334.     mov    dl,0ffh            ; console input
  6335.     int    dos            ; discard character(s)
  6336.                     ; Perform mode change
  6337. chgds1:    cmp    byte ptr temp+1,0    ; do without serial port xon/xoff?
  6338.     jne    chgdsx1            ; ne = yes
  6339.     cmp    flags.modflg,1        ; is mode line enabled?
  6340.     jbe    chgdsx            ; be = yes, and off or locally owned
  6341.     mov    flags.modflg,1        ; remove foreign ownership
  6342. chgdsx:    mov    ah,flowon        ; get flow-on byte
  6343.     or    ah,ah            ; using flow control?
  6344.     jz    chgdsx1            ; z = no
  6345.     call    foutchr            ; send it
  6346. chgdsx1:call    scrmod            ; pick up current screen size
  6347.     pop    di            ; restore what we saved
  6348.     pop    si
  6349.     pop    dx
  6350.     pop    cx
  6351.     pop    bx
  6352.     pop    ax
  6353.     pop    es
  6354.     ret                ; return to caller
  6355.      
  6356. ; Individual tests for various 132-column boards
  6357.                     ; Tseng LABS EVA, UltraPAK, ET4000
  6358. ckteva: mov    ax,0c000h        ; seg addr for EVA
  6359.     mov    es,ax            ; set into es register
  6360.     mov    di,76h            ; offset of board's string
  6361.     lea    si,tsngid        ; validation string
  6362.     mov    cx,tsnglen        ; length of validiation string
  6363.     cld
  6364.     repe    cmpsb            ; compare strings
  6365.     je    ckteva2            ; e = strings match
  6366.     mov    ax,4d00h        ; check for UltraPAK mono driver
  6367.     int    screen
  6368.     cmp    ax,5aa5h        ; driver signature?
  6369.      jne    ckteva4            ; ne = no
  6370.     mov    ax,7            ; default to mono (7) for this board
  6371.     cmp    byte ptr temp,0        ; setting 132 columns?
  6372.     je    ckteva1            ; e = resetting to normal
  6373.     mov    ax,18h            ; set to 132 cols (Set Mode 18H)
  6374. ckteva1:int    screen
  6375.     clc                ; carry clear means success
  6376.     ret
  6377.                     ; an EVA board - check for 132 col kit
  6378. ckteva2:cmp    byte ptr es:099h,0    ; check 132 col kit installed
  6379.     jne    catfnd            ; ne = installed, do the mode change
  6380. ckteva3:stc                ; indicate adapter not present
  6381.     ret                ; and exit
  6382.  
  6383. ckteva4:mov    dx,03cdh        ; ET4000 test
  6384.     in    al,dx            ; Segment Select Register, get value
  6385.     push    ax
  6386.     xor    al,15h            ; create test condition
  6387.     jmp    $+2
  6388.     jmp    $+2
  6389.     out    dx,al            ; set condition
  6390.     jmp    $+2
  6391.     jmp    $+2
  6392.     mov    ah,al            ; save condition
  6393.     in    al,dx            ; get new condition
  6394.     jmp    $+2
  6395.     jmp    $+2
  6396.     cmp    ah,al            ; did it work (same)?
  6397.     pop    ax
  6398.     out    dx,al            ; restore original condition
  6399.     jne    ckteva3            ; ne = no, ET4000 not present
  6400.     mov    ax,3            ; default to cga 3
  6401.     cmp    byte ptr temp,0        ; setting 132 columns?
  6402.     je    ckteva5            ; e = resetting to normal
  6403.     mov    ax,23h            ; set to 132 cols (Set Mode 23H)
  6404. ckteva5:int    screen
  6405.     clc
  6406.     ret
  6407.                     ;
  6408. ckstbv:    mov    ax,0c000h        ; STB's VGA/EM, VGA/EM-16, EM-16 Plus
  6409.     mov    es,ax            ;
  6410.     mov    di,70h            ; where to look for signature
  6411.     lea    si,stbvid        ; the signature
  6412.     mov    cx,stbvlen        ;
  6413.     cld                ;
  6414.     repe    cmpsb            ; test
  6415.     je    catfnd            ; e = found
  6416.     mov    di,70h            ; where to look for signature
  6417.     lea    si,stavid        ; the signature
  6418.     mov    cx,stavlen
  6419.     cld
  6420.     repe    cmpsb            ; test
  6421.     je    catfnd            ; e = found
  6422.     stc                ; else say not there
  6423.     ret                ;
  6424.                     ; ATI EGA Wonder
  6425. ckatiw:    mov    ax,0c000h        ; seg addr for EGA Wonder
  6426.     mov    es,ax            ; set into es register
  6427.     mov    di,012fh        ; offset of message in ROM
  6428.     lea    si,atiwid        ; offset of message here
  6429.     mov    cx,atilen        ; length of validation string
  6430.     cld
  6431.     repe    cmpsb            ; compare strings
  6432.     je    catfnd            ; e = they match
  6433.     lea    si,atiwid2        ; alternative signature
  6434.     mov    di,30h            ; start at this offset
  6435.     mov    cx,atilen2        ; alternative signature length
  6436.     mov    ax,es:[di]        ; get first two bytes
  6437.     cmp    al,atiwid2        ; string starts here?
  6438.      je    ckatiw1            ; e = yes
  6439.     inc    di            ; try next location, just in case
  6440.     cmp    ah,atiwid2        ; or here?
  6441.     je    ckatiw1            ; e = yes
  6442.     stc                ; strings differ
  6443.     ret
  6444. ckatiw1:repe    cmpsb            ; check the whole string
  6445.     je    catfnd            ; e = matches the whole thing
  6446.     stc                ; fail on mismatch
  6447.     ret
  6448. catfnd:    mov    ax,0003h        ; prepare to reset video mode
  6449.     cmp    byte ptr temp,0        ; are we setting or resetting?
  6450.     je    catfnd1            ; e is reset, exit
  6451.     mov    ax,0023h        ; set to 132 cols (Set Mode 23H)
  6452. catfnd1:int    screen
  6453.     clc                ; carry clear means success
  6454.     ret
  6455.  
  6456. chkpa:    mov    ax,0c000h        ; load Paradise ROM BIOS address
  6457.     mov    es,ax
  6458.     mov    ax,0057h        ; assume 132x25 mono display needed
  6459.     mov    di,0009h        ; load EGA board identifier index
  6460.     lea    si,pmega1        ; Paradise Autoswitch Mono ident
  6461.     mov    cx,pmegal1
  6462.     cld
  6463.     repe    cmpsb            ; do identification strings match?
  6464.     je    chgpa2            ; e = yes, check num of display lines
  6465.     mov    di,007dh        ; no, load VGA board identifier index
  6466.     lea    si,p30id        ; Paradise VGA, other flavors
  6467.     mov    cx,p30ln
  6468.     repe    cmpsb            ; do identification strings match?
  6469.     je    chgpa1            ; e = yes, check for color mode
  6470.     stc                ; fail
  6471.     ret
  6472. chgpa1:    cmp    crt_norm,3        ; is the "normal" screen in color?
  6473.     ja    chgpa2            ; a = no, orig assumption is correct
  6474.     mov    ax,0055h        ; assume 132x25 color required
  6475. chgpa2:    cmp    crt_lins,25        ; is the "normal" screen 25 lines?
  6476.     jna    chgpa3            ; na = yes, check num of cols needed
  6477.     dec    ax            ; change assumption to 132x43
  6478. chgpa3:    cmp    byte ptr temp,0        ; switching to a 132 column mode?
  6479.     jne    chgpa4            ; ne = yes
  6480.     mov    al,crt_norm        ; load "normal" display mode
  6481. chgpa4:    int    screen            ; issue BIOS call to change display
  6482.     clc                ; success
  6483.     ret
  6484.                     ; Video 7 Vega Deluxe
  6485. ckv7vd:    mov    ax,0c000h        ; seg addr for Vega rom bios
  6486.     mov    es,ax            ; set into es register
  6487.     mov    di,002ah        ; offset of message in ROM
  6488.     lea    si,vid7id        ; offset of message here
  6489.     mov    cx,vid7len
  6490.     cld
  6491.     repe    cmpsb            ; compare strings
  6492.     je    cnv7fn1            ; e = same
  6493.     mov    di,002ah        ; offset of ident string
  6494.     mov    si,offset vid7id2    ; Video 7 VGA board
  6495.     mov    cx,vid7len2
  6496.     repe    cmpsb
  6497.     je    cnv7fn2            ; e = found
  6498. cnv7fx:    stc                ; strings are different
  6499.     ret
  6500.                     ;
  6501. cnv7fn1:test    byte ptr es:[03ffeh],1    ; is this a 'Deluxe' Vega?
  6502.     jz    cnv7fx            ; z = nope, can't do it
  6503.     mov    ah,35h            ; DOS Get Vector
  6504.     mov    al,10h            ; Bios video interrupt
  6505.     int    dos            ; get it into es:bx
  6506.     mov    di,bx            ; es:bx is returned int 10h entry pnt
  6507.     sub    di,5ah            ; back offset to msg in 132X25.COM
  6508.     lea    si,vid7id        ; offset of validation message
  6509.     mov    cx,vid7len        ; length of validation string
  6510.     cld
  6511.     repe    cmpsb            ; Look for repeat of msg by 132X25.COM
  6512.     jne    cnv7fn2            ; if different
  6513.     mov    al,crt_mode        ; prepare to reset video mode
  6514.     xor    ah,ah
  6515.     cmp    byte ptr temp,0        ; are we setting or resetting?
  6516.     je    cnv7fn2a        ; e is reset
  6517.     mov    ax,0000h        ; set to 132 cols (old 40x25)
  6518. cnv7fn1a:int    screen
  6519.     clc
  6520.     ret
  6521.  
  6522. cnv7fn2:mov    ax,6f00h        ; check for VegaBios driver
  6523.     int    screen
  6524.     cmp    bx,'V7'            ; Video 7 Bios presence response
  6525.     jne    cnv7fx            ; ne = not there
  6526.     mov    ax,6f01h        ; al gets monitor type (mono,color,ega)
  6527.     int    screen
  6528.     mov    bx,51h            ; presume mono 132x25, page 0
  6529.     cmp    crt_lins,42        ; 43 lines active?
  6530.     jb    cnv7fn2a        ; b = no
  6531.     inc    bx            ; use bx = 52h for 132x43
  6532. cnv7fn2a:
  6533.     cmp    al,10h            ; analogue fixed freq (IBM 85xx)?
  6534.     je    cnv7fx            ; e = yes, no 132 columns
  6535.     cmp    al,2            ; 1 = mono, 2 = color, above = ega
  6536.     jb    cnv7fn3            ; b = mono or unknown
  6537.     mov    bx,4fh            ; presume med res color 132x25
  6538.     je    cnv7fn3            ; e = med res color, al = 2
  6539.     mov    bx,41h            ; ega high res 132x25, enhanced mons
  6540.     cmp    crt_lins,42        ; 43 lines active?
  6541.     jb    cnv7fn3            ; b = no
  6542.     inc    bx            ; use bx = 42h for 132x43
  6543. cnv7fn3:mov    ax,6f05h        ; set special mode found in bl
  6544.     cmp    byte ptr temp,0        ; resetting to 80 column mode?
  6545.     jne    cnv7fn4            ; ne = no, setting 132x25
  6546.     mov    al,crt_norm        ; get normal mode
  6547.     xor    ah,ah            ; set mode
  6548.     cmp    crt_lins,42        ; 43 lines active?
  6549.     jb    cnv7fn4            ; b = no
  6550.     mov    bl,40h            ; use Video 7 mode 40h 80x43 for color
  6551.     mov    ax,6f05h        ; and do special mode set
  6552. cnv7fn4:int    screen            ; special mode is in bl
  6553.     mov    ax,0f00h        ; a nop screen bios command
  6554.     int    screen
  6555.     clc
  6556.     ret
  6557.  
  6558. ckevrx: mov     ax,0c000h               ; seg addr for Everex EV-659
  6559.         mov     es,ax                   ; set into es register
  6560.         mov     di,0047h                ; offset of message in ROM
  6561.         lea     si,evrxid               ; offset of message here
  6562.         mov     cx,evrxlen              ; length of validation string
  6563.         cld
  6564.         repe    cmpsb                   ; compare strings
  6565.         jne     ckfnr2                  ; ne = strings differ
  6566.         mov     ah,crt_lins             ; we recognize either 44 or 25 rows
  6567.         cmp     ah,43                   ; equal to 44-1 rows?
  6568.         jne     ckfnr1                  ; ne = no
  6569.         mov     ax,0070h                ; Everex extended mode ident
  6570.         mov     bl,09h                  ; prepare to reset video mode to 80x44
  6571.         cmp     byte ptr temp,0         ; are we setting or resetting?
  6572.         je      ckfnr4                  ; e is reset, exit
  6573.         mov     bl,0bh                  ; 132x44
  6574.     int    screen
  6575.     clc
  6576.     ret
  6577. ckfnr1: cmp     ah,24                   ; equal to 25-1 rows?
  6578.     je    ckfnr3            ; e = yes
  6579. ckfnr2:    stc                ; return failure
  6580.     ret
  6581. ckfnr3:    mov     ax,0003h                ; prepare to reset video mode
  6582.         cmp     byte ptr temp,0         ; are we setting or resetting?
  6583.         je      ckfnr4                  ; e is reset, exit
  6584.         mov     ax,0070h                ; Everex extended mode ident
  6585.         mov     bl,0ah                  ; 132x25
  6586. ckfnr4:    int    screen
  6587.     clc
  6588.     ret
  6589. ckevga:    mov    ax,0c000h        ; Everex FVGA-673, EV-678 rom segment
  6590.     mov    es,ax
  6591.     mov    di,76h            ; offset in rom for board's id string
  6592.     lea    si,evgid        ; id string
  6593.     mov    cx,evglen        ; length of id string
  6594.     cld
  6595.     repe    cmpsb            ; do they match?
  6596.     je    ckevg0            ; e = yes
  6597.     mov    di,9dh            ; offset in ROM for board's ID string
  6598.     lea    si,evvid        ; ID string
  6599.     mov    cx,evvlen        ; length of ID string
  6600.     cld
  6601.     repe    cmpsb            ; do they match?
  6602.     jne    ckevg2            ; ne = no
  6603. ckevg0:    mov    ax,3            ; prepare to reset video mode
  6604.     cmp    byte ptr temp,0        ; setting or resetting mode?
  6605.     je    ckevg1            ; e = resetting, exit
  6606.     mov    ax,0070h        ; mode for 132x25
  6607.     mov    bl,0ah            ; Everex mode 0ah
  6608. ckevg1:    int    screen
  6609.     clc
  6610.     ret
  6611. ckevg2:    stc                ; say board not found
  6612.     ret
  6613.                     ; AT&T EGA/VGA boards
  6614. ckatt:    mov    ax,0c000h        ; seg of first signature
  6615.     mov    es,ax
  6616.     mov    si,offset attvdc6    ; first pattern
  6617.     mov    di,35h            ; test area
  6618.     cld
  6619.     mov    cx,attvdlen        ; length
  6620.     repe    cmpsb
  6621.     je    ckatt2            ; e = found
  6622.     mov    cx,attvdlen        ; try second signature, same length
  6623.     mov    si,offset attvdc7
  6624.     mov    ax,0e000h        ; seg of second signature
  6625.     mov    es,ax
  6626.     mov    di,10h            ; test area
  6627.     repe    cmpsb
  6628.     je    ckatt2            ; e = found
  6629.     stc                ; not found
  6630.     ret
  6631. ckatt2:    mov    al,crt_norm        ; old mode
  6632.     xor    ah,ah
  6633.     cmp    byte ptr temp,0        ; resetting to 80 col?
  6634.     je    ckatt3            ; e = yes
  6635.     mov    ax,0055h        ; 132 cols, set mode 55h
  6636. ckatt3:    int    screen
  6637.     clc
  6638.     ret
  6639.                     ; VESA compatibles
  6640. chkvesa:mov    di,seg rdbuf        ; es:di is buffer for results
  6641.     mov    es,di
  6642.     mov    di,offset rdbuf
  6643.     mov    ax,4f00h        ; get SVGA information
  6644.     int    screen
  6645.     cmp    ax,4fh            ; success?
  6646.     jne    chkvesax        ; ne = no
  6647.     cmp    word ptr rdbuf,'EV'    ; 'VESA'
  6648.     jne    chkvesax        ; ne = no
  6649.     cmp    word ptr rdbuf+2,'AS'
  6650.     jne    chkvesax        ; ne = no
  6651.     mov    ax,4f01h        ; get mode info to es:di buffer
  6652.     mov    cx,109h            ; 109h is 132x25 text
  6653.     int    screen
  6654.     cmp    ax,4fh            ; success?
  6655.     jne    chkvesax        ; ne = no
  6656.     mov    bx,3            ; assume 80 columns
  6657.     cmp    byte ptr temp,0        ; setting or resetting mode?
  6658.     je    chkvesa2        ; e = resetting
  6659.     mov    bx,109h            ; mode for 132x25
  6660. chkvesa2:mov    ax,4f02h        ; set mode from bx
  6661.     int    screen
  6662.     cmp    ax,4fh            ; success?
  6663.     jne    chkvesax        ; ne = no
  6664.     clc                ; say success
  6665.     ret
  6666. chkvesax:stc                ; say failure
  6667.     ret
  6668.  
  6669.                     ; IBM XGA 132 columns
  6670. ckxga:    push    bp            ; (old BIOSes are still around)
  6671.     push    ds            ; set es to data segment
  6672.     pop    es
  6673.     mov    ax,1b00h        ; get functionality table
  6674.     xor    bx,bx
  6675.     mov    di,offset decbuf    ; es:di is 64 bytes of workspace
  6676.     int    screen
  6677.     cmp    al,1bh            ; is this call supported?
  6678.     jne    ckxgax            ; ne = no, fail
  6679.     les    bx,dword ptr decbuf    ; get the address of the modes info
  6680.     test    byte ptr es:[bx+2],10h    ; is mode 14h supported?
  6681.     jz    ckxman            ; z = no, try manual method for now
  6682.     mov    ax,3            ; assume resetting to mode 3, 80x25
  6683.     cmp    byte ptr temp,0        ; setting 132 columns?
  6684.     je    ckxga1            ; e = no, resetting to 80 columns
  6685.     mov    ax,14h            ; invoke IBM XGA mode 14h, 132x25
  6686. ckxga1:    int    screen
  6687. ckxga2:    pop    bp
  6688.     clc                ; say success
  6689.     ret
  6690. ckxgax:    pop    bp
  6691.     mov    xga_reg_base,-2        ; flag saying no XGA Adapter found
  6692.     stc                ; say failure
  6693.     ret
  6694.  
  6695. ckxman:    call    xgaman            ; do tests/sets manually
  6696.     pop    bp
  6697.     jnc    ckxman1            ; nc = success
  6698.     mov    xga_reg_base,-2        ; flag saying no XGA Adapter found
  6699. ckxman1:ret
  6700. chgdsp    endp
  6701.  
  6702. ; XGA mode setting via going to the hardware manually
  6703. ; Code furnished by Bert Tyler, National Institue of Health
  6704.  
  6705. xgaman    proc    near
  6706.     cmp    xga_reg_base,-2        ; has the XGA detector already failed?
  6707.     je    xgafail            ; e = yes, fail again
  6708.     cmp    xga_reg_base,-1        ; have we already found the XGA?
  6709.     je    xga_loc            ; e = no
  6710.     jmp    xga_do1            ; yes, process it
  6711. xga_loc:push    es
  6712.     mov    ah,35h            ; DOS get interrupt vector
  6713.     mov    al,15h            ; Int 15h
  6714.         int     dos                     ; returns vector in es:bx
  6715.     mov    ax,es            ; segment part
  6716.     pop    es
  6717.     or    ax,ax            ; undefined vector?
  6718.     jz    xgafail            ; z = yes
  6719.     mov    dx,-1            ; start with an invalid POS address
  6720.     mov    ax,0c400h        ; look for POS base address
  6721.     int    15h            ;  (Microchannel machines only)
  6722.     jc    xgafail            ; c = error, not a MC machine
  6723.     mov    word ptr decbuf,dx    ; save pos_base_address
  6724.     xor    cx,cx            ; check all MCA slots & motherboard
  6725.     cmp    dx,-1            ; do we have a good POS?
  6726.     jne    xga_lp1            ; ne = yes, proceed with MCA checks
  6727. xgafail:stc                ; fail
  6728.     ret
  6729.  
  6730. xga_lp1:cli                ; no interrupts, please
  6731.     cmp    cx,0            ; treat the motherboard differently?
  6732.     jne    xga_sk4            ; ne = yes
  6733.     mov    al,0dfh            ; enable the motherboard for setup
  6734.     mov    dx,94h
  6735.     out    dx,al
  6736.     jmp    short xga_sk5
  6737. xga_sk4:mov    ax,0c401h        ; enable an MCA slot for setup
  6738.     mov    bx,cx            ;  this slot
  6739.     int    15h
  6740. xga_sk5:mov    dx,word ptr decbuf    ; get pos record for the slot
  6741.     in    ax,dx            ;  ID
  6742.     mov    word ptr decbuf+2,ax
  6743.     add    dx,2            ; compute IO Res Base
  6744.     in    al,dx            ;  get POS data byte1
  6745.     and    ax,0eh            ;  muck about with it to get reg base
  6746.     shl    ax,1
  6747.     shl    ax,1
  6748.     shl    ax,1
  6749.     add    ax,2100h
  6750.     mov    xga_reg_base,ax
  6751.     cmp    cx,0            ; treat the motherboard differently?
  6752.     jne    xga_sk6            ; ne = yes
  6753.     mov    al,0ffh            ; enable the motherboard for normal
  6754.     out    094h,al
  6755.     jmp    short xga_sk7
  6756. xga_sk6:mov    ax,0c402h        ; enable the MCA slot for normal
  6757.     mov    bx,cx            ;  this slot
  6758.     int    15h
  6759. xga_sk7:sti                ; interrupts on again
  6760.  
  6761.     mov    ax,word ptr decbuf+2    ; is an XGA adapter on this slot?
  6762.     cmp    ax,08fd8h
  6763.     jae    xga_sk8            ; ae = yes
  6764.     jmp    xga_lp2            ; try another slot
  6765. xga_sk8:cmp    ax,08fdbh        ; still within range?
  6766.     jbe    xga_sk9            ; be = yes
  6767.     jmp    xga_lp2            ; no, try another slot
  6768. xga_sk9:mov    dx,xga_reg_base        ; is there a monitor on this slot?
  6769.     add    dx,0ah
  6770.     mov    al,052h
  6771.     out    dx,al
  6772.     mov    dx,xga_reg_base
  6773.     add    dx,0bh
  6774.     in    al,dx
  6775.     and    al,0fh
  6776.     cmp    al,0fh
  6777.     jne    xga_ska            ; ne = yes
  6778.     jmp    xga_lp2            ; no
  6779. xga_ska:mov    dx,xga_reg_base        ; is this XGA in VGA mode?
  6780.     in    al,dx
  6781.     test    al,1
  6782.     jnz    xga_do1            ; nz = yes, found it!
  6783.  
  6784. xga_lp2:inc    cx            ; try another adapter?
  6785.     cmp    cx,9            ; done all slots?
  6786.     ja    xga_no            ; a = yes
  6787.     jmp    xga_lp1            ; no, try another slot
  6788. xga_no:    jmp    xgafail            ; fail
  6789.  
  6790. ;    *finally* put the XGA into 132-column or 80-column mode
  6791.  
  6792. xga_do1:cmp    byte ptr temp,0        ; setting 80-column mode?
  6793.     jne    xga_do2            ; ne = no, 132 columns
  6794.     jmp    xga_do3            ; do 80 column mode
  6795.  
  6796.                     ; 132-column mode routine
  6797. xga_do2:mov    dx,xga_reg_base        ; (the manual doesn't explain...)
  6798.     add    dx,0ah
  6799.     mov    ax,1550h
  6800.     out    dx,ax
  6801.     mov    ax,1450h
  6802.     out    dx,ax
  6803.     mov    ax,0454h
  6804.     out    dx,ax
  6805.     mov    ax,1202h        ; select 400 scan lines
  6806.     mov    bl,30h
  6807.     int    screen
  6808.     mov    ax,0+3            ; set video mode 3
  6809.     int    screen
  6810.  
  6811.     mov    dx,xga_reg_base        ; (the manual doesn't explain...)
  6812.     add    dx,0ah
  6813.     mov    al,50h
  6814.     out    dx,al
  6815.     inc    dx
  6816.     in    al,dx
  6817.     or    al,1
  6818.     out    dx,al
  6819.  
  6820.     mov    dx,xga_reg_base        ; (the manual doesn't explain...)
  6821.     add    dx,0ah
  6822.     mov    al,50h
  6823.     out    dx,al
  6824.     inc    dx
  6825.     in    al,dx
  6826.     and    al,0fdh
  6827.     out    dx,al
  6828.  
  6829.     mov    dx,xga_reg_base        ; (the manual doesn't explain...)
  6830.     add    dx,0ah
  6831.     mov    al,50h
  6832.     out    dx,al
  6833.     inc    dx
  6834.     in    al,dx
  6835.     and    al,0fch
  6836.     out    dx,al
  6837.  
  6838.     mov    dx,xga_reg_base        ; (the manual doesn't explain...)
  6839.     mov    al,3
  6840.     out    dx,al
  6841.  
  6842.     mov    dx,xga_reg_base        ; (the manual doesn't explain...)
  6843.     add    dx,0ah
  6844.     mov    ax,0154h
  6845.     out    dx,ax
  6846.     mov    ax,8070h
  6847.     out    dx,ax
  6848.  
  6849.     mov    dx,xga_reg_base        ; (the manual doesn't explain...)
  6850.     add    dx,0ah
  6851.     mov    al,50h
  6852.     out    dx,al
  6853.     inc    dx
  6854.     in    al,dx
  6855.     and    al,0efh
  6856.     out    dx,al
  6857.  
  6858.     mov    dx,03d4h        ; (the manual doesn't explain...)
  6859.     mov    ax,11h
  6860.     out    dx,al
  6861.     inc    dx
  6862.     in    al,dx
  6863.     and    al,7fh
  6864.     out    dx,al
  6865.  
  6866.     mov    dx,03d4h        ; (the manual doesn't explain...)
  6867.     mov    ax,0
  6868.     out    dx,al
  6869.     inc    dx
  6870.     mov    ax,0a4h
  6871.     out    dx,al
  6872.  
  6873.     mov    dx,03d4h        ; (the manual doesn't explain...)
  6874.     mov    ax,1
  6875.     out    dx,al
  6876.     inc    dx
  6877.     mov    ax,83h
  6878.     out    dx,al
  6879.  
  6880.     mov    dx,03d4h        ; (the manual doesn't explain...)
  6881.     mov    ax,2
  6882.     out    dx,al
  6883.     inc    dx
  6884.     mov    ax,84h
  6885.     out    dx,al
  6886.  
  6887.     mov    dx,03d4h        ; (the manual doesn't explain...)
  6888.     mov    ax,3
  6889.     out    dx,al
  6890.     inc    dx
  6891.     mov    ax,83h
  6892.     out    dx,al
  6893.  
  6894.     mov    dx,03d4h        ; (the manual doesn't explain...)
  6895.     mov    ax,4
  6896.     out    dx,al
  6897.     inc    dx
  6898.     mov    ax,90h
  6899.     out    dx,al
  6900.  
  6901.     mov    dx,03d4h        ; (the manual doesn't explain...)
  6902.     mov    ax,5
  6903.     out    dx,al
  6904.     inc    dx
  6905.     mov    ax,80h
  6906.     out    dx,al
  6907.  
  6908.     mov    dx,xga_reg_base        ; (the manual doesn't explain...)
  6909.     add    dx,0ah
  6910.     mov    ax,0a31ah
  6911.     out    dx,ax
  6912.     mov    ax,001bh
  6913.     out    dx,ax
  6914.  
  6915.     mov    dx,03d4h        ; (the manual doesn't explain...)
  6916.     mov    ax,13h
  6917.     out    dx,al
  6918.     inc    dx
  6919.     mov    ax,42h
  6920.     out    dx,al
  6921.  
  6922.     mov    dx,03d4h        ; (the manual doesn't explain...)
  6923.     mov    al,11h
  6924.     out    dx,al
  6925.     inc    dx
  6926.     in    al,dx
  6927.     or    al,80h
  6928.     out    dx,al
  6929.  
  6930.     mov    dx,xga_reg_base        ; (the manual doesn't explain...)
  6931.     add    dx,0ah
  6932.     mov    al,50h
  6933.     out    dx,al
  6934.     inc    dx
  6935.     in    al,dx
  6936.     or    al,3
  6937.     out    dx,al
  6938.  
  6939.     mov    dx,03c4h        ; (the manual doesn't explain...)
  6940.     mov    ax,1
  6941.     out    dx,al
  6942.     inc    dx
  6943.     in    al,dx
  6944.     or    al,1
  6945.     out    dx,al
  6946.  
  6947.     mov    dx,03dah        ; (the manual doesn't explain...)
  6948.     in    al,dx
  6949.  
  6950.     mov    dx,003c0h        ; (the manual doesn't explain...)
  6951.     mov    al,13h
  6952.     out    dx,al
  6953.     xor    al,al
  6954.     out    dx,al
  6955.     mov    al,20h
  6956.     out    dx,al
  6957.  
  6958.     mov    ax,40h            ; tell the BIOS we have 132 columns
  6959.     mov    es,ax
  6960.     mov    byte ptr es:[4ah],132    ; set Bios screen width data area
  6961.     clc                ; return success
  6962.     ret
  6963.                         ; Set 80 column mode
  6964. xga_do3:mov    dx,xga_reg_base        ; (the manual doesn't explain...)
  6965.     add    dx,01h
  6966.     xor    al,al
  6967.     out    dx,al
  6968.  
  6969.     mov    dx,xga_reg_base        ; (the manual doesn't explain...)
  6970.     add    dx,4
  6971.     xor    al,al
  6972.     out    dx,al
  6973.  
  6974.     mov    dx,xga_reg_base        ; (the manual doesn't explain...)
  6975.     add    dx,5
  6976.     mov    al,0ffh
  6977.     out    dx,al
  6978.  
  6979.     mov    dx,xga_reg_base        ; (the manual doesn't explain...)
  6980.     add    dx,0ah
  6981.     mov    ax,0ff64h
  6982.     out    dx,ax
  6983.  
  6984.     mov    dx,xga_reg_base        ; (the manual doesn't explain...)
  6985.     add    dx,0ah
  6986.     mov    ax,1550h
  6987.     out    dx,ax
  6988.  
  6989.     mov    dx,xga_reg_base        ; (the manual doesn't explain...)
  6990.     add    dx,0ah
  6991.     mov    ax,1450h
  6992.     out    dx,ax
  6993.  
  6994.     mov    dx,xga_reg_base        ; (the manual doesn't explain...)
  6995.     add    dx,0ah
  6996.     mov    ax,0051h
  6997.     out    dx,ax
  6998.  
  6999.     mov    dx,xga_reg_base        ; (the manual doesn't explain...)
  7000.     add    dx,0ah
  7001.     mov    ax,0454h
  7002.     out    dx,ax
  7003.  
  7004.     mov    dx,xga_reg_base        ; (the manual doesn't explain...)
  7005.     add    dx,0ah
  7006.     mov    ax,7f70h
  7007.     out    dx,ax
  7008.  
  7009.     mov    dx,xga_reg_base        ; (the manual doesn't explain...)
  7010.     add    dx,0ah
  7011.     mov    ax,202ah
  7012.     out    dx,ax
  7013.  
  7014.     mov    dx,xga_reg_base        ; (the manual doesn't explain...)
  7015. ;;    add    dx,00h
  7016.     mov    al,1
  7017.     out    dx,al
  7018.  
  7019.     mov    dx,03c3h        ; (the manual doesn't explain...)
  7020.     mov    al,1
  7021.     out    dx,al
  7022.  
  7023.     mov    ax,1202h        ; select 400 scan lines
  7024.     mov    bl,30h
  7025.     int    screen
  7026.     mov    ax,0+3            ; set video mode 3
  7027.     int    screen
  7028.     clc                ; return success
  7029.     ret
  7030. xgaman    endp
  7031.  
  7032. ; Routine to do keyclick if flag is set, no arguments
  7033. vclick    proc    near
  7034.     test    vtemu.vtflgop,vskeyclick ; is keyclick flag on?
  7035.     jz    vclick1            ; z = no, just return
  7036.     push    bx
  7037.     push    di
  7038.     mov    di,500            ; 500 Hertz
  7039.     mov    bx,1            ; For 1 millisecond
  7040.     call    vtsound            ; Do it
  7041.     pop    di            ; Restore the ACs
  7042.     pop    bx
  7043. vclick1:ret
  7044. vclick    endp
  7045.  
  7046. ; Routine to do VT100-style bell, no arguments
  7047. fvtbell    proc    far
  7048.     call    vtbell
  7049.     ret
  7050. fvtbell    endp
  7051.  
  7052. vtbell    proc    near
  7053.     cmp    belltype,1        ; visual bell?
  7054.     je    vtbell1            ; e = yes
  7055.     ja    vtbell2            ; a = no bell
  7056.     push    di            ; audible bell
  7057.     push    bx
  7058.     mov    di,880            ; 880 Hertz
  7059.     mov    bx,40            ; For 40 ms
  7060.     call    vtsound            ; Do it
  7061.     pop    bx
  7062.     pop    di
  7063.     ret
  7064. vtbell1:call    revscn            ; reverse screen
  7065.     push    ax
  7066.     mov    ax,40            ; for 40 milliseconds
  7067.     call    fpcwait
  7068.     pop    ax
  7069.     call    revscn            ; put back
  7070. vtbell2:ret
  7071. vtbell    endp
  7072.  
  7073. ; Routine to make noise of arbitrary frequency for arbitrary duration.
  7074. ; Similar to routine (with typo removed) in "IBM PC Assembly Language:
  7075. ; A Guide for Programmers", Leo J. Scanlon, 1983 Robert J. Brady Co.,
  7076. ; Bowie, MD., page 270. Modified by J R Doupnik to use 0.1 millsec interval.
  7077. ; Call:        di/    frequency in Hertz.
  7078. ;        bx/    duration in 1 millisecond units
  7079. vtsound proc    near
  7080.     push    ax            ; save regs
  7081.     push    cx
  7082.     push    dx
  7083.     mov    al,0B6H            ; write timer mode register
  7084.     out    43H,al
  7085.     mov    dx,14H            ; timer divisor is
  7086.     mov    ax,4F38H        ; 1331000/frequency
  7087.     div    di
  7088.     out    42H,al            ; write timer 2 count low byte
  7089.     mov    al,ah
  7090.     out    42H,al            ; write timer 2 count high byte
  7091.     in    al,61H            ; get current port B setting
  7092.     or    al,3            ; turn speaker on
  7093.     out    61H,al
  7094.     mov    ax,bx            ; number of milliseconds to wait
  7095.     call    fpcwait            ; do the calibrated wait
  7096.     in    al,61H            ; get current port B setting
  7097.     and    al,0fch            ; turn off speaker and timer
  7098.     out    61H,al
  7099.     pop    dx            ; restore regs
  7100.     pop    cx
  7101.     pop    ax
  7102.     ret
  7103. vtsound endp
  7104. code1    ends
  7105.     end
  7106.