home *** CD-ROM | disk | FTP | other *** search
/ Phoenix CD 2.0 / Phoenix_CD.cdr / 01e / msk230s2.zip / MSYIBM.ASM < prev    next >
Assembly Source File  |  1988-02-12  |  100KB  |  2,018 lines

  1.         NAME msyibm
  2. ; File MSYIBM.ASM
  3. ; edit history:
  4. ; Last edit: 5 Jan 1988
  5. ; 5 Jan 1988 Restore cursor codes broken by Tek code additions. [jrd]
  6. ; 1 Jan 1988 version 2.30
  7. ; 24 Dec 1987 Restore startup screen attributes at Kermit prompts. [jrd]
  8. ; 21 Dec 1987 Fix memory size sign problem for >640K systems. From Edgar Butt
  9. ; 4 Dec 1987 cleanup mode switching, add more Video 7 material. [jrd]
  10. ; 8 Nov 1987 Add EGA mode switching, from Terry Kennedy.
  11. ; 1 Nov 1987 Add support for Tektronix, based on work by Brian Holley. [jrd]
  12. ; 13 Oct 1987 Revise memory allocation sequence to avoid small holes. [jrd]
  13. ; 2 Oct 1987 Make log file character width match Set Display but 8 bits when
  14. ;  debugging. [jrd]
  15. ; 12 Sept 1987 clarify sequence of translation and 8 bit display. [jrd]
  16. ; 27 Aug 1987 Do Translation before logging. [jrd]
  17. ; 18 Aug 1987 Change ESC to escape for MASM 4.5+ [jrd]
  18. ; 28 July 1987 Fix scron problem in screen save. [jrd]
  19. ; 16 June 1987 Remove global byte jwait (wait for vertical retrace), embedd
  20. ;  code for proc scrwait in proc scroff. Replace calls for scrwait with
  21. ;  calls to scron/scroff. Thanks to Dave Tweten (dt). [jrd]
  22. ; 11 June 1987 Add control of automatic screen roll back when new characters
  23. ;  are to be displayed; default is off (no roll back). [jrd]
  24. ; 8 June 1987 Add keypad application mode tests to emit single chars. [jrd]
  25. ; 10 May 1987 Move input translation into terminal emulator, leave copy
  26. ;  here for terminal type None, use mszibm byte anspflg to sense print
  27. ;  screen is active, print translated characters but don't translate if
  28. ;  debugging is active. [jrd]
  29. ; 28 March 1987 Make low_rgt screen coord word a global parameter.
  30. ;  Add support for variable length screens and cursor size changes with
  31. ;  EGA boards. Tests ok with 25, 35, 43, 50 lines with &/without MS Windows.
  32. ;  EGA Memory locations 40:84H and 40:87H are used in this process.
  33. ;  Use savadr dw as place to save screen: usually screen page 1 if screen
  34. ;  dimensions are non-standard (80x25), else memory buffer scrsav. [jrd]
  35. ; 21 March 1987 Translate arriving Connect mode chars via table rxtable. [jrd]
  36. ;  Add 132 Column support for Tseng Labs EVA board via procedure chgdsp,
  37. ;  add restore scrolled screen before writing to it. From David L. Knoell [dlk]
  38. ; Modify msy and msz to use variable screen length and widths. [dlk] and [jrd]
  39. ; 17 March 1987 Reduce screen roll back buffer to half the memory to do the
  40. ;  same number of screens. [jrd]
  41. ; 12 Jan 1987 Add keyboard translator, remove older code. [jrd]
  42. ; 1 Oct 1986 Version 2.29a
  43.  
  44.         public  term, lclyini                           ; entry points
  45.         public  prtbout, prtnout, csrtype, scrmod, scrseg, scrsync
  46.         public  scroff, scron, atsclr, vtscru, vtscrd, scrloc, trnmod, telmsy
  47.         public  chgdsp, vtroll, crt_lins, crt_cols, getflgs, tv_mode
  48.                         ; action verb procedures for keyboard translator
  49.         public  uparrw, dnarrw, rtarr, lfarr, pf1, pf2, pf3, pf4
  50.         public  kp0, kp1, kp2, kp3, kp4, kp5, kp6, kp7, kp8, kp9
  51.         public  kpminus, kpcoma, kpenter, kpdot, chrout, cstatus, cquit
  52.         public  cquery, dmpscn, vtans52, vtinit, dnwpg, upwpg, endwnd, homwnd
  53.         public  upone, dnone, trnprs, dumpscr, modlin, modwrt, snull
  54.         public  klogon, klogof, cdos, chang
  55.  
  56.         public  vtemu, crt_mode, scbattr, refresh, low_rgt  ; data
  57.         public  savescr, restscr
  58.  
  59.         include mssdef.h
  60.  
  61. ; some definitions
  62. ; hardware
  63. crt_status equ  3dah                    ; CGA crt status port
  64. disp_enb equ    8                       ; CGA display enable bit
  65. crtmset equ     3D8H                    ; CGA CRT mode set port.
  66. screen  equ     10h                     ; bios screen interrupt
  67. biostty equ     0eh                     ; Bios screen tty write mode
  68.  
  69. modfrm  struc                           ; format of mode (status) line
  70.         db      'Esc-chr: '             ; do not write in last column.
  71. m_echr  db      2 dup (?)
  72.         db      '  help: '
  73. m_hlp   db      2 dup (?)
  74.         db      '?  port:'
  75. m_prt   db      1 dup (?)
  76.         db      ' speed:'
  77. m_baud  db      5 dup (?)
  78.         db      ' parity:'
  79. m_par   db      4 dup (?)
  80.         db      ' echo:'
  81. m_echo  db      3 dup (?)
  82. m_term  db      13 dup (' ')            ; 13 bytes for term type
  83. m_prn   db      3 dup (' ')             ; show PRN when printer is on
  84. modfrm  ends
  85.  
  86.  
  87. datas   segment public 'datas'
  88.         extrn flags:byte, mar_top:byte, mar_bot:byte, portval:word
  89.         extrn filtst:byte, dmpname:byte, kbdflg:byte, rxtable:byte
  90.         extrn anspflg:byte, tekflg:byte
  91.  
  92. ; stuff for screen routines
  93. yflags  db      ?                       ; status flags...
  94. flags1  db      0                       ; internal flags (but used in mszibm).
  95. prtscr  equ     1                       ; print screen pressed
  96. inited  equ     08h                     ; been here before...
  97. vtinited db     0                       ; flag for emulator having been inited
  98. cursor  dw      ?
  99. esc_ch  db      ?
  100. parmsk  db      ?                       ; 8/7 bit parity mask, for reception
  101. argadr  dw      ?                       ; address of arg blk
  102.  
  103. vid7id  db      'VEGA BIOS Code, '      ; Video 7 Vega version string subset
  104. vid7len equ     $-vid7id                ; length of string
  105. atiwid  db      'ATI EGA Wonder Bios,'  ; ATI EGA wonder version string subset
  106. atilen  equ     $-atiwid                ; length of string, inc terminator
  107. tsngid  db      'Tseng'                 ; Tseng Labs EVA board
  108. tsnglen equ     $-tsngid
  109. ega_mode db     0                       ; non-zero if IBM EGA is in use.
  110. tvhere  equ     0feh                    ; Topview active query
  111. tvsynch equ     0ffh                    ; Topview resynch request
  112. tv_segs dw      ?                       ; Topview virtual screen, segment
  113. tv_sego dw      ?                       ; and offset
  114. tv_mode db      0                       ; flag, 0 = no Topview.
  115. savadr  dw      2 dup (?)               ; offset then segment of saved screen
  116. savflg  dw      ?                       ; low_rgt at time of screen save
  117.  
  118.  
  119. ; The following are used to turn the display back on (after scrolling etc.)
  120. msets   db      2CH,28H,2DH,29H,2AH,2EH,1EH,29H
  121.  
  122.  
  123. vtemu   emulst  <>                      ; emulator flags
  124. ansflgs db      0                       ; ANSI flags
  125. trmtyp  db      0                       ; most recent terminal type
  126. mtty    db      '  TTY   '              ; no terminal type (mode line)
  127.  
  128. lincur  dw      ?                       ; cursor type save area
  129. scbattr db      ?                       ; Screen background attribute
  130. oldattr db      ?                       ; screen attributes at init time
  131. curattr db      ?                       ; current attribute
  132. temp    dw      ?                       ; scratch storage
  133. modtemp db      0                       ; temp to hold Kermit modeline status
  134. captrtn dw      ?                       ; routine to call for captured output
  135. dmphand dw      ?                       ; screen dump file handle
  136. dumpbuf db      132 dup (?), cr, lf     ; 134 byte dump work buffer
  137. dumpsep db      FF,cr,lf                ; screen image separators
  138. dmperr  db      ' Cannot open file to save screen to disk $'
  139. crlf    db      cr,lf,'$'
  140.  
  141. ; some static data for mode line
  142. modbuf  modfrm  <>                      ; mode line buffer
  143. unkbaud db      'unkwn'                 ; must be 5 chars...
  144. baudn   db      ' 45.5',' 50  ',' 75  ',' 110 ','134.5',' 150 ',' 300 ',' 600 '
  145.         db      ' 1200',' 1800',' 2000',' 2400',' 4800',' 9600','19200','38400'
  146.         db      '57.6K','115 K'
  147. baudnsiz  equ   18                      ; # of baud rates known (tbl size / 4)
  148. parnams db      'even','mark','none','odd ','spc '
  149. lclmsg  db      'loc'
  150. remmsg  db      'rem'
  151. portno  db      ?
  152.  
  153. ; storage for multi-window stuff
  154. swidth  equ     80                      ; max screen width
  155. slen    equ     24                      ; and length of text
  156. npages  equ     10                      ; # of pages of scrolling on each side
  157. crt_norm db     ?                       ; video mode for normal screen
  158. crt_mode db     ?                       ; video mode (typ 3, must be text)
  159. crt_cols db     ?                       ; number of screen columns (typ 80)
  160. crt_lins db     24                      ; number of screen rows - 1 (typ 24)
  161. low_rgt dw      ?                       ; lower right corner of text window
  162.                                         ; high = row address (typ 23)
  163.                                         ; low = column address (typ 79)
  164. inipara dw      ?                       ; initial paragraphs of scroll memory
  165. scrsav  dw      ?                       ; segment address of save area
  166. refresh db      0                       ; screen refresh (0=wait for retrace)
  167. vtroll  db      0                       ; auto roll back allowed (0 = no).
  168.  
  169. ; circular buffer for screen roll back.
  170. cbuf    struc
  171. pp      dw      ?                       ; place ptr in buffer
  172. bend    dw      ?                       ; end of buffer
  173. orig    dw      ?                       ; buffer origin
  174. lcnt    dw      0                       ; # of lines in buffer.
  175. lmax    dw      ?                       ; max lines of buffer.
  176. cbuf    ends
  177.  
  178. twnd    cbuf    <>                      ; top screen spill-buffer struct
  179. bwnd    cbuf    <>                      ; bottom screen spill buffer struct
  180.  
  181. datas   ends
  182.  
  183. code    segment public 'code'
  184.         extrn   beep:near, prtchr:near, outchr:near, sbrk:near, pcwait:near
  185.         extrn   isfile:near, strlen:near, strcpy:near   ; in mssfil
  186.         extrn   anstty:near,ansini:near,ansrei:near     ; in mszibm
  187.         extrn   anstat:near,anskbi:near,ansdsl:near     ; in mszibm
  188.         extrn   ans52t:near, vsinit:near                ; in mszibm
  189.         extrn   msuinit:near, keybd:near                ; in msuibm
  190.         extrn   tekini:near,tekcls:near,tekemu:near,tekend:near ;in msgibm
  191.  
  192.         assume  cs:code, ds:datas, es:datas
  193.  
  194. ; do initialization local to this module...
  195. ; Dynamically allocates 4000 bytes for screen save/restore buffer plus
  196. ;  320 to 38400 bytes for screen scroll back buffers. Tries to leave space
  197. ;  for Command.com before enlarging buffers. [jrd]
  198. lclyini proc    near
  199.         call    msuinit                 ; initialize keyboard module msuxxx
  200.  
  201.         mov     ax,swidth*(slen+1)*2    ; (80 char + 80 attr) * 25 lines
  202.         call    sbrk                    ; memory allocation routine (mssker)
  203.                                         ;if we get here them we have the lines
  204.         mov     scrsav,ax               ; memory segment for save screens
  205.                                         ; screen roll back buffers
  206.         mov     bx,0ffffh               ; ask for all of memory, to get size
  207.         mov     ah,alloc                ; allocate all of memory (must fail)
  208.         int     dos                     ; bx has # free paragraphs
  209.         mov     ax,bx                   ; ax has copy of number free paragraphs
  210.         sub     ax,24000D/16            ; space for Command.com copy #2
  211.         jbe     lclyin1                 ; be = not enough for it. [ebb]
  212.         cmp     ax,(swidth*slen+15)/16  ; minimum roll back space left over?
  213.         jbe     lclyin1                 ; be = not even that much
  214.         cmp     ax,(swidth*slen*npages+7)/8 ; paragraphs wanted for roll back
  215.         jbe     lclyin2                 ; be = enough but not more than needed
  216.         mov     ax,(swidth*slen*npages+7)/8 ; limit to our actual needs
  217.         jmp     short lclyin2           ; ask for all we really want
  218. lclyin1:mov     ax,(4*swidth+15)/16     ; use minimum needed paragraphs
  219. lclyin2:mov     inipara,ax              ; save for later resizing of buffers
  220.         mov     cl,4                    ; convert paragraphs to bytes
  221.         shl     ax,cl                   ;  for sbrk
  222.         call    sbrk                    ; ask for that many bytes
  223.                                         ;if we get here them we have the space
  224.         mov     bwnd.orig,ax            ; memory segment, bottom window area
  225.         mov     twnd.orig,ax            ; top. same place for both buffers!
  226.         mov     ax,inipara              ; # paragraphs allocated by DOS
  227.         mov     cl,3                    ; 2**3 = 8
  228.         shl     ax,cl                   ; paragraphs to words (char + attrib)
  229.         xor     dx,dx                   ; clear extended size
  230.         mov     cx,swidth               ; number of chars per line in buffer
  231.         div     cx                      ; ax = number of lines in buffer
  232.         mov     bwnd.lmax,ax            ; max lines per buffer (quotient)
  233.         mov     twnd.lmax,ax            ; max lines per buffer
  234.         add     cx,cx                   ; count char and attribute per item
  235.         xor     dx,dx                   ; clear extended numerator
  236.         mul     cx                      ; ax = effective # bytes per buffer
  237.         dec     ax                      ; adjust for counting from zero
  238.         mov     bwnd.bend,ax            ; offset of last byte in buffer
  239.         mov     twnd.bend,ax            ; offset of last byte in buffer
  240.         mov     bwnd.pp,0               ; offset of first byte in buffer
  241.         mov     twnd.pp,0               ; offset of first byte in buffer
  242.         mov     bwnd.lcnt,0             ; number of lines occupied in buffer
  243.         mov     twnd.lcnt,0             ; number of lines occupied in buffer
  244.         call    scrseg                  ; test running in an Environment
  245.         call    scrmod                  ; read video state, get crt_mode.
  246.         mov     al,crt_mode
  247.         mov     crt_norm,al             ; save as normal mode
  248.         mov     ah,8                    ; read current attributes
  249.         xor     bh,bh                   ; page 0
  250.         int     screen
  251.         mov     scbattr,ah              ; save video attributes
  252.         mov     oldattr,ah              ; and here too
  253.         call    vsinit                  ; init terminal emulator module MSZ
  254.         ret
  255. lclyini endp
  256.  
  257. scrini  proc    near                    ; init screen stuff
  258.         call    scrmod                  ; get screen mode, low_rgt
  259.         mov     ah,3                    ; get cursor position and char.
  260.         xor     bh,bh                   ; page 0
  261.         int     screen
  262.         mov     lincur,cx               ; save cursor type (scan line #'s)
  263.         mov     ax,low_rgt              ; present screen text size
  264.         cmp     ax,savflg               ;  vs size of saved screen
  265.         je      scrin7                  ; e = same
  266.         and     flags1,not(inited)      ; different, reinit screen (no restore)
  267.         and     vtinited,not(inited)    ; re-init emulator and clear rollback
  268.         mov     ax,inipara              ; paragraphs allotted to roll back
  269.         mov     cl,3                    ; 2**3 = 8
  270.         shl     ax,cl                   ; paragraphs to words (char + attrib)
  271.         xor     dx,dx                   ; clear extended size
  272.         mov     cl,byte ptr low_rgt     ; number of chars per line in buffer
  273.         inc     cl                      ; chars per line
  274.         xor     ch,ch                   ; clear high byte
  275.         div     cx                      ; ax = number of lines in buffer
  276.         mov     bwnd.lmax,ax            ; max lines per buffer (quotient)
  277.         mov     twnd.lmax,ax            ; max lines per buffer
  278.         add     cx,cx                   ; count char and attribute per item
  279.         xor     dx,dx                   ; clear extended numerator
  280.         mul     cx                      ; ax = effective # bytes per buffer
  281.         dec     ax                      ; adjust for counting from zero
  282.         mov     bwnd.bend,ax            ; offset of last byte in buffer
  283.         mov     twnd.bend,ax            ; offset of last byte in buffer
  284.         mov     bwnd.pp,0               ; offset of first byte in buffer
  285.         mov     twnd.pp,0               ; offset of first byte in buffer
  286.         mov     bwnd.lcnt,0             ; number of lines occupied in buffer
  287.         mov     twnd.lcnt,0             ; number of lines occupied in buffer
  288.  
  289. scrin7:
  290.         mov     dx,cursor               ; assume old cursor
  291.         mov     ega_mode,0              ; assume no EGA.
  292.         mov     ax,1200H                ; EGA: Bios alternate select
  293.         mov     bl,10H                  ; Ask for EGA info
  294.         mov     bh,0ffH                 ; Bad info, for testing
  295.         mov     cl,0fH                  ; Reserved switch settings
  296.         int     screen                  ; EGA, are you there?
  297.         cmp     cl,0cH                  ; Test reserved switch settings
  298.         jge     scrin6                  ; ge = no EGA in use.
  299.         push    es
  300.         mov     ax,40h                  ; check Bios 40:87h for ega being
  301.         mov     es,ax                   ;  the active display adapter
  302.         test    byte ptr es:[87h],8     ; is ega active?
  303.         pop     es
  304.         jnz     scrin6                  ; nz = no
  305.         mov     ega_mode,1              ; yes, set flag to say so.
  306.         mov     crt_norm,3              ; assume color monitor is attached
  307.         cmp     bh,0                    ; is color mode in effect?
  308.         je      scrin6                  ; e = yes
  309.         mov     crt_norm,7              ; else use mode 7 for mono
  310. scrin6: test    flags1,inited           ; have we been here before?
  311.         jnz     scrin4                  ; nz = yes, use old cursor
  312.         mov     ah,oldattr              ; get init time attributes
  313.         mov     curattr,ah              ; and set nice screen attribute
  314.         mov     scbattr,ah
  315.         mov     ah,3                    ; figure out where cursor is
  316.         xor     bh,bh                   ; page 0
  317.         int     screen                  ; read cursor position, in dx
  318. scrin4: cmp     dh,byte ptr low_rgt+1   ; past logical end of screen?
  319.         jb      scrin2                  ; b = no, keep going
  320.         mov     dh,byte ptr low_rgt+1   ; yes, just use lower right corner
  321. scrin2: cmp     dl,byte ptr low_rgt     ; maybe past right margin
  322.         jb      scrin3                  ; b = no, use the way it is
  323.         mov     dl,byte ptr low_rgt
  324. scrin3: mov     cursor,dx               ; init cursor
  325.         mov     ah,2                    ; set cursor position
  326.         xor     bh,bh                   ; page zero
  327.         int     screen                  ; set cursor in case it moved
  328.         ret
  329. scrini  endp
  330.  
  331. ; Routine to initialize VT102/52/Heath-19 terminal emulator.
  332.  
  333. vtinit  proc    near
  334.         cmp     flags.vtflg,0           ; doing emulation?
  335.         je      vtinix                  ; e = no
  336.         cmp     tekflg,0                ; Tek mode active?
  337.         jne     vtini2                  ; ne = yes, do it's reinit
  338.         or      vtinited,inited
  339.         call    ansflg                  ; update ansi flags
  340.         mov     al,yflags               ; Pass the flags.
  341.         mov     bx,argadr               ; Get address of argument block
  342.         mov     dl,[bx].baudb           ; Baud rate code in dl
  343.         mov     dh,[bx].parity          ; Parity code in bits
  344.         mov     cl,4                    ; 0-3 of dh
  345.         shl     dh,cl
  346.         test    flags.remflg,d8bit      ; eight bit display?
  347.         jnz     vtini1                  ; nz = yes
  348.         or      dh,07H                  ; Just say 7 data bits.
  349.         call    ansini                  ; call startup routine in mszibm.
  350.         ret
  351. vtini1: or      dh,8                    ; say 8 bits
  352.         call    ansini
  353. vtinix: clc
  354.         ret
  355. vtini2: call    tekcls                  ; clear Tek screen
  356.         clc
  357.         ret
  358. vtinit  endp
  359.  
  360.  
  361. argini  proc    near                    ; read passed arguments
  362.         mov     bx,argadr               ; base of argument block
  363.         mov     al,[bx].flgs            ; get flags
  364.         and     al,capt+emheath+havtt+trnctl+lclecho+modoff+lnwrap
  365.         mov     yflags,al               ; mask for allowable and save
  366.         mov     al,[bx].prt
  367.         mov     portno,al               ; update port number
  368.         mov     al,[bx].rows
  369.         mov     crt_lins,al             ; init # of rows and cols
  370.         mov     ax,[bx].captr
  371.         mov     captrtn,ax              ; buffer capture routine
  372.         mov     al,[bx].escc
  373.         mov     esc_ch,al
  374.         mov     parmsk,0ffh             ; parity mask, assume parity = None
  375.         cmp     [bx].parity,parnon      ; is parity None?
  376.         je      argini1                 ; e = yes, keep all 8 bits
  377.         mov     parmsk,07fh             ; else keep lower 7 bits
  378. argini1:ret                             ; that's it
  379. argini  endp
  380.  
  381. modlin  proc    near                    ; turn on mode line
  382.         mov     al,esc_ch
  383.         mov     modbuf.m_echr,' '       ; first char is initial space
  384.         mov     modbuf.m_hlp,' '        ; goes here too.
  385.         cmp     al,32                   ; printable?
  386.         jnb     modl1                   ; yes, keep going
  387.         add     al,40h                  ; made printable
  388.         mov     modbuf.m_echr,5eh       ; caret, note control char
  389.         mov     modbuf.m_hlp,5eh
  390. modl1:  mov     modbuf.m_echr+1,al      ; fill in character
  391.         mov     modbuf.m_hlp+1,al
  392.         mov     bx,argadr               ; get argument block
  393.         mov     al,[bx].baudb           ; get baud bits
  394.         mov     si,offset unkbaud       ; assume unknown baud
  395.         cmp     al,baudnsiz             ; too big?
  396.         jnb     modl2                   ; nb = yes, use default
  397.         mov     cl,size m_baud          ; each is 5 bytes long
  398.         mul     cl
  399.         mov     ah,0
  400.         add     ax,offset baudn
  401.         mov     si,ax
  402. modl2:  mov     cx,size m_baud          ; length of baud space
  403.         mov     di,offset modbuf.m_baud
  404.         push    es                      ; save es
  405.         push    ds
  406.         pop     es                      ; set es to datas segment
  407.         cld
  408.         rep     movsb                   ; copy in baud rate
  409.         mov     al,[bx].parity          ; get parity code
  410.         mov     cl,2                    ; each is 4 bytes long...
  411.         shl     al,cl
  412.         mov     ah,0
  413.         add     ax,offset parnams       ; names of parity settings
  414.         mov     si,ax
  415.         mov     cx,4                    ; each is 4 long
  416.         mov     di,offset modbuf.m_par
  417.         rep     movsb
  418.         mov     si,offset remmsg        ; Assume remote echoing.
  419.         test    yflags,lclecho          ; Is remote side echoing?
  420.         jz      modl4                   ; Yes, keep going
  421.         mov     si,offset lclmsg        ; Else it's local echoing.
  422. modl4:  mov     cx,3                    ; size of on/off
  423.         mov     di,offset modbuf.m_echo
  424.         rep     movsb
  425.         mov     al,portno               ; communications port
  426.         cmp     al,' '                  ; binary (non-printable)?
  427.         jae     modl5                   ; ae = no, ascii
  428.         add     al,'0'                  ; convert to ascii
  429. modl5:  mov     modbuf.m_prt,al         ; fill in port number
  430.         mov     cx,8                    ; blank out terminal id field
  431.         mov     si,offset mtty          ; assume no terminal emulation.
  432.         mov     di,offset modbuf.m_term ; destination
  433.         rep     movsb                   ; copy it in.
  434.         mov     modbuf.m_prn,' '        ; assume not printing the screen
  435.         mov     modbuf.m_prn+1,' '
  436.         mov     modbuf.m_prn+2,' '
  437.         test    anspflg,prtscr          ; doing a print the screen?
  438.         jz      modl5a                  ; z = no.
  439.         mov     modbuf.m_prn,'P'        ; yes. display PRN at end of line
  440.         mov     modbuf.m_prn+1,'R'
  441.         mov     modbuf.m_prn+2,'N'
  442. modl5a: mov     cx,size modfrm          ; this is size of mode line
  443.         mov     si,offset modbuf        ; mode line image
  444.         pop     es
  445.                         ; alternate entry to write an alternate mode line
  446. modwrt: push    cx
  447.         push    si                      ; save mode line and size
  448.         mov     ah,3                    ; read cursor position
  449.         xor     bx,bx                   ; screen page 0
  450.         int     screen
  451.         mov     cursor,dx               ; save cursor position
  452.         call    trmatt                  ; Get terminal attributes
  453.         and     ah,77h                  ; omit blinking/bold attributes
  454.         mov     bh,ah                   ; get video attribute
  455.         mov     dx,low_rgt              ; right most column
  456.         inc     dh                      ; refer to status line
  457.         mov     ch,dh                   ; bottom line [dlk]
  458.         mov     cl,0                    ; left col = 0 (first) [dlk]
  459.         mov     ax,600h                 ; scroll to clear the line
  460.         int     screen
  461.         mov     dh,byte ptr low_rgt+1   ; refer to status line
  462.         inc     dh
  463.         xor     dl,dl                   ; left most column
  464.         mov     bh,0
  465.         mov     ah,2                    ; set cursor position
  466.         int     screen
  467.         pop     si
  468.         pop     cx                      ; restore these
  469.         cmp     cl,crt_cols             ; mode line longer than screen?
  470.         jbe     modl6                   ; le = no
  471.         mov     cl,crt_cols             ; else do just one line's worth
  472.         dec     cx                      ; don't let screen scroll
  473. modl6:  cld
  474.         lodsb                           ; get a byte
  475.         mov     ah,14                   ; write to terminal
  476.         mov     bh,0                    ; page 0
  477.         int     screen
  478.         loop    modl6                   ; write out entire mode line
  479.         cmp     flags.vtflg,0           ; emulating?
  480.         je      modl7                   ; e = no
  481.         and     yflags,not modoff       ; update local flags (mode line on)
  482.         mov     al,yflags               ; Yes - update flags also
  483.         call    ansdsl                  ; get extras from emulator
  484. modl7:  mov     dx,cursor
  485.         mov     ah,2
  486.         mov     bh,0
  487.         int     screen                  ; put cursor back where it belongs
  488.         ret                             ; and return
  489. modlin  endp
  490.  
  491. clrmod  proc    near                    ; clear mode line
  492.         call    trmatt                  ; Get terminal screen attributes
  493.         mov     bh,al                   ; Use screen background attribute
  494.         mov     ax,600h                 ; blank window
  495.         mov     dx,low_rgt              ; right most column
  496.         inc     dh                      ; refer to status line
  497.         mov     cx,dx                   ; bottom line [dlk]
  498.         xor     cl,cl                   ; left most column
  499.         int     screen                  ; clear mode line
  500.         ret                             ; and return
  501. clrmod  endp
  502.  
  503.  
  504. ; Fetch screen attributes from emulator (if emulating). It exists mainly
  505. ; so that the reverse video will work.   Returns the current mode
  506. ; line background attribute in ah, the current screen background in al,
  507. ; and the current "cursor" (foreground) attribute in bl.  (Note: anstat
  508. ; returns status yflags in bh).
  509.  
  510. trmatt  proc    near                    ; Get attributes
  511.         cmp     flags.vtflg,0           ; emulating?
  512.         je      trmat1                  ; No, just do simple stuff.
  513.         mov     al,yflags               ; anstat expects flags byte in al.
  514.         call    anstat                  ; Fetch emulator status/attributes
  515.         ret
  516. trmat1: mov     al,scbattr              ; Background attributes.
  517.         mov     bl,curattr              ; And cursor attribute.
  518.         mov     ah,al                   ; where modlin needs them
  519.         and     ah,77h                  ; get colors part, no blink/bold
  520.         rol     ah,1                    ; reverse them
  521.         rol     ah,1
  522.         rol     ah,1
  523.         rol     ah,1
  524.         ret
  525. trmatt  endp
  526.  
  527. ; Get byte yflags of terminal emulator passed in AL. Used in mode line
  528. ; handling when 25th line is used by the emulator. [jrd]
  529. telmsy  proc    near
  530.         mov     yflags,al               ; get the updated flags
  531.         call    ansflg                  ; and any other emulator info
  532.         ret
  533. telmsy  endp
  534.  
  535.  
  536. ;[IU2] This routine updates the ANSI status flags from the emulator,
  537. ; and passes the "yflags" byte to the VT100 emulator also.
  538.  
  539. ansflg  proc    near
  540.         push    ax                      ; Save acs over call
  541.         push    bx
  542.         mov     al,yflags
  543.         call    anstat                  ; Get status and attributes
  544.         mov     ansflgs,bh              ; Save.
  545.         pop     bx
  546.         pop     ax
  547.         ret
  548. ansflg  endp
  549.  
  550. getflgs proc    near                    ; supply yflags for terminal emulators
  551.         mov     al,yflags
  552.         ret
  553. getflgs endp
  554.  
  555. term    proc    near                    ; terminal mode entry point
  556.         mov     argadr,ax               ; save argument ptr
  557.         call    argini                  ; init options from arg address
  558.         call    scrini                  ; init screen stuff
  559.  
  560.         test    flags1,inited           ; have we run yet?
  561.         jz      term1                   ; z = no, so no saved screen yet
  562.         call    restscr                 ; restore screen
  563. term1:  or      flags1,inited           ; remember we've run already.
  564.         cmp     flags.vtflg,0           ; current terminal type = None?
  565.         je      term3a                  ; e = yes, nothing to init.
  566.         mov     al,yflags               ; tell emulator we are back
  567.         cmp     vtinited,inited         ; inited emulator yet?
  568.         je      term3                   ; e = yes
  569.         cmp     tekflg,0                ; Tek mode still active?
  570.         jne     term3a                  ; ne = yes, no re-init here
  571.         call    vtinit                  ; init it now
  572.         jmp     term3a
  573. term3:  call    ansrei                  ; reinit the emulator
  574.         call    ansflg                  ; and get its flags
  575. term3a: cmp     flags.modflg,0          ; is mode line disabled?
  576.         je      term2a                  ; e = yes, disabled
  577.         cmp     flags.vtflg,0           ; emulating a terminal?
  578.         jne     term1a                  ; ne = yes, can have mode line
  579.         cmp     trmtyp,0                ; previous terminal type = none?
  580.         jne     term2                   ; ne = no. need to clear mode line.
  581.         jmp     term2a                  ; yes, let 25th line be intact
  582. term1a: test    yflags,modoff           ; is mode line toggled off?
  583.         jnz     term2                   ; nz = yes, clear the line.
  584.         cmp     flags.vtflg,tttek       ; going to be a Tek terminal?
  585.         je      term2a                  ; e = yes, no mode line
  586.         call    modlin                  ; turn on mode line
  587.         jmp     term2a
  588. term2:  call    clrmod                  ; ensure its off
  589. term2a: mov     al,flags.vtflg          ; current terminal type
  590.         mov     trmtyp,al               ; place to remember it til next time
  591.         cmp     flags.vtflg,tttek       ; Tek mode?
  592.         je      term4                   ; e = yes
  593.         cmp     tekflg,0                ; Tek mode active within DEC stuff?
  594.         je      lp                      ; e = no
  595. term4:  call    tekini                  ; reinit to get graphics screen
  596.  
  597. lp:     call    portchr                 ; char at port?
  598.          jnc    chkinp                  ; nc = no, keep going
  599.          nop
  600.         call    outtty                  ; print on terminal
  601. chkinp: call    keybd                   ; call keyboard translator in msu
  602.         jnc     lp                      ; nc = no char or have processed it
  603.                                         ; carry set = quit Connect mode.
  604.  
  605. quit:   call    tekend                  ; [bjh]
  606.         mov     ah,3                    ; get cursor position
  607.         xor     bh,bh                   ; page 0
  608.         int     screen
  609.         mov     cursor,dx               ; save position
  610.         call    savescr                 ; save screen
  611.         cmp     flags.vtflg,0           ; emulating?
  612.         je      quit1                   ; e = no
  613.         mov     ax,0600h                ; clear mode line with old attributes
  614.         mov     bh,oldattr              ; attributes
  615.         mov     dx,low_rgt              ; right most column
  616.         inc     dh                      ; refer to status line
  617.         mov     cx,dx                   ; bottom line [dlk]
  618.         xor     cl,cl                   ; left most column
  619.         int     screen                  ; clear the mode line
  620. quit1:  mov     ah,oldattr              ; attributes at init time
  621.         mov     scbattr,ah              ; background = original state
  622.                                         ; for ega in non-standard # lines
  623.         cmp     ega_mode,0              ; ega board active?
  624.         je      quit2                   ; e = no
  625.         cmp     byte ptr low_rgt+1,23   ; is screen standard length?
  626.         je      quit2                   ; e = yes, so regular cursor set is ok
  627.         push    es                      ; turn off ega cursor emulation
  628.         mov     ax,40h                  ; byte 40:87H is ega Info byte
  629.         mov     es,ax
  630.         push    es:[87h]                ; save info byte around call
  631.         or      byte ptr es:[87h],1     ; set emulation off (low bit = 1)
  632.         mov     cx,lincur               ; cursor shape to set
  633.         mov     ah,1                    ; set the shape
  634.         int     screen                  ;   back to starting value
  635.         pop     es:[87h]                ; recover original Info byte
  636.         pop     es                      ; and our work reg
  637.         jmp     short quit3             ; skip regular mode cursor setting
  638. quit2:                                  ; for regular sized screen
  639.         mov     cx,lincur               ; cursor type at startup
  640.         mov     ah,1
  641.         int     screen                  ; restore cursor type
  642. quit3:  mov     ah,2                    ; Position cursor
  643.         mov     bh,0                    ; Page 0
  644.         mov     dx,low_rgt              ; bottom line
  645.         inc     dh                      ; status line position
  646.         xor     dl,dl                   ; left most column
  647.         int     screen                  ; Do it.
  648.         mov     al,yflags
  649.         mov     bx,argadr
  650.         mov     [bx].flgs,al            ; update flags in arg block
  651.         ret                             ; and return to caller
  652. term    endp
  653.  
  654. ; put the character in al to the screen
  655. outtty  proc    near
  656.         cmp     flags.vtflg,0           ; emulating a terminal?
  657.         jne     outnoc                  ; ne = yes, emulator handles printing
  658.         test    flags.remflg,d8bit      ; keep 8 bits for displays?
  659.         jnz     outnp9                  ; nz = yes, 8 bits if possible
  660.         and     al,7fh                  ; remove high bit
  661. outnp9: cmp     rxtable+256,0           ; translation turned off?
  662.         je      outnp7                  ; e = yes, no translation
  663.         push    bx
  664.         mov     bx,offset rxtable       ; address of translate table
  665.         xlatb                           ; new char is in al
  666.         pop     bx
  667. outnp7: test    anspflg,prtscr          ; should we be printing?
  668.         jz      outnop                  ; no, keep going
  669.         push    ax
  670.         mov     ah,lstout               ; write to system printer device
  671.         mov     dl,al
  672.         int     dos
  673.         pop     ax
  674.         jnc     outnop                  ; nc = successful print
  675.         push    ax
  676.         call    beep                    ; else make a noise and
  677.         call    trnprs                  ;  turn off printing
  678.         pop     ax
  679. outnop: test    yflags,capt             ; capturing output?
  680.         jz      outnoc                  ; no, forget this part
  681.         push    ax                      ; save char
  682.         call    captrtn                 ; give it captured character
  683.         pop     ax                      ; restore character and keep going
  684. outnoc: cmp     tekflg,0                ; Tek mode active?
  685.         jne     outnp6                  ; ne = yes, skip screen rolling
  686.         cmp     vtroll,0                ; auto roll back allowed?
  687.         jz      outnp6                  ; z = no, leave screen as is.
  688.         cmp     bwnd.lcnt,0             ; is screen rolled back? [dlk]
  689.         je      outnp6                  ; e = no
  690.         call    endwnd                  ; restore screen before writing [dlk]
  691. outnp6: cmp     flags.vtflg,0           ; emulating a terminal?
  692.         jnz     outnop1                 ; nz = yup, go do something smart
  693.         test    yflags,trnctl           ; debug? if so use Bios tty mode
  694.         jz      outnp4                  ; z = no
  695.         mov     ah,biostty              ; Bios tty screen write
  696.         cmp     al,7fh                  ; Ascii Del char or greater?
  697.         jb      outnp1                  ; b = no
  698.         je      outnp0                  ; e = Del char
  699.         push    ax                      ; save the char
  700.         mov     al,7eh                  ; output a tilde for 8th bit
  701.         int     screen
  702.         pop     ax                      ; restore char
  703.         and     al,7fh                  ; strip high bit
  704. outnp0: cmp     al,7fh                  ; is char now a DEL?
  705.         jne     outnp1                  ; ne = no
  706.         and     al,3fH                  ; strip next highest bit (Del --> '?')
  707.         jmp     outnp2                  ; send, preceded by caret
  708. outnp1: cmp     al,' '                  ; control char?
  709.         jae     outnp3                  ; ae = no
  710.         add     al,'A'-1                ; make visible
  711. outnp2: push    ax                      ; save char
  712.         mov     al,5eh                  ; caret
  713.         int     screen                  ; display it
  714.         pop     ax                      ; recover the non-printable char
  715. outnp3: int     screen
  716.         ret
  717. outnp4: cmp     al,bell                 ; bell (Control G)?
  718.         jne     outnp5                  ; ne = no
  719.         jmp     beep                    ; use short beep, avoid char loss.
  720. outnp5: mov     dl,al                   ; write without intervention.
  721.         mov     ah,conout
  722.         int     dos                     ; else let dos display char
  723.         ret                             ; and return
  724.  
  725. outnop1:cmp     flags.vtflg,tttek       ; doing Tektronix emulation?
  726.         je      outnop2                 ; e = yes, use Tek emulator
  727.         cmp     tekflg,0                ; Tek submode active?
  728.         jne     outnop2                 ; ne = yes, use Tek emulator
  729.         jmp     anstty                  ; call terminal emulator routine & ret
  730. outnop2:jmp     tekemu                  ; use Tek emulator and return
  731.  
  732. outtty  endp
  733.  
  734. ;[IU2] Here to output character to port with no echo (like escape sequences
  735. ; sent by PF keys, responses to requests from the host, etc.   It is
  736. ; wrong thinking to echo these).
  737.  
  738. prtbout proc    near                    ; Global routine now.
  739.         mov     ah,al                   ; This is where outchr expects it
  740.         call    outchr
  741.          nop                            ; Ignore skip return.
  742.          nop
  743.          nop
  744.         ret
  745. prtbout endp
  746.  
  747.  
  748. ;[IU2] Here to output an unsigned 8-bit number (in al) to the port without
  749. ; echoing. Used by terminal emulator escape sequence output.
  750.  
  751. prtnout proc    near
  752.         mov     bl,10                   ; Output in base 10.
  753.         jmp     prtno2                  ; Ensure at least a zero.
  754.  
  755. prtno1: cmp     al,0
  756.         jne     prtno2                  ; Yes - do more digits
  757.         ret                             ; No - return from recursive call.
  758. prtno2: mov     ah,0                    ; Clear previous remainder.
  759.         div     bl                      ; Divide off a digit
  760.         push    ax                      ; Push remainder (in ah) on stack
  761.         call    prtno1                  ; Recur.
  762.         pop     ax                      ; Pop off a digit
  763.         add     ah,'0'                  ; Make it ASCII
  764.         call    outchr                  ; send to port
  765.          nop
  766.          nop
  767.          nop
  768.         ret
  769. prtnout endp
  770.  
  771. ; send the character in al out to the serial port; handle echoing.
  772. ; Can send an 8 bit char while displaying only 7 bits locally.
  773. outprt  proc    near
  774.         test    yflags,lclecho          ; echoing?
  775.         jz      outpr1                  ; z = no, forget it
  776.         push    ax                      ; save char
  777.         call    outtty                  ; print it
  778.         pop     ax                      ; restore
  779. outpr1: mov     ah,al                   ; this is where outchr expects it
  780.         call    outchr                  ; output to the port
  781.          nop
  782.          nop
  783.          nop                            ; skip returns...
  784.         ret
  785. outprt  endp
  786.  
  787. ; returns with carry on if a character is available
  788.  
  789. portchr proc    near
  790.         call    prtchr                  ; character at port?
  791.          jmp    short portc1            ; yes, go handle
  792.          nop                            ; skip return is stupid...
  793.         clc                             ; no carry -> no character
  794.         ret                             ; and return...
  795. portc1: and     al,parmsk               ; apply 8/7 bit parity mask
  796.         stc                             ; have a character
  797.         ret                             ; and return
  798. portchr endp
  799.  
  800. ;;; Action routines (verbs) for keyboard translator KEYBD in msuibm.
  801. ; These are invoked by a jump instruction. Return carry clear for normal
  802. ; processing, return carry set for invoking Quit (kbdflg has transfer char).
  803. uparrw: mov     al,'A'                  ; cursor keys
  804.         jmp     short comarr
  805. dnarrw: mov     al,'B'
  806.         jmp     short comarr
  807. rtarr:  mov     al,'C'
  808.         jmp     short comarr
  809. lfarr:  mov     al,'D'
  810. comarr: push    ax                      ; save final char
  811.         mov     al,escape               ; Output an escape.
  812.         call    outprt                  ; Output, echo permitted
  813.         cmp     flags.vtflg,tttek       ; Tek terminal?
  814.         je      comar0                  ; e = yes, use VT100 codes
  815.         cmp     flags.vtflg,ttvt100     ; VT100 terminal emulation?
  816.         jne     comar2                  ; No, do VT52/HEATH-19 sequence.
  817. comar0: call    ansflg                  ; Update flags all around.
  818.         mov     al,'['                  ; Maybe this next?
  819.         test    ansflgs,decckm          ; Cursor key mode reset?
  820.         je      comar1                  ; Yes, output the "["
  821.         mov     al,'O'                  ; No, set, use the "O".
  822. comar1: call    outprt                  ; Output it (echo permitted).
  823. comar2: pop     ax                      ; recover final char
  824.         call    outprt                  ; Output to port (echo permitted)
  825.         clc
  826.         ret
  827.  
  828. pf1:    mov     al,'P'                  ; keypad function keys 1-4
  829.         jmp     short compf
  830. pf2:    mov     al,'Q'
  831.         jmp     short compf
  832. pf3:    mov     al,'R'
  833.         jmp     short compf
  834. pf4:    mov     al,'S'
  835. compf:  push    ax                      ; save final char
  836.         mov     al,escape               ; Output an escape.
  837.         call    prtbout
  838.         call    ansflg                  ; get emulator flags
  839.         test    ansflgs,decanm          ; ansi mode?
  840.         jz      short compf1            ; z = no
  841.         mov     al,'O'                  ; send an "O".
  842.         call    prtbout                 ; Output it.
  843. compf1: pop     ax                      ; Get the saved char back
  844.         call    prtbout                 ; Output to port
  845.         clc
  846.         ret
  847.  
  848. kp0:    mov     al,'p'                  ; keypad numeric keys
  849.         jmp     short comkp
  850. kp1:    mov     al,'q'
  851.         jmp     short comkp
  852. kp2:    mov     al,'r'
  853.         jmp     short comkp
  854. kp3:    mov     al,'s'
  855.         jmp     short comkp
  856. kp4:    mov     al,'t'
  857.         jmp     short comkp
  858. kp5:    mov     al,'u'
  859.         jmp     short comkp
  860. kp6:    mov     al,'v'
  861.         jmp     short comkp
  862. kp7:    mov     al,'w'
  863.         jmp     short comkp
  864. kp8:    mov     al,'x'
  865.         jmp     short comkp
  866. kp9:    mov     al,'y'
  867.         jmp     short comkp
  868. kpminus:mov     al,'m'
  869.         jmp     short comkp
  870. kpcoma: mov     al,'l'
  871.         jmp     short comkp
  872. kpenter:mov     al,'M'
  873.         jmp     short comkp
  874. kpdot:  mov     al,'n'
  875. comkp:  test    ansflgs,deckpam         ; keypad application mode active?
  876.         jnz     comkp3                  ; nz = yes, use escape sequences
  877.         sub     al,40h                  ; deduct offset to numeric symbols
  878.         jmp     comkp0                  ; and send that single char
  879. comkp3: push    ax                      ; save final char
  880.         mov     al,escape               ; Output an escape.
  881.         call    prtbout
  882.         mov     al,'O'                  ; Output the "O"
  883.         cmp     flags.vtflg,ttvt100     ; VT100 mode?
  884.         je      comkp1                  ; e = yes, use "O" code
  885.         cmp     flags.vtflg,tttek       ; Tek terminal
  886.         je      comkp1                  ; e = yes, use VT100 codes
  887.         test    ansflgs,decanm          ; ANSI (alt application keypad) mode?
  888.         jnz     comkp1                  ; nz = yes, use "O"
  889. comkp2: mov     al,'?'                  ; else use "?" instead of "O".
  890. comkp1: call    prtbout
  891.         pop     ax                      ; recover final char
  892. comkp0: call    prtbout                 ; send it
  893.         clc
  894.         ret
  895. klogon  proc    near                    ; resume logging (if any)
  896.         test    flags.capflg,logses     ; session logging enabled?
  897.         jz      klogn                   ; z = no, forget it
  898.         or      argadr.flgs,capt        ; turn on capture flag
  899.         or      yflags,capt             ; set local msy flag as well
  900.         call    ansflg                  ; tell emulator
  901. klogn:  clc
  902.         ret
  903. klogon  endp
  904.  
  905. klogof  proc    near                    ; suspend logging (if any)
  906.         and     argadr.flgs,not capt    ; stop capturing
  907.         and     yflags,not capt         ; reset local msy flag as well
  908.         call    ansflg                  ; tell emulator
  909. klogo:  clc
  910.         ret
  911. klogof  endp
  912.  
  913. snull   proc    near                    ; send a null byte
  914.         mov     al,0                    ; the null
  915.         call    prtbout                 ; send without logging and local echo
  916.         clc
  917.         ret
  918. snull   endp
  919.                                         ; general character out for emulator
  920. chrout: cmp     flags.vtflg,0           ; emulating?
  921.         je      chrou5                  ; e = no
  922.         call    anskbi                  ; Yes, say we had keyboard input.
  923.         cmp     al,cr                   ; A CR?
  924.         jne     chrou5                  ; No - just output it and return
  925.         call    ansflg                  ; Yes - update VT100 flags
  926.         test    ansflgs,anslnm          ; ANSI new-line mode set?
  927.         jz      chrou5                  ; No - just send the cr
  928.         call    outprt                  ; Yes - output a carriage-return
  929.         mov     al,lf                   ; Followed by a line feed.
  930. chrou5: call    outprt
  931.         clc
  932.         ret
  933.  
  934.                                         ; these commands invoke Quit
  935. cdos:   mov     al,'P'                  ; Push to DOS
  936.         jmp     short cmdcom
  937. cstatus:mov     al,'S'                  ; Status
  938.         jmp     short cmdcom
  939. cquit:  mov     al,'C'                  ; Exit Connect mode
  940.         jmp     short cmdcom
  941. cquery: mov     al,'?'                  ; Help
  942.         jmp     short cmdcom
  943. chang:  mov     al,'H'                  ; Hangup, drop DTR & RTS
  944.         jmp     short cmdcom
  945. cmdcom: mov     kbdflg,al               ; pass char to msster.asm via kbdflg
  946.         stc                             ; signal that Quit is needed
  947.         ret
  948.  
  949. dmpscn  proc    near                    ; dump screen to file
  950.         call    savescr                 ; save screen to buffer
  951.         call    dumpscr                 ; do buffer to file
  952.         clc                             ; do not exit Connect mode
  953.         ret
  954. dmpscn  endp
  955.  
  956.  
  957. ;[IU2] Routine to toggle VT100/VT52/Heath-19 modes in VT100 emulator.
  958.  
  959. vtans52 proc    near
  960.         cmp     flags.vtflg,0           ; emulating?
  961.         je      vtans5                  ; e = no
  962.         call    ans52t                  ; Call MSZ toggle-it routine.
  963.         call    ansflg                  ; Update flags.
  964.         clc                             ; clear c bit so don't exit Connect.
  965. vtans5: ret
  966. vtans52 endp
  967.                                         ; Toggle Mode Line
  968. trnmod: cmp     flags.modflg,0          ; is mode line enabled?
  969.         je      trnm2                   ; e = no, don't touch it
  970.         cmp     flags.vtflg,tttek       ; Tek mode?
  971.         je      trnm2                   ; yes
  972.         cmp     tekflg,0                ; Tek submode?
  973.         jne     trnm2                   ; ne = yes, no mode line changes
  974.         test    yflags,modoff           ; mode line already off?
  975.         jnz     trnm1                   ; yes, go turn on
  976.         call    clrmod                  ; no, clear mode line here
  977.         or      yflags,modoff           ; turn on flag
  978.         call    ansflg                  ; Update flags all around.
  979.         clc                             ; clear c bit so don't exit Connect
  980.         ret                             ; and return
  981. trnm1:  and     yflags,not modoff       ; Clear flag first.
  982.         call    modlin                  ; Then turn on mode line.
  983.         call    ansflg                  ; Update flags all around.
  984. trnm2:  clc
  985.         ret
  986.  
  987. trnprs: push    ax                      ; toggle ^ PrtSc screen to printer
  988.         test    anspflg,prtscr          ; are we currently printing?
  989.         jnz     trnpr2                  ; nz = yes, its on and going off
  990.         mov     ah,ioctl
  991.         mov     al,7                    ; get output status of printer
  992.         push    bx
  993.         mov     bx,4                    ; file handle for system printer
  994.         int     dos
  995.         pop     bx
  996.         jc      trnpr1                  ; c = printer not ready
  997.         cmp     al,0ffh                 ; Ready status?
  998.         je      trnpr2                  ; e = Ready
  999. trnpr1: call    beep                    ; Not Ready, complain
  1000.         jmp     trnpr3                  ; and ignore request
  1001. trnpr2: xor     anspflg,prtscr          ; flip the flag
  1002.         test    yflags,modoff           ; mode line off?
  1003.         jnz     trnpr3                  ; nz = yes
  1004.         call    modlin                  ; else rewrite mode line
  1005. trnpr3: pop     ax
  1006.         clc                             ; return carry clear (don't quit)
  1007.         ret
  1008.  
  1009. ;;;;; General screen management routines for IBM PC
  1010.  
  1011. ; computes screen location to ax, given row and col in [dh,dl], resp.
  1012. ; trashes dx
  1013. scrloc  proc    near
  1014.         mov     al,dh                   ; get row
  1015.         xor     ah,ah                   ; clear ah
  1016.         mul     crt_cols                ; multiply by number of columns
  1017.         xor     dh,dh                   ; clear row
  1018.         add     ax,dx                   ; this is current position
  1019.         shl     ax,1                    ; double for attributes
  1020.         ret
  1021. scrloc  endp
  1022.  
  1023. ; Routine to set cursor type.  Pass cursor type in al: 0 = No cursor,
  1024. ; 1 = Underline cursor, 2 = Block cursor.   All cursors blink due to hardware.
  1025. ; Routine frags any ac that video ints frag.
  1026. ; For EGA boards running in non-25 line mode the cursor emulation is turned
  1027. ; off during cursor shape changing and restored afterward. It's another
  1028. ; ega Feature. [jrd]
  1029. csrtype proc    near
  1030.         push    cx                      ; save the reg
  1031.         mov     ah,1                    ; Video fxn for set cursor type
  1032.         mov     cx,0F00H                ; Assume no cursor
  1033.         cmp     al,0                    ; No cursor?
  1034.         je      csrty2                  ; Right - set it and be done with it.
  1035.         cmp     crt_mode,7              ; B&W card?
  1036.         je      csrty3                  ; Yes - different sizes
  1037.         mov     cx,0607H                ; No, use CGA underline cursor
  1038.         cmp     al,2                    ; Block?
  1039.         jne     csrty2                  ; No - set it now.
  1040. csrty1: xor     ch,ch                   ; Yes - make it a block
  1041. csrty2: cmp     ega_mode,0              ; ega board active?
  1042.         je      csrty4                  ; e = no
  1043.         cmp     byte ptr low_rgt+1,23   ; standard screen length?
  1044.         je      csrty4                  ; e = yes, use regular cursor setting
  1045.         push    es                      ; EGA. turn off cursor emulation
  1046.         mov     ax,40h                  ; 40:87h is ega Info byte
  1047.         mov     es,ax
  1048.         push    es:[87h]                ; save Info byte around call
  1049.         or      byte ptr es:[87h],1     ; set emulation off (low bit = 1)
  1050.         mov     ah,1                    ; Video fxn for set cursor type
  1051.         int     screen
  1052.         pop     es:[87h]                ; restore Info byte
  1053.         pop     es                      ;  and our work register
  1054.         pop     cx
  1055.         ret
  1056. csrty4: int     screen                  ; regular cursor shape setting
  1057.         pop     cx
  1058.         ret
  1059. csrty3: mov     cx,0B0CH                ; Assume B&W underline cursor
  1060.         cmp     al,2                    ; Block?
  1061.         jne     csrty2                  ; No - set it now.
  1062.         jmp     csrty1                  ; Yes - make it a block
  1063. csrtype endp
  1064.  
  1065.  
  1066. ; Save the entire screen in a buffer so we can restore and/or dump it.
  1067. ; Saves regular (80x25) screens to memory buffer scrsav and other sized
  1068. ; screens to video memory page 1. Resultant save place put into savadr
  1069. ; (offset then segment) and current low_rgt size info in savflg. Note,
  1070. ; some Environments (TopView/Windows etc) may not permit use of page 1. [jrd]
  1071. savescr proc    near
  1072.         push    es
  1073.         push    ds
  1074.         push    ax
  1075.         push    cx
  1076.         push    si
  1077.         push    di
  1078.         call    scrseg                  ; get screen segment in ax and es:di
  1079.         push    ax                      ; save screen segment
  1080.         mov     si,0
  1081.         mov     di,scrsav               ; place to put screen (memory buff)
  1082.         mov     savadr+2,di             ; working seg address for restore
  1083.         mov     savadr,0                ; and no offset for memory buffer
  1084.  
  1085.         call    scrmod                  ; ascertain video mode and screen
  1086.         mov     ax,low_rgt              ; text screen lower right (typ 23,79)
  1087.         mov     savflg,ax               ; save it for screen restore
  1088.         inc     al                      ; number of columns
  1089.         add     ah,2                    ;  plus status line = number of rows
  1090.         cmp     al,swidth               ; same as preset screen space (80)?
  1091.         ja      savsc1                  ; a = no, use screen video page 1
  1092.         cmp     ah,slen+1               ; same as preset screen length (24)?
  1093.         je      savsc3                  ; e = yes, use our memory buffer
  1094. savsc1: mul     ah                      ; times rows = characters on screen
  1095.         shl     ax,1                    ; times two for attributes = page 1
  1096.         mov     cx,ax                   ; cx = working copy of screen size
  1097.         and     cx,000fh                ; get lower four bits for offset part
  1098.         mov     savadr,cx               ; save offset in this word
  1099.         mov     cl,4
  1100.         shr     ax,cl                   ; compute number of paragraphs
  1101.         pop     di                      ; source screen address
  1102.         push    di                      ; restore again
  1103.         add     di,ax                   ; add paragraphs, point di to page 1
  1104.         mov     savadr+2,di             ; and save segment in this word
  1105. savsc3:
  1106.         mov     es,savadr+2             ; segment of storage area
  1107.         mov     di,savadr               ;  offset of same
  1108.         mov     ax,low_rgt              ; lower right of text screen
  1109.         inc     al                      ; number of columns on screen
  1110.         add     ah,2                    ; number of rows on screen
  1111.         mul     ah                      ; number of characters on the screen
  1112.         mov     cx,ax                   ; save this in counter cx
  1113.         call    scroff                  ; turn off screen [dt]
  1114.         pop     ds                      ; address screen
  1115.         cld
  1116.         rep     movsw                   ; save the screen
  1117.         pop     di
  1118.         pop     si
  1119.         pop     cx
  1120.         pop     ax
  1121.         pop     ds                      ; restore this
  1122.         call    scron                   ; turn on screen [dt]
  1123.         pop     es
  1124.         ret
  1125. savescr endp
  1126.  
  1127. ; restore screen from buffer (offset and seg in savadr, text coord in savflg).
  1128. ; Restores all screen lines. [jrd]
  1129. restscr proc    near
  1130.         push    es
  1131.         mov     ax,savflg               ; saved low_rgt text screen coord
  1132.         add     ah,2                    ; number of screen lines
  1133.         inc     al                      ; number of screen columns
  1134.         mul     ah                      ; columns time lines = # characters
  1135.         mov     cx,ax                   ; save this in counter cx
  1136.         push    cx                      ; save count
  1137.         call    scrseg                  ; get address of screen in es:di
  1138.         call    scroff                  ; turn off screen [dt]
  1139.         push    ds                      ; save original data segment
  1140.         mov     si,savadr               ; offset of storage area
  1141.         push    savadr+2                ; segment of same
  1142.         pop     ds                      ; put storage segment into ds
  1143.         cld
  1144.         rep     movsw                   ; restore data to screen
  1145.         pop     ds                      ; recover original data segment
  1146.         call    scron                   ; turn on screen [dt]
  1147.         pop     cx                      ; recover count
  1148.         call    scrsync                 ; synch Topview with new screen
  1149.         pop     es
  1150.         ret
  1151. restscr endp
  1152.  
  1153. ; Save the screen to a buffer and then append buffer to a disk file. [jrd]
  1154. ; Default filename is Kermit.scn; actual file can be a device too. Filename
  1155. ; is determined by mssset and is passed as pointer dmpname.
  1156. ; Dumpscr reads the screen image saved by savescr so call savescr call first.
  1157.  
  1158. dumpscr proc    near
  1159.         push    ax
  1160.         push    bx
  1161.         push    cx
  1162.         push    dx
  1163.         mov     dmphand,-1              ; preset illegal handle
  1164.         mov     dx,offset dmpname       ; name of disk file, from mssset
  1165.         mov     ax,dx                   ; where isfile wants name ptr
  1166.         call    isfile                  ; what kind of file is this?
  1167.         jc      dmp5                    ; c = no such file, create it
  1168.         test    byte ptr filtst.dta+21,1fh ; file attributes, ok to write?
  1169.         jnz     dmp0                    ; nz = no.
  1170.         mov     al,1                    ; writing
  1171.         mov     ah,open2                ; open existing file
  1172.         int     dos
  1173.         jc      dmp0                    ; c = failure
  1174.         mov     dmphand,ax              ; save file handle
  1175.         mov     bx,ax                   ; need handle here
  1176.         mov     cx,0ffffh               ; setup file pointer
  1177.         mov     dx,-1                   ; and offset
  1178.         mov     al,2                    ; move to eof minus one byte
  1179.         mov     ah,lseek                ; seek the end
  1180.         int     dos
  1181.         jmp     dmp1
  1182.  
  1183. dmp5:   test    filtst.fstat,80h        ; access problem?
  1184.         jnz     dmp0                    ; nz = yes
  1185.         mov     ah,creat2               ; file did not exist
  1186.         mov     cx,20h                  ; attributes, archive bit
  1187.         int     dos
  1188.         mov     dmphand,ax              ; save file handle
  1189.         jnc     dmp1                    ; nc = ok
  1190.  
  1191. dmp0:   mov     ah,3                    ; get cursor position
  1192.         xor     bx,bx                   ; page 0
  1193.         int     screen
  1194.         push    dx                      ; save it
  1195.         mov     dh,byte ptr low_rgt+1   ; go to status line
  1196.         inc     dh
  1197.         xor     dl,dl                   ; left most column
  1198.         mov     ah,2                    ; position cursor
  1199.         int     screen
  1200.         mov     dx,offset dmperr        ; say no can do
  1201.         mov     ah,prstr
  1202.         int     dos
  1203.         pop     dx                      ; get original cursor position
  1204.         mov     ah,2                    ; position cursor
  1205.         xor     bx,bx                   ; page 0
  1206.         int     screen
  1207.         pop     dx
  1208.         pop     cx
  1209.         pop     bx
  1210.         pop     ax
  1211.         clc
  1212.         ret
  1213.  
  1214. dmp1:   mov     ah,ioctl                ; is destination ready for output?
  1215.         mov     al,7                    ; test output status
  1216.         mov     bx,dmphand              ; handle
  1217.         int     dos
  1218.         jc      dmp0                    ; c = error
  1219.         cmp     al,0ffh                 ; ready?
  1220.         jne     dmp0                    ; ne = not ready.
  1221.         push    di                      ; read screen buffer, write lines
  1222.         push    si
  1223.         push    es
  1224.         mov     cl,byte ptr low_rgt+1   ; number of lines - 2
  1225.         add     cl,2                    ; number of line on screen
  1226.         xor     ch,ch
  1227.         mov     si,savadr               ; offset in storage area
  1228. dmp2:   push    cx                      ; save outer loop counter
  1229.         mov     es,savadr+2             ; get storage segment
  1230.         mov     di,offset dumpbuf       ; data segment memory
  1231.         mov     cl,byte ptr savflg      ; number of columns on screen - 1
  1232.         inc     cl                      ; number of columns on screen
  1233.         xor     ch,ch
  1234. dmp3:   mov     ax,word ptr es:[si]     ; read char + attribute
  1235.         mov     byte ptr [di],al        ; store just char, don't use es:
  1236.         inc     si                      ; update pointers
  1237.         inc     si
  1238.         inc     di
  1239.         loop    dmp3                    ; do for each column
  1240.         std                             ; set scan backward
  1241.         mov     cl,byte ptr savflg      ; number of columns on screen - 1
  1242.         inc     cl                      ; number of columns on screen
  1243.         xor     ch,ch
  1244.         push    es
  1245.         mov     ax,ds
  1246.         mov     es,ax                   ; set es to data segment for es:di
  1247.         mov     di,offset dumpbuf       ; start of line
  1248.         add     di,cx                   ; plus length of line
  1249.         dec     di                      ; minus 1 equals end of line
  1250.         mov     al,' '                  ; thing to scan over
  1251.         repe    scasb                   ; scan until non-space
  1252.         cld                             ; set direction forward
  1253.         pop     es
  1254.         jz      dmp3a                   ; z = all spaces
  1255.         inc     cx
  1256.         inc     di
  1257. dmp3a:  mov     word ptr [di+1],0A0Dh   ; append cr/lf
  1258.         add     cx,2                    ; line count + cr/lf
  1259.         mov     dx,offset dumpbuf       ; array to be written
  1260.         mov     bx,dmphand              ; need file handle
  1261.         mov     ah,write2               ; write the line
  1262.         int     dos
  1263.         pop     cx                      ; get line counter again
  1264.         jc      dmp3b                   ; c = error
  1265.         loop    dmp2                    ; do next line
  1266.         mov     dx,offset dumpsep       ; put in formfeed/cr/lf
  1267.         mov     cx,3                    ; three bytes overall
  1268.         mov     ah,write2               ; write them
  1269. dmp3b:  mov     bx,dmphand              ; file handle
  1270.         int     dos
  1271.         mov     ah,close2               ; close the file now
  1272.         int     dos
  1273. dmp6:   pop     es
  1274.         pop     si
  1275.         pop     di
  1276.         pop     dx
  1277.         pop     cx
  1278.         pop     bx
  1279.         pop     ax
  1280.         clc
  1281.         ret
  1282. dumpscr endp
  1283.  
  1284.  
  1285. ; Get CRT mode - returns mode in variable crt_mode,
  1286. ; updates crt_cols and low_rgt.
  1287. ; For EGA active it looks in Bios work memory 40:84H for number of rows. [jrd]
  1288. scrmod  proc    near
  1289.         push    ax
  1290.         push    dx
  1291.         mov     ah,15                   ; Get current video state.
  1292.         int     screen
  1293.         mov     crt_mode,al             ; Store CRT mode value.
  1294.         mov     crt_cols,ah             ; store # of cols
  1295.         mov     dl,ah                   ; # of cols again
  1296.         mov     dh,crt_lins             ; and # of rows (constant from msster)
  1297.         cmp     ega_mode,0              ; ega active?
  1298.         je      scrmod4                 ; e = no
  1299.         push    es                      ; yes, permit different lengths
  1300.         mov     ax,40h                  ; refer to 40:84h for # ega rows
  1301.         mov     es,ax
  1302.         mov     ah,es:[84h]             ; get number of rows - 1 (typ 24)
  1303.         cmp     ah,20                   ; less than 20 rows?
  1304.         jb      scrmod3                 ; b = yes, ignore this length
  1305.         cmp     ah,80                   ; more than 80 rows?
  1306.         ja      scrmod3                 ; a = yes, ignore this length
  1307.         mov     dh,ah                   ; use this length
  1308.         mov     crt_lins,dh             ; update our working constant
  1309. scrmod3:pop     es
  1310. scrmod4:
  1311.         dec     dl                      ; max text column, count from zero
  1312.         dec     dh                      ; max text row, count from zero
  1313.         mov     low_rgt,dx              ; save away window address
  1314.         pop     dx
  1315.         pop     ax
  1316.         ret                             ; And return.
  1317. scrmod  endp
  1318.  
  1319.  
  1320. ; Get screen segment - returns screen segment in ax, and full address in es:di
  1321.  
  1322. scrseg  proc    near
  1323.         xor     di,di                   ; start at beginning of screen (0,0)
  1324.         mov     ax,0B000H               ; Assume B&W card..
  1325.         cmp     crt_mode,7              ; Is it?
  1326.         je      scrse1                  ; e = yes
  1327.         mov     ax,0B800H               ; No - video memory is here on color
  1328.         cmp     crt_mode,12             ; graphics set?
  1329.         jb      scrse1                  ; b = no
  1330.         mov     ax,0A000H               ; graphics
  1331. scrse1: mov     es,ax           ; tell Topview our hardware address needs
  1332.         mov     tv_segs,es              ; save our hardware screen address
  1333.         mov     tv_sego,di              ; segment and offset form
  1334.         mov     tv_mode,1               ; assume we're running under Topview
  1335.         mov     ah,tvhere               ; query Topview for its presence
  1336.         int     screen
  1337.         mov     ax,es                   ; get its new segment for screen work
  1338.         cmp     ax,tv_segs              ; same as hardware?
  1339.         jne     scrse2                  ; ne = no, we are being mapped
  1340.         cmp     di,tv_sego              ; check this too.
  1341.         jne     scrse2          ; ne = no too. Use TV's work buf as screen.
  1342.         mov     tv_mode,0               ; else no Topview or no mapping.
  1343. scrse2: ret
  1344. scrseg  endp
  1345.  
  1346. ; Synchronize a Topview provided virtual screen buffer with the image
  1347. ; seen by the user. Requires cx = number of words written to screen
  1348. ; (char & attribute bytes) and es:di = ENDING address of screen write.
  1349. ; Changes ax and di.
  1350. scrsync proc    near
  1351.         cmp     tv_mode,0               ; Topview mode active?
  1352.         je      scrsyn1                 ; e = no, skip DOS call below
  1353.         sub     di,cx                   ; backup to start byte (cx = words)
  1354.         sub     di,cx                   ;  after storing words to screen
  1355.         mov     ah,tvsynch              ; tell Topview we have changed screen
  1356.         int     screen                  ;  so user sees updated screen
  1357. scrsyn1:ret
  1358. scrsync endp
  1359.  
  1360. ; The following two routines are used to turn off the display while we
  1361. ; are reading or writing the screen in one of the color card modes.
  1362. ; Turn screen off for (known) color card modes only. All regs preserved.
  1363. ; Includes code for old procedure scrwait. 16 June 1987 [jrd]
  1364. scroff  proc    near
  1365.         cmp     refresh,0               ; slow refresh?
  1366.         jne     scrofx                  ; ne = no wait
  1367.         cmp     ega_mode,0              ; Extended Graphics Adapter in use?
  1368.         jne     scrofx                  ; ne = yes, no waiting.
  1369.         cmp     tv_mode,0               ; Topview mode?
  1370.         jne     scrofx                  ; ne = yes, no waiting
  1371.         cmp     crt_mode,7              ; B&W card?
  1372.         jnb     scrofx                  ; Yes - just return.
  1373.         push    ax                      ; Save ax and dx.
  1374.         push    dx
  1375.         mov     dx,crt_status           ; CGA: Wait for vertical retrace
  1376. scrof1: in      al,dx
  1377.         test    al,disp_enb             ; display enabled?
  1378.         jnz     scrof1                  ; yes, keep waiting
  1379. scrof2: in      al,dx
  1380.         test    al,disp_enb             ; now wait for it to go off
  1381.         jz      scrof2                  ; so can have whole cycle
  1382.         mov     dx,crtmset              ; Output to CRT mode set port.
  1383.         mov     al,25H                  ; This shuts down the display
  1384.         out     dx,al                   ; Dumb, but card is too..
  1385.         pop     dx                      ; Restore acs.
  1386.         pop     ax
  1387. scrofx: ret                             ; And return.
  1388. scroff  endp
  1389.  
  1390.  
  1391. ; Turn screen on for (known) color card modes only
  1392. ; All registers are preserved.
  1393.  
  1394. scron   proc    near
  1395.         cmp     refresh,0               ; slow refresh?
  1396.         jne     scronx                  ; ne = no wait
  1397.         cmp     ega_mode,0              ; Extended Graphics Adapter in use?
  1398.         jne     scronx                  ; ne = yes, no waiting.
  1399.         cmp     tv_mode,0               ; Topview mode?
  1400.         jne     scronx                  ; ne = yes, no waiting
  1401.         cmp     crt_mode,7              ; B&W card?
  1402.         jnb     scronx                  ; Yes - just return.
  1403.         push    ax                      ; Save ax, dx, and si
  1404.         push    dx
  1405.         push    si
  1406.         mov     al,crt_mode             ; Convert crt_mode to a word
  1407.         xor     ah,ah
  1408.         mov     si,ax                   ; Get it in a usable register
  1409.         mov     al,msets[si]            ; Fetch the modeset byte
  1410.         mov     dx,crtmset              ; This port
  1411.         out     dx,al                   ; Flash it back on
  1412.         pop     si                      ; Restore acs.
  1413.         pop     dx
  1414.         pop     ax
  1415. scronx: ret                             ; And return.
  1416. scron   endp
  1417.  
  1418.  
  1419. ; Screen clearing routine. [IU]
  1420. ;
  1421. ; Call:         ax/     coordinates of first screen location to be cleared.
  1422. ;               bx/     coordinates of last location to be cleared.
  1423. ; Coord: ah = row [0-24], al = column [0-79]. Preserves all registers. [jrd]
  1424.  
  1425. atsclr: push    ax                      ; Save some acs
  1426.         push    cx
  1427.         push    dx
  1428.         mov     dx,bx                   ; Compute last screen offset in ax
  1429.         push    ax
  1430.         call    scrmod                  ; update column length
  1431.         pop     ax                      ; scrmod zaps ax
  1432.         push    ax
  1433.         call    scrloc                  ; get screen start address in ax
  1434.         mov     cx,ax                   ; Save it in cx for a minute
  1435.         pop     dx                      ; Compute first screen offset in ax
  1436.         call    scrloc
  1437.         sub     cx,ax                   ; Compute number of locs to clear...
  1438.         add     cx,2
  1439.         sar     cx,1                    ; Make byte count a word count
  1440.         jle     atscl2                  ; If nothing to clear, then vamos.
  1441.         push    di                      ; Save some more acs
  1442.         push    es                      ; save es
  1443.         push    ax                      ; save around call
  1444.         call    scrseg                  ; Get address of screen in ax, es:di
  1445.         pop     ax                      ; recover displacement
  1446.         add     di,ax                   ; displacement memory address
  1447.         mov     ah,scbattr              ; Use current screen background attr.
  1448.         mov     al,' '                  ; Use space for fill
  1449.         mov     dl,byte ptr low_rgt     ; line length - 1
  1450.         inc     dl                      ; line length
  1451.         xor     dh,dh
  1452.         cmp     cx,dx                   ; Blanking a line or less??
  1453.         jg      atscl1                  ; No - make scroff disable display
  1454. atscl1: call    scroff                  ; Turn screen off if color card.
  1455.         push    cx                      ; save word count for Topview
  1456.         cld
  1457.         rep     stosw                   ; Blit... (excuse PDP-10ese please)
  1458.         pop     cx                      ; recover word count
  1459.         call    scrsync                 ; synch Topview
  1460.         call    scron                   ; Turn screen back on if color card.
  1461.         pop     es                      ; Restore segment register
  1462.         pop     di                      ; And destination index
  1463. atscl2: pop     dx                      ; restore regs
  1464.         pop     cx
  1465.         pop     ax
  1466.         ret
  1467.  
  1468. ; Scrolling routines.  vtscru scrolls up one row, vtscrd scrolls down one
  1469. ; row.  atsprep is called before scrolling up to save the top line in the
  1470. ; circular buffer. All registers are preserved.
  1471.  
  1472. ; Screen-roll down. Move text down one line, for terminal emulator only.
  1473.  
  1474. vtscrd: push    ax                      ; Upgraded by [jrd]
  1475.         push    bx
  1476.         push    cx
  1477.         push    dx
  1478.         mov     ax,701H                 ; scroll down one line
  1479.         mov     ch,mar_top              ; top margin line
  1480.         mov     cl,0                    ; left most column
  1481.         mov     dh,mar_bot              ; bottom margin line
  1482.         mov     dl,byte ptr low_rgt     ; right most column
  1483.         mov     bh,scbattr              ; attributes
  1484.         int     screen                  ; scroll it down
  1485.         pop     dx
  1486.         pop     cx
  1487.         pop     bx
  1488.         pop     ax
  1489.         clc
  1490.         ret
  1491.                                         ; worker routine for vtscru/d
  1492. atsprep:push    es                      ; upgraded from older version  [jrd]
  1493.         call    scroff                  ; turn off color screen
  1494.         call    scrseg                  ; get display address in es:di
  1495.         mov     si,di                   ; si will be source
  1496.         mov     bx,offset twnd          ; this is where it goes
  1497.         call    putcirc                 ; put screen line in circular buffer
  1498.         pop     es                      ; and that
  1499.         call    scron                   ; turn on screen again
  1500.         ret                             ; and return
  1501.  
  1502.  
  1503. ; Screen scroll up one line (text moves up) for terminal emulator use.
  1504.  
  1505. vtscru: push    ax                      ; Upgraded by  [jrd]
  1506.         push    bx
  1507.         push    cx
  1508.         push    dx
  1509.         push    si
  1510.         push    di
  1511.         cmp     mar_top,0               ; scrolling the top screen line?
  1512.         ja      scru1                   ; a = no. don't save anything
  1513.         call    atsprep                 ; save top line
  1514. scru1:  mov     ax,601H                 ; scroll up one line
  1515.         mov     dh,mar_bot              ; bottom row
  1516.         mov     dl,byte ptr low_rgt     ; right most column
  1517.         mov     ch,mar_top              ; top row of scrolling region
  1518.         mov     cl,0                    ; left most column
  1519.         mov     bh,scbattr              ; background attributes
  1520.         int     screen                  ; scroll up that region
  1521.         pop     di                      ; Restore the rest of the regs.
  1522.         pop     si
  1523.         pop     dx
  1524.         pop     cx
  1525.         pop     bx
  1526.         pop     ax
  1527.         clc
  1528.         ret                             ; And return
  1529.  
  1530. ;screen text roll up, version for manual scrolling only
  1531.  
  1532. mscru:  push    ax                      ; Upgraded by  [jrd]
  1533.         push    bx
  1534.         push    cx
  1535.         push    dx
  1536.         push    si
  1537.         push    di
  1538.         cmp     bwnd.lcnt,0             ; any lines in bottom window?
  1539.         je      mscru2                  ; e = no, so ignore request
  1540.         call    atsprep                 ; save top line
  1541. mscru1: mov     ax,601H                 ; scroll up one line
  1542.         mov     dx,low_rgt              ; lower right corner
  1543.         xor     cx,cx                   ; top row of scrolling region
  1544.         mov     bh,scbattr              ; background attributes
  1545.         int     screen                  ; scroll up that region
  1546.         call    scroff
  1547.         mov     dx,low_rgt
  1548.         mov     dl,0                    ; location is lower left corner
  1549.         call    scrloc                  ; get count from display start
  1550.         push    es
  1551.         push    ax                      ; save count
  1552.         call    scrseg                  ; get screen's segment into ax, es:di
  1553.         pop     ax                      ; recover count
  1554.         add     di,ax                   ; destination memory address (es:di)
  1555.         mov     bx,offset bwnd          ; source of lines
  1556.         call    getcirc                 ; get line from circ buf to screen
  1557.         pop     es                      ; restore es
  1558.         call    scron                   ; turn on the screen
  1559. mscru2: pop     di                      ; Restore the rest of the regs.
  1560.         pop     si
  1561.         pop     dx
  1562.         pop     cx
  1563.         pop     bx
  1564.         pop     ax
  1565.         ret
  1566.  
  1567.  
  1568. ; prep for screen scroll down.
  1569. ; copies bottom scroll line from screen to bottom window buffer.
  1570. ; destroys ax,cx,dx,si,di.
  1571. getbot proc near                        ; Upgraded from old version [jrd]
  1572.         push    es
  1573.         call    scroff                  ; turn off screen
  1574.         mov     dx,low_rgt              ; from screen location, row
  1575.         mov     dl,0                    ; starting in col 0
  1576.         call    scrseg                  ; get adaptor's offset into es:di
  1577.         call    scrloc                  ; get offset in display buffer in ax
  1578.         add     di,ax                   ; source addr in display buffer es:di
  1579.         mov     si,di                   ; screen is source (si)
  1580.         mov     bx,offset bwnd          ; buffer to use (bottom window)
  1581.         call    putcirc                 ; copy bottom screen line to circ buf
  1582.         pop     es
  1583.         call    scron                   ; turn on display again
  1584.         ret
  1585. getbot endp
  1586.  
  1587. ;screen text scroll down, for manual mode only
  1588. mscrd:  push    ax                      ; Upgraded by [jrd]
  1589.         push    bx
  1590.         push    cx
  1591.         push    dx
  1592.         push    si
  1593.         push    di
  1594.         cmp     twnd.lcnt,0             ; any lines left in top window?
  1595.         je      mscrd1                  ; e = no, ingore request
  1596.         call    getbot                  ; fetch bottom line from screen
  1597.         mov     ax,701H                 ; scroll down one line
  1598.         xor     cx,cx                   ; top left corner
  1599.         mov     dx,low_rgt              ; bottom right corner
  1600.         mov     bh,scbattr              ; attributes
  1601.         int     screen                  ; scroll it down
  1602.         call    scroff                  ; turn off display
  1603.         push    es
  1604.         call    scrseg                  ; get segment address of screen
  1605.         mov     bx,offset twnd          ; buffer to use (top window)
  1606.         call    getcirc                 ; copy from circ buf to screen
  1607.         pop     es
  1608.         call    scron                   ; turn on display again
  1609. mscrd1: pop     di                      ; Restore the rest of the ACs.
  1610.         pop     si
  1611.         pop     dx
  1612.         pop     cx
  1613.         pop     bx
  1614.         pop     ax
  1615.         ret
  1616.  
  1617. ; move viewing window down as much as possible (text moves up)
  1618. endwnd  proc    near                    ; go to end of scrolling text
  1619.         push    cx
  1620.         mov     cx,bwnd.lcnt            ; all bottom window lines [dlk]
  1621.         jmp     dnwp0                   ; and enter dwnpg
  1622. endwnd  endp
  1623.  
  1624. dnone   proc    near                    ; move text up one line [jrd]
  1625.         push    cx
  1626.         mov     cx,1
  1627.         jmp     dnwp0
  1628. dnone   endp
  1629.  
  1630. ; scroll viewing window down (text moves up) one page (24 lines)
  1631. dnwpg   proc    near
  1632.         push    cx
  1633.         mov     cl,byte ptr low_rgt+1   ; number of rows, excl status
  1634.         inc     cl                      ; count from 1, not 0
  1635.         mov     ch,0
  1636. dnwp0:                                  ; additional entry point
  1637.         cmp     bwnd.lcnt,cx            ; enough lines in bottom line buffer?
  1638.         jge     dnwp1                   ; ge = we have that many lines stored
  1639.         mov     cx,bwnd.lcnt            ; do as many as we have
  1640. dnwp1:  jcxz    dnwp2                   ; z = nothing to do
  1641.         cmp     tekflg,0                ; Tek mode active?
  1642.         jne     dnwp2                   ; ne = yes, no scrolling
  1643.         call    mscru                   ; scroll up text one line
  1644.         loop    dnwp1
  1645. dnwp2:  pop     cx
  1646.         clc
  1647.         ret
  1648. dnwpg   endp
  1649.  
  1650. ; home viewing window
  1651. homwnd  proc    near
  1652.         push    cx
  1653.         mov     cx,twnd.lcnt            ; all top window lines [dlk]
  1654.         jmp     upwp0                   ; join upwpg
  1655. homwnd  endp
  1656.  
  1657. upone   proc    near                    ; move text down one line [jrd]
  1658.         push    cx
  1659.         mov     cx,1
  1660.         jmp     upwp0
  1661. upone   endp
  1662.  
  1663. ; scroll viewing window up (text moves down) a page (24 lines)
  1664. upwpg   proc    near
  1665.         push    cx
  1666.         mov     cl,byte ptr low_rgt+1   ; number of rows, excl status line
  1667.         inc     cl                      ; count from 1, not 0
  1668.         mov     ch,0
  1669. upwp0:                                  ; additional entry point
  1670.         cmp     twnd.lcnt,cx            ; enough lines in top line buffer?
  1671.         jae     upwp1                   ; ae = at least as many as requested
  1672.         mov     cx,twnd.lcnt            ; do only as many as are stored.
  1673. upwp1:  jcxz    upwp2                   ; z = no lines to scroll
  1674.         cmp     tekflg,0                ; Tek mode active?
  1675.         jne     upwp2                   ; ne = yes, no scrolling
  1676.         call    mscrd                   ; roll down text one line
  1677.         loop    upwp1
  1678. upwp2:  pop     cx
  1679.         clc
  1680.         ret
  1681. upwpg   endp
  1682.  
  1683.  
  1684. ; Put a line into the circular buffer.  Pass the buffer structure in bx.
  1685. ; Source is tv_segs:si which is the current screen address.
  1686. ; Rewritten by [jrd]
  1687. putcirc proc    near
  1688.         push    es
  1689.         mov     cl,crt_cols             ; number of columns
  1690.         xor     ch,ch
  1691.         mov     es,[bx].orig            ; get segment of memory area
  1692.         cmp     bx,offset bwnd          ; bottom buffer?
  1693.         je      putci6                  ; e = yes
  1694.         mov     di,twnd.pp              ; pick up buffer ptr (offset from es)
  1695.         add     di,cx                   ; increment to next available slot
  1696.         add     di,cx                   ; char and attribute
  1697.         cmp     di,twnd.bend            ; would line extend beyond buffer?
  1698.         jb      putci1                  ; b = not beyond end
  1699.         mov     di,0                    ; else start at the beginning
  1700. putci1: mov     twnd.pp,di              ; update ptr
  1701.         cld                             ; set direction to forward
  1702.         push    ds                      ; save regular datas seg reg
  1703.         mov     ds,tv_segs              ; use screen segment for ds:si
  1704.         rep     movsw                   ; copy into buffer
  1705.         pop     ds                      ; restore regular datas segment
  1706.         mov     cx,twnd.lmax            ; line capacity of buffer
  1707.         dec     cx                      ; minus one work space line
  1708.         cmp     twnd.lcnt,cx            ; can we increment line count?
  1709.         jae     putci1b                 ; ae = no, keep going
  1710.         inc     twnd.lcnt               ; else count this line
  1711. putci1b:cmp     bwnd.lcnt,0             ; any lines in bottom buffer?
  1712.         je      putci2                  ; e = no
  1713.         mov     cx,bwnd.pp              ; see if we overlap bot buf
  1714.         cmp     cx,twnd.pp              ; is this line in bot buf area?
  1715.         jne     putci2                  ; ne = no
  1716.         add     cl,crt_cols             ; move bottom pointer one slot earlier
  1717.         adc     ch,0
  1718.         add     cl,crt_cols             ; words
  1719.         adc     ch,0
  1720.         cmp     cx,bwnd.bend            ; beyond end of buffer?
  1721.         jb      putci1a                 ; b = no
  1722.         mov     cx,0                    ; yes, start at beginning of buffer
  1723. putci1a:mov     bwnd.pp,cx              ; new bottom pointer
  1724.         dec     bwnd.lcnt               ; one less line in bottom buffer
  1725. putci2: pop     es
  1726.         ret
  1727. putci6:                                 ; bottom buffer
  1728.         add     cx,cx                   ; words worth
  1729.         cmp     bwnd.lcnt,0             ; any lines in the buffer yet?
  1730.         jne     putci7                  ; ne = yes
  1731.         mov     di,twnd.pp              ; get latest used slot of top buff
  1732.         add     di,cx                   ; where first free (?) slot starts
  1733.         cmp     di,bwnd.bend            ; are we now beyond the buffer?
  1734.         jb      putci6a                 ; b = no
  1735.         mov     di,0                    ; yes, start at beginning of buffer
  1736. putci6a:add     di,cx                   ; start of second free (?) slot
  1737.         cmp     di,bwnd.bend            ; are we now beyond the buffer?
  1738.         jb      putci6b                 ; b = no
  1739.         mov     di,0                    ; yes, start at beginning of buffer
  1740. putci6b:mov     cx,twnd.lmax            ; buffer line capacity
  1741.         sub     cx,twnd.lcnt            ; minus number used by top buffer
  1742.         sub     cx,2                    ; minus one work slot and one we need
  1743.         cmp     cx,0                    ; overused some slots?
  1744.         jge     putci8                  ; ge = enough to share
  1745.         add     twnd.lcnt,cx            ; steal these from top window beginning
  1746.         jmp     short putci8
  1747.  
  1748. putci7: mov     es,bwnd.orig            ; get segment of memory area
  1749.         mov     di,bwnd.pp              ; pick up buffer ptr (offset from es)
  1750.         cmp     di,0                    ; would line start before buffer?
  1751.         jne     putci7a                 ; ne = after start of buffer
  1752.         mov     di,bwnd.bend            ; else start at the end minus one slot
  1753.         inc     di
  1754. putci7a:sub     di,cx
  1755. putci8: mov     bwnd.pp,di              ; update ptr (this is latest used slot)
  1756.         mov     cl,crt_cols
  1757.         xor     ch,ch
  1758.         cld                             ; set direction to forward
  1759.         push    ds                      ; save regular datas seg reg
  1760.         mov     ds,tv_segs              ; use screen segment for ds:si
  1761.         rep     movsw                   ; copy into buffer
  1762.         pop     ds                      ; restore regular datas segment
  1763.         mov     cx,bwnd.lmax            ; line capacity of buffer
  1764.         cmp     bwnd.lcnt,cx            ; can we increment line count?
  1765.         jae     putci8b                 ; ae = no, keep going
  1766.         inc     bwnd.lcnt               ; else count this line
  1767. putci8b:cmp     twnd.lcnt,0             ; any lines in top line buf?
  1768.         je      putci9                  ; e = no
  1769.         mov     cx,twnd.pp              ; yes, see if we used last top line
  1770.         cmp     cx,bwnd.pp              ; where we just wrote
  1771.         jne     putci9                  ; not same place, so all is well
  1772.         dec     twnd.lcnt               ; one less line in top window
  1773.         cmp     cx,0                    ; currently at start of buffer?
  1774.         jne     putci8a                 ; ne = no
  1775.         mov     cx,twnd.bend            ; yes
  1776.         inc     cx
  1777. putci8a:sub     cl,crt_cols             ; back up top window
  1778.         sbb     ch,0
  1779.         sub     cl,crt_cols             ; by one line
  1780.         sbb     ch,0
  1781.         mov     twnd.pp,cx              ; next place to read
  1782. putci9: pop     es
  1783.         ret
  1784.  
  1785. putcirc endp
  1786.  
  1787. ; Get a line from the circular buffer, removing it from the buffer.
  1788. ; returns with carry on if the buffer is empty.
  1789. ; Pass the buffer structure in bx.
  1790. ; Destination preset in es:di which is the current screen address.
  1791. ; Rewritten by [jrd]
  1792. getcirc proc    near
  1793.         cmp     [bx].lcnt,0             ; any lines in buffer?
  1794.         jne     getci1                  ; ne = yes, ok to take one out.
  1795.         stc                             ; else set carry
  1796.         ret                             ; and return
  1797. getci1:                                 ; top and bottom window common code
  1798.         mov     cl,crt_cols             ; # of chars to copy
  1799.         xor     ch,ch
  1800.         push    cx                      ; save around calls
  1801.         mov     si,[bx].pp              ; this is source
  1802.         cld                             ; set direction to forward
  1803.         push    ds                      ; save original ds
  1804.         mov     ds,[bx].orig            ; use seg address of buffer for si
  1805.         rep     movsw
  1806.         pop     ds                      ; recover original data segment
  1807.         pop     cx                      ; length for Topview
  1808.         push    cx                      ; save again
  1809.         call    scrsync                 ; synch Topview
  1810.         mov     si,[bx].pp              ; get ptr again
  1811.         pop     cx
  1812.         add     cx,cx                   ; words
  1813.         cmp     bx,offset bwnd          ; bottom window?
  1814.         je      getci6                  ; e = yes
  1815.         sub     si,cx                   ; top window, move back
  1816.         jnc     getcir2                 ; nc = still in buffer, continue
  1817.         mov     si,twnd.bend            ; else use end of buffer
  1818.         sub     si,cx                   ; minus length of a piece
  1819.         inc     si
  1820. getcir2:mov     twnd.pp,si              ; update ptr
  1821.         dec     twnd.lcnt               ; decrement # of lines in buffer
  1822.         clc                             ; make sure no carry
  1823.         ret
  1824. getci6:                                 ; bottom window
  1825.         add     si,cx                   ; words, move back (bot buf = reverse)
  1826.         cmp     si,bwnd.bend            ; still in buffer?
  1827.         jb      getci7                  ; b = yes
  1828.         mov     si,0                    ; else use beginning of buffer
  1829. getci7: mov     bwnd.pp,si              ; update ptr
  1830.         dec     bwnd.lcnt               ; decrement # of lines in buffer
  1831.         clc                             ; make sure no carry
  1832.         ret
  1833. getcirc endp
  1834.  
  1835. ;
  1836. ; CHKDSP - procedure to check for hardware support of 132 cols [dlk]
  1837. ;
  1838. ;  Supported hardware: EVA board from Tseng Labs w/132-col kit installed
  1839. ;               Video 7 Vega Deluxe w/ 132X25.COM driver installed [tmk]
  1840. ;               ATI EGA Wonder
  1841. ;
  1842. ;  The routine checks for the presence of a 132-column-capable adapter. If
  1843. ;  one is found, its handler returns the proper vide mode in [CX]. The main-
  1844. ;  line code then moves this to [AX] and issues the video interrupt.
  1845. ;
  1846.  
  1847. chgdsp  proc    near
  1848.         push    es                      ; save all we use
  1849.         push    ax
  1850.         push    bx
  1851.         push    cx
  1852.         push    dx
  1853.         push    si
  1854.         push    di
  1855.         mov     temp,ax                 ; save set/reset flag from msz
  1856.         mov     bx,portval              ; get flow control around mode sets
  1857.         mov     bx,[bx].flowc           ; bh=xon, bl=xoff, or both nulls
  1858.         mov     byte ptr temp+1,bh      ; save xon or null here
  1859.         cmp     bl,0                    ; no flow control?
  1860.         je      chgds0                  ; e = none
  1861.         mov     ah,bl                   ; get xoff
  1862.         call    outchr                  ; send it
  1863.          nop
  1864.          nop
  1865.          nop
  1866.         mov     ax,100                  ; wait 100 millisec for mode to finish
  1867.         call    pcwait
  1868. chgds0: call    ckteva                  ; try for Tseng Labs EVA
  1869.         jnc     chgds1                  ; nc = found
  1870.         call    ckv7vd                  ; try for Video 7 Vega Deluxe
  1871.         jnc     chgds1                  ; nc = found
  1872.         call    ckatiw                  ; try for ATI EGA Wonder
  1873.         jnc     chgds1                  ; nc = found
  1874.         jmp     chgdsx                  ; if not, exit
  1875. ;
  1876. chgds1: mov     ax,cx                   ; get returned value in proper reg
  1877.         int     screen                  ; call the bios
  1878.         call    scrini                  ; reset parameters
  1879.         cmp     flags.modflg,0          ; is it enabled
  1880.         je      chgdsx                  ; e=not allowed
  1881.         test    yflags,modoff           ; is mode line toggled off
  1882.         jnz     chgdsx                  ; nz=yes its off so ignore it
  1883.         call    modlin                  ; make mode visible
  1884. chgdsx: cmp     byte ptr temp+1,0       ; no flow control?
  1885.         je      chgdsx1                 ; e = none
  1886.         mov     ah,byte ptr temp+1      ; get xon
  1887.         call    outchr                  ; send it
  1888.          nop
  1889.          nop
  1890.          nop
  1891. chgdsx1:pop     di                      ; restore what we saved
  1892.         pop     si
  1893.         pop     dx
  1894.         pop     cx
  1895.         pop     bx
  1896.         pop     ax
  1897.         pop     es
  1898.         ret                             ; return to caller
  1899. chgdsp  endp
  1900.  
  1901. ; Individual tests for various 132-column boards
  1902.                                         ;
  1903.                                         ; Tseng LABS EVA
  1904. ckteva: mov     ax,0c000h               ; seg addr for eva
  1905.         mov     es,ax                   ; set into es register
  1906.         mov     di,76h                  ; offset of board's string
  1907.         lea     si,tsngid               ; validation string
  1908.         mov     cx,tsnglen              ; length of validiation string
  1909.         cld
  1910.         repe    cmpsb                   ; compare strings
  1911.         jne     chnoad                  ; ne = strings differ
  1912.                                         ;
  1913.                                         ; an EVA board - check for 132 col kit
  1914.         cmp     byte ptr es:099h,0      ; check 132 col kit installed
  1915.         je      chnoad                  ; e=0=not installed
  1916.         jmp     catfnd                  ; do the mode change
  1917.  
  1918. chnoad: stc                             ; indicate adapter not present
  1919.         ret                             ; and exit
  1920.                                         ;
  1921.                                         ; ATI EGA Wonder
  1922. ckatiw: mov     ax,0c000h               ; seg addr for EGA Wonder
  1923.         mov     es,ax                   ; set into es register
  1924.         mov     di,012fh                ; offset of message in ROM
  1925.         lea     si,atiwid               ; offset of message here
  1926.         mov     cx,atilen               ; length of validation string
  1927.         cld
  1928.         repe    cmpsb                   ; compare strings
  1929.         jne     chnoad                  ; ne = strings differ
  1930.                                         ;
  1931. catfnd: mov     cx,0003h                ; prepare to reset video mode
  1932.         cmp     byte ptr temp,0         ; are we setting or resetting?
  1933.         je      ckexit                  ; e is reset, exit
  1934.         mov     cx,0023h                ; set to 132 cols (Set Mode 23H)
  1935. ckexit: clc                             ; carry clear means found
  1936.         ret
  1937.                                         ;
  1938.                                         ; Video 7 Vega Deluxe
  1939. ckv7vd: mov     ax,0c000h               ; seg addr for Vega rom bios
  1940.         mov     es,ax                   ; set into es register
  1941.         mov     di,002ah                ; offset of message in ROM
  1942.         lea     si,vid7id               ; offset of message here
  1943.         mov     cx,vid7len
  1944.         cld
  1945.         repe    cmpsb                   ; compare strings
  1946.         jne     chnoad                  ; ne = strings are different
  1947.                                         ;
  1948.         test    byte ptr es:[03ffeh],1  ; is this a 'Deluxe' Vega?
  1949.         jz      chnoad                  ; z = nope, can't do it
  1950.         mov     ah,35h                  ; DOS Get Vector
  1951.         mov     al,10h                  ; Bios video interrupt
  1952.         int     dos                     ; get it into es:bx
  1953.         mov     di,bx                   ; es:bx is returned int 10h entry pnt
  1954.         sub     di,5ah                  ; back offset to msg in 132X25.COM
  1955.         lea     si,vid7id               ; offset of validation message
  1956.         mov     cx,vid7len              ; length of validation string
  1957.         cld
  1958. cnv7fn1:repe    cmpsb                   ; Look for repeat of msg by 132X25.COM
  1959.         jne     cnv7fn2                 ; if different
  1960.         mov     cl,crt_mode             ; prepare to reset video mode
  1961.         mov     ch,0
  1962.         cmp     byte ptr temp,0         ; are we setting or resetting?
  1963.         je      ckexit                  ; e is reset, exit
  1964.         mov     cx,0000h                ; set to 132 cols (old 40x25)
  1965.         jmp     short ckexit            ; and exit
  1966.  
  1967. cnv7fn2:mov     ax,6f00h                ; check for VegaBios driver
  1968.         int     screen                  ;  run by ESU.EXE
  1969.         cmp     bx,'V7'                 ; Video 7 Bios presence response
  1970.         jne     chnoad                  ; ne = not there
  1971.         mov     ax,6f01h                ; al gets monitor type (mono,color,ega)
  1972.         int     screen
  1973.         mov     bx,51                   ; presume mono 132x25, page 0
  1974.         cmp     al,2                    ; 1=mono, 2=color, above=ega
  1975.         jb      cnv7fn3                 ; b = mono
  1976.         mov     bx,4fh                  ; presume med res color 132x25
  1977.         je      cnv7fn3                 ; e = med res color
  1978.         mov     bx,41h                  ; ega high res 132x25
  1979. cnv7fn3:push    bx
  1980.         mov     ah,0eh                  ; get current mode
  1981.         int     screen
  1982.         mov     ax,6f05h                ; set special mode found in bl
  1983.         cmp     byte ptr temp,0         ; resetting to 80 column mode?
  1984.         jne     cnv7fn4                 ; ne = no, setting 132x25
  1985.         mov     al,crt_norm             ; get normal mode
  1986.         mov     ah,0                    ; set mode
  1987. cnv7fn4:pop     bx                      ; recover special mode
  1988.         int     screen
  1989.         mov     cx,0f00h                ; a nop screen bios command
  1990.         clc
  1991.         ret
  1992.  
  1993. ; Jumping to this location is like retskp.  It assumes the instruction
  1994. ;   after the call is a jmp addr.
  1995.  
  1996. RSKP    PROC    NEAR
  1997.         pop     bp
  1998.         add     bp,3
  1999.         push    bp
  2000.         ret
  2001. RSKP    ENDP
  2002.  
  2003. ; Jumping here is the same as a ret.
  2004.  
  2005. R       PROC    NEAR
  2006.         ret
  2007. R       ENDP
  2008.  
  2009. code    ends
  2010.  
  2011. if1
  2012.         %out [End of pass 1]
  2013. else
  2014.         %out [End of assembly]
  2015. endif
  2016.  
  2017.         end
  2018.