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

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