home *** CD-ROM | disk | FTP | other *** search
/ Columbia Kermit / kermit.zip / ccdos / cczibm.asm < prev    next >
Assembly Source File  |  2020-01-01  |  163KB  |  3,333 lines

  1.         NAME    cczibm
  2. ; File CCZIBM.ASM
  3.         page 60,132
  4. ; Terminal emulator module for IBM PC's and compatibles.
  5. ;
  6. ;CHINESE
  7.  
  8. ifdef   MSDOS
  9.         include mszibm.dat
  10. else
  11.         include cczibm.dat
  12. endif
  13.  
  14. code    segment public 'code'
  15.         extrn   prtbout:near, prtnout:near, csrtype:near, trnmod:near
  16.         extrn   scrmod:near, scrseg:near, scrsync:near, scroff:near
  17.         extrn   scron:near, atsclr:near, vtscru:near, vtscrd:near
  18.         extrn   modwrt:near, telmsy:near, scrloc:near, pcwait:near
  19.         extrn   chgdsp:near, trnprs:near, cptchr:near, tekesc:near
  20.         extrn   pntchr:near, pntchk:near, pntflsh:near
  21.                                 ; extrn procedures are all in module msyibm
  22.         extrn   tekini:near, tekemu:near, tekend:near, vtrmac:near,vtsmac:near
  23.  
  24.         assume  cs:code, ds:datas, es:datas
  25.  
  26. ; This routine initializes the VT100 setups at startup.  It is called from
  27. ; procedure lclyini in module msyibm.
  28.  
  29. vsinit  proc    near
  30.         mov     vtemu.vtflgst,vsdefaults ; Init to defaults in mssdef.h
  31.         mov     vtemu.vtflgop,vsdefaults ; Init runtime state to setup items
  32.         mov     insmod,0                ; turn off insert mode
  33.         mov     deftabs,0               ; Column 1 has no tab stop
  34.         mov     ansflgs,0
  35.         mov     cl,crt_cols             ; physical screen width (80)
  36.         dec     cl                      ; we count from column 0
  37.         mov     ch,crt_lins             ; physical screen length-1
  38.         dec     ch                      ; we count from row 0
  39.         mov     low_rgt,cx              ; store active text area
  40.         mov     cx,131
  41.         mov     di,1                    ; Starting index for column 2
  42. vsini1: mov     al,0                    ; Assume we will clear this one
  43.         test    di,0007H                ; Index mod 8 equals 0?
  44.         jnz     vsini2                  ; No, clear it
  45.         mov     al,0FFH                 ; Yes, set it
  46. vsini2: mov     deftabs[di],al          ; Set or clear a tab stop
  47.         inc     di                      ; Advance to next
  48.         loop    vsini1                  ; Loop for all
  49.         mov     cx,slen                 ; clear linetype array
  50.         mov     di,0
  51. vsini3: mov     linetype[di],0
  52.         inc     di
  53.         loop    vsini3
  54.         mov     vtemu.vttbst,offset deftabs ; addrs of active tabs for STATUS
  55.         mov     vtemu.vttbs,offset deftabs  ; addrs of tabs for setup (SET)
  56.         mov     vttabs,offset deftabs   ; initial source of tabs
  57.         call    cpytabs                 ; copy default to active
  58.         mov     vtemu.att_ptr,offset att_normal  ; ptr to video attributes
  59.         mov     ah,8                    ; read current attributes
  60.         xor     bh,bh                   ; page 0
  61.         int     screen
  62.         mov     scbattr,ah              ; save video attributes
  63.         mov     att_normal,ah           ; set att_normal to present colors
  64.         call    brkatt                  ; separate colors from blink/bold
  65.         rol     ah,1                    ; reverse foreground & background
  66.         rol     ah,1                    ; RGB bits
  67.         rol     ah,1
  68.         rol     ah,1
  69.         call    addatt                  ; reinsert bold/blink bits
  70.         mov     att_reverse,ah          ; set att_reverse too
  71.         mov     ah,byte ptr low_rgt     ; right most column (counted from 0)
  72.         sub     ah,8                    ; place marker 9 columns from margin
  73.         mov     belcol,ah               ; store column number to ring bell
  74.         ret                             ; And return
  75. vsinit  endp
  76.  
  77.  
  78. ; Initialization routine.
  79. ;
  80. ; Call:         al/     yflags byte that was passed to Term routine
  81. ;               dl/     index for baud rate table
  82. ;               dh/     parity in bits 4-7, number of data bits in bits 0-3
  83. ;
  84.  
  85. ansini  proc    near
  86.         mov     yflags,al               ; Always save flags
  87.         mov     ah,vtemu.vtflgst        ; setup flags
  88.         mov     vtflags,ah
  89.         mov     vttabs,offset deftabs   ; tab stop pointer
  90.         mov     vtemu.vttbst,offset tabs; store here for STATUS
  91.         mov     al,flags.vtflg          ; get current terminal type
  92.         mov     oldterm,al              ; remember it here for soft restarts
  93.         mov     insmod,0                ; turn off insert mode
  94.         mov     h19l25,0                ; clear Heath 25th line enable
  95.         mov     h19ctyp,1               ; set Heath cursor to underline, on
  96.         mov     anspflg,0               ; clear printer flag
  97.         push    ax
  98.         mov     ah,byte ptr low_rgt     ; right most column (counted from 0)
  99.         sub     ah,8                    ; place marker 9 columns from margin
  100.         mov     belcol,ah               ; store column number to ring bell
  101.         pop     ax
  102.         cmp     dl,lbaudtab             ; Wierd index?
  103.         jb      ansin1                  ; No - OK - store it
  104.         mov     dl,lbaudtab-1           ; Yes - make it the maximum
  105. ansin1: mov     baudidx,dl              ; Save baud rate index
  106.         mov     al,dh                   ; Get parity/number of databits
  107.         and     al,0FH                  ; Isolate number of databits
  108.         mov     datbits,al              ; Save
  109.         mov     cl,4                    ; Isolate parity code
  110.         shr     dh,cl                   ; Isolate parity code
  111.         cmp     dh,lpartab              ; Weird code?
  112.         jb      ansin2                  ; No - OK - store it
  113.         mov     dh,lpartab-1            ; Yes - make it the maximum
  114. ansin2: mov     parcode,dh              ; Save
  115.         call    scrmod                  ; Get the screen mode, in MSYxxx
  116.         mov     cl,crt_cols             ; physical screen number columns (80)
  117.         dec     cl                      ; we count from column 0 here
  118.         mov     ch,crt_lins             ; physical screen number rows-1 (24)
  119.         dec     ch                      ; we count from row 0 here
  120.         mov     low_rgt,cx              ; save as active text screen size
  121.         mov     oldscrn,cx              ; remember old screen dimensions
  122. ansin3: call    atreset                 ; Reset everything
  123.         mov     ttstate,offset atnrm    ; Reset state to "normal"
  124.         ret                             ; And return
  125. ansini  endp
  126.  
  127.  
  128. ; Re-initialization routine. Called when Term was called but screen was
  129. ; restored from a previously saved screen, etc.
  130. ;
  131. ; Call: al/     yflags byte that was passed from msyibm module.
  132. ;
  133.  
  134. ansrei  proc    near
  135.         mov     yflags,al               ; Always save flags
  136.         mov     ah,vtemu.vtflgop        ; get runtime flags
  137.         mov     tmpflags,ah
  138.         call    scrmod                  ; Get the screen mode
  139.         call    atsctyp                 ; set cursor type [rbv]
  140.         mov     ah,3                    ; get cursor position from msy
  141.         mov     bh,0                    ; Page zero
  142.         int     screen                  ; physical = logical cursor here
  143.         mov     cursor,dx               ; dh = row, dl = column
  144.         mov     cl,crt_cols             ; physical screen number columns (80)
  145.         dec     cl                      ; we count from column 0 here
  146.         mov     ch,crt_lins             ; physical screen number rows-1 (24)
  147.         dec     ch                      ; we count from row 0 here
  148.         mov     low_rgt,cx              ; save as active text screen size
  149.         cmp     linelen,79              ; want 80 cols?
  150.         ja      ansre2                  ; a = no
  151.         cmp     byte ptr low_rgt,79     ; want 80 cols. Is active screen wider?
  152.         jbe     ansre2                  ; be = no
  153.         mov     byte ptr low_rgt,79     ; narrow down to 80 columns
  154. ansre2: test    vtemu.vtflgop,vswdir    ; writing right to left?
  155.         jz      ansre4                  ; z = no, left to right
  156.         sub     dl,byte ptr low_rgt     ; reflect cursor from right side
  157.         neg     dl
  158.         mov     cursor,dx               ; store as logical position
  159. ansre4: push    cx                      ; save current physical screen size
  160.         call    stblmds                 ; Check settable modes, set flags
  161.         pop     cx
  162.         cmp     cx,oldscrn              ; has screen size changed?
  163.         je      ansre3                  ; e = no, same as last time
  164.         mov     oldscrn,cx              ; remember new size
  165.         mov     mar_top,0               ; reset scrolling region
  166.         mov     al,byte ptr low_rgt+1
  167.         mov     mar_bot,al
  168.         jmp     atres2                  ; better do soft reset
  169. ansre3: ret
  170. ansrei  endp
  171.  
  172.  
  173. ; This routine copies the new tab stops when they have changed.
  174. ; Copies all 132 columns.
  175. cpytabs proc    near
  176.         mov     cx,swidth               ; number of screen columns
  177.         jcxz    cpytab1                 ; z = none to do
  178.         mov     si,vttabs               ; Source
  179.         mov     di,offset tabs          ; Destination
  180.         push    es                      ; save es
  181.         push    ds
  182.         pop     es                      ; set es to datas segment
  183.         cld
  184.         rep     movsb                   ; Do the copy
  185.         pop     es                      ; recover es
  186. cpytab1:ret
  187. cpytabs endp
  188.  
  189.  
  190. ; This routine checks to see whether any of the settable modes have changed
  191. ; (things that can be changed in both SETUP and by host commands), and
  192. ; changes those that need to be changed.  TMPFLAGS has the new VT100 setup
  193. ; flags, VTFLAGS has the old. This routine also updates VTFLAGS.
  194. ; Revised by [jrd] to allow MSY to reset scbattr when not in connect mode,
  195. ; to do "soft reset" if terminal type has changed, and to do a screen clear
  196. ; reset if the actual screen colors have changed.
  197.  
  198. stblmds proc    near
  199.         mov     al,flags.vtflg          ; get current terminal type
  200.         cmp     al,oldterm              ; same as before?
  201.         je      stblm10                 ; e = yes, skip over soft reset
  202.         mov     oldterm,al              ; remember current terminal type
  203.         mov     insmod,0                ; reset insert mode flag
  204.         mov     h19l25,0                ; reset heath-19 25th line enable
  205.         mov     mar_top,0               ; reset top scrolling margin
  206.         mov     al,byte ptr low_rgt+1   ; and scrolling margin
  207.         mov     mar_bot,al              ; to last normal line on screen
  208.         mov     ah,byte ptr low_rgt     ; right most column (counted from 0)
  209.         sub     ah,8                    ; place marker 9 columns from margin
  210.         mov     belcol,ah               ; store column number to ring bell
  211.         and     ansflgs,decckm+deckpam+decom+dececho ; save some flags
  212.         push    bx                      ; save this register around loop
  213.         mov     bx,offset linetype      ; setup to clear double width chars
  214.         mov     cx,slen                 ; number of linetype slots to clear
  215.         cmp     flags.vtflg,ttvt100     ; VT100 now?
  216.         jne     stblm0                  ; ne = no
  217.         or      ansflgs,decanm          ; set ansi flag bit
  218. stblm0: mov     byte ptr [bx],0         ; clear the linetype array to single
  219.         inc     bx                      ;  width characters
  220.         loop    stblm0                  ; do each line (1 byte per line)
  221.         pop     bx                      ; restore bx
  222. stblm10:mov     al,tmpflags             ; Get the new flags
  223.         and     ansflgs,not anslnm      ; assume we do not want newline
  224.         test    al,vsnewline            ; is newline mode desired?
  225.         jz      stblm1                  ; No - continue
  226.         or      ansflgs,anslnm          ; Yes - set corresponding mode flag
  227. stblm1: and     ansflgs,not decawm      ; assume not want wrap
  228.         test    al,vswrap               ; Did wrap mode change?
  229.         jz      stblm2                  ; No - continue
  230.         or      ansflgs,decawm          ; Yes - set corresponding mode flag
  231. stblm2:
  232. ;;      mov     ah,vtflags              ; old flags
  233. ;;      xor     ah,tmpflags             ; new flags
  234. ;;      test    ah,vsshift3             ; pick out char set bit
  235. ;;      jz      stblm4                  ; z = no change
  236. ;;      mov     ah,ascset               ; assume US ASCII
  237. ;;      test    tmpflags,vsshift3       ; Want UK?
  238. ;;      jz      stblm3                  ; No - guessed right
  239. ;;      mov     ah,ukset                ; Yes - use UK set
  240.         mov     ah,vtemu.vtchset        ; select char set from setup byte
  241. stblm3: mov     chr_sg0,ah              ; Set the sets
  242.         mov     chr_sg1,ah
  243. stblm4: mov     ah,oldbatr              ; get old screen background scbattr
  244.         mov     scbattr,ah              ; and update working copy
  245.         mov     ah,att_normal           ; get new attributes (Set Term Color)
  246.         push    bx
  247.         mov     bh,ah                   ; get new intensity bit of att_normal
  248.         and     bh,att_intensity
  249.         and     curattr,not att_intensity ; char attrs. clear intensity bit
  250.         or      curattr,bh              ; set new intensity
  251.         and     mlbattr,not att_intensity ; mode line attrs. clear intensity
  252.         and     scbattr,not att_intensity ; screen background attribute
  253.         or      scbattr,bh              ; set its intensity also
  254.         mov     bl,scbattr
  255.         mov     oldbatr,bl              ; and save it here as well
  256.         pop     bx
  257.         call    brkatt                  ; separate color and blink/bold
  258.         rol     ah,1                    ; reverse fore/back color fields
  259.         rol     ah,1
  260.         rol     ah,1
  261.         rol     ah,1
  262.         call    addatt                  ; put back blink/bold
  263.         push    bx                      ; check on color change
  264.         mov     bh,ah                   ; new att_reverse pattern
  265.         and     bh,not(att_intensity+att_blink) ; look at just color bits
  266.         mov     bl,att_reverse          ; previous att_reverse pattern
  267.         and     bl,not(att_intensity+att_blink) ; look at just color bits
  268.         mov     att_reverse,ah          ; save new reverse pattern
  269.         cmp     bh,bl                   ; have any color bits changed?
  270.         pop     bx                      ; does not affect flags
  271.         je      stblm9                  ; e = no
  272.         mov     cursor,0                ; reset cursor position
  273.         jmp     atres2                  ; go to semi-reset
  274. stblm9:                                 ; check on screen normal/reversed
  275.         mov     al,tmpflags
  276.         xor     al,vtflags              ; Find which ones have changed
  277.         test    al,vsscreen             ; How about screen background?
  278.         jz      stblm8                  ; No - don't touch it
  279.         test    tmpflags,vsscreen       ; Flag to be set?
  280.         jnz     stblm5                  ; Yes - go to it
  281.         and     ansflgs,not decscnm     ; No - cleared (normal video)
  282.         and     savflgs,not decscnm
  283.         mov     al,att_normal           ; No - get new background
  284.         jmp     short stblm6            ; And reverse everything
  285.  
  286. stblm5: or      ansflgs,decscnm         ; Set (reverse video)
  287.         or      savflgs,decscnm
  288.         mov     al,att_reverse          ; No - set reverse video
  289. stblm6: call    atrss2                  ; Reverse screen and cursor attribute
  290. stblm7: mov     al,scbattr              ; Reset saved attribute also
  291.         mov     savecu+svattr_index,al
  292.         mov     oldbatr,al              ; and save our attribute
  293. stblm8: mov     al,tmpflags             ; Get new flags
  294.         mov     vtflags,al              ; Store them
  295.         mov     ah,2                    ; set cursor
  296.         mov     bh,0                    ; page 0
  297.         mov     dx,cursor
  298.         call    direction               ; set cursor for writing direction
  299.         ret
  300. stblmds endp
  301.  
  302. ; Return screen offset - given rol, col in dx, returns offset of the word
  303. ; for that character from the screen origin in ax. Preserves all other regs.
  304. ; Use same routine in msy to more closely track screen width.
  305. ;;scrloc        proc    near
  306. ;;      push    bx                      ; We will use bx
  307. ;;      mov     al,dh                   ; Get row
  308. ;;      mov     bl,swidth               ; And length of a line
  309. ;;      mul     bl                      ; Offset for this row
  310. ;;      mov     dh,0                    ; Clear row
  311. ;;      add     ax,dx                   ; Word offset for this position
  312. ;;      sal     ax,1                    ; Make it a byte offset
  313. ;;      pop     bx                      ; Restore bx
  314. ;;      ret                             ; And return
  315. ;;scrloc        endp
  316.  
  317.  
  318.  
  319. ; Fetch status/attributes routine.
  320. ;
  321. ; Call:         al/     "yflags" byte from MSYxxx.
  322. ;
  323. ; Return:       ah/     mode line background attribute
  324. ;               al/     screen background attribute
  325. ;               bl/     current cursor attribute
  326. ;               bh/     ANSI (VT100) mode flags
  327.  
  328. anstat  proc    near
  329.         mov     yflags,al               ; Mostly for disleds
  330.         mov     ah,mlbattr              ; Return them our attrs, flags, etc
  331.         mov     al,scbattr
  332.         mov     bl,curattr
  333.         mov     bh,ansflgs
  334.         ret
  335. anstat  endp
  336.  
  337.  
  338. ; Routine called when something is typed on the keyboard
  339. ;
  340. ; Call:         No arguments
  341. ;
  342.  
  343. anskbi  proc    near
  344.         mov     ttkbi,0FFH              ; Just set a flag
  345.         ret
  346. anskbi  endp
  347.  
  348. ; Routine to do keyclick if flag is set.
  349. ;
  350. ; Call:         No arguments
  351. ;
  352.  
  353. vclick  proc    near
  354.         test    vtflags,vskeyclick      ; Is the flag on?
  355.         jz      vclick1                 ; No - just return
  356.         push    bx                      ; Save some ACs
  357.         push    di
  358.         mov     di,500                  ; 500 Hertz
  359.         mov     bx,1                    ; For 1 millisecond
  360.         call    vtsound                 ; Do it
  361.         pop     di                      ; Restore the ACs
  362.         pop     bx
  363. vclick1:ret
  364. vclick  endp
  365.  
  366.  
  367. ; Routine to do VT100-style bell.
  368. ;
  369. ; Call:         No arguments
  370. ;
  371.  
  372. vtbell  proc    near
  373.         push    di
  374.         push    bx
  375.         mov     di,880                  ; 880 Hertz
  376.         mov     bx,40                   ; For 40 ms
  377.         call    vtsound                 ; Do it
  378.         pop     bx
  379.         pop     di
  380.         ret
  381. vtbell  endp
  382.  
  383. ; Routine to make noise of arbitrary frequency for arbitrary duration.
  384. ; Similar to routine (with typo removed) in "IBM PC Assembly Language:
  385. ; A Guide for Programmers", Leo J. Scanlon, 1983 Robert J. Brady Co.,
  386. ; Bowie, MD., page 270. Modified by J R Doupnik to use 0.1 millsec interval.
  387. ;
  388. ; Call:         di/     frequency in Hertz.
  389. ;               bx/     duration in 1 millisecond units
  390. ;
  391.  
  392. vtsound proc    near
  393.         push    ax                      ; Save regs
  394.         push    cx
  395.         push    dx
  396.         mov     al,0B6H                 ; Write timer mode register
  397.         out     43H,al
  398.         mov     dx,14H                  ; Timer divisor is
  399.         mov     ax,4F38H                ; 1331000/frequency
  400.         div     di
  401.         out     42H,al                  ; Write timer 2 count low byte
  402.         mov     al,ah
  403.         out     42H,al                  ; Write timer 2 count high byte
  404.         in      al,61H                  ; Get current port B setting
  405.         or      al,3                    ; Turn speaker on
  406.         out     61H,al
  407.         mov     ax,bx                   ; number of milliseconds to wait
  408.         call    pcwait                  ; do the calibrated wait
  409.         in      al,61H                  ; Get current port B setting
  410.         and     al,0fch                 ; Turn off speaker and timer
  411.         out     61H,al
  412.         pop     dx                      ; Restore regs
  413.         pop     cx
  414.         pop     ax
  415.         ret
  416. vtsound endp
  417.  
  418. ; Routine to toggle VT100/VT52/Heath-19 modes. No arguments.
  419. ; Use & update global byte flags.vtflg for terminal type and update local
  420. ; bit decanm. Note: shifting to Heath-19 here does Not reset the scrolling
  421. ; margins mar_top & mar_bot nor reset the double char linetype array.
  422. ; [jrd]
  423. ans52t  proc    near
  424.         cmp     tekflg,0                ; in Tek sub mode?
  425.         jne     ans52c                  ; ne = yes, get out now
  426.         cmp     flags.vtflg,ttvt100     ; in VT100 mode?
  427.         jne     ans52a                  ; ne = no
  428.         and     ansflgs,not decanm      ; reset VT100 ansi mode
  429.         mov     flags.vtflg,ttvt52      ; say VT52 now (clears vt100 bit)
  430.         mov     oldterm,ttvt52          ; and remember it
  431.         jmp     ans52e
  432. ans52a: cmp     flags.vtflg,ttvt52      ; in VT52 mode?
  433.         jne     ans52b                  ; ne = no
  434.         mov     flags.vtflg,ttheath     ; say Heath-19 now
  435.         mov     oldterm,ttheath
  436.         jmp     ans52e
  437. ans52b: cmp     flags.vtflg,ttheath     ; in Heath-19 mode?
  438.         jne     ans52c                  ; ne = no
  439.         test    denyflg,tekxflg         ; is Tek mode disabled?
  440.         jz      ans52f                  ; z = no, enabled
  441.         mov     flags.vtflg,ttvt100     ; say VT100 now
  442.         mov     oldterm,ttvt100
  443.         or      ansflgs,decanm          ; set, go to VT100 mode
  444.         jmp     short ans52e
  445. ans52f: call    atsc                    ; save cursor and associated data
  446.         mov     flags.vtflg,tttek       ; set Tek mode
  447.         call    tekini                  ; init Tek to switch screens
  448.         jmp     atnorm                  ; normal state and return
  449. ans52c: cmp     flags.vtflg,tttek       ; in Tek mode now?
  450.         je      ans52d                  ; e = yes
  451.         cmp     tekflg,0                ; doing Tek sub mode?
  452.         jne     ans52d                  ; ne = yes
  453.         jmp     atnorm                  ; else ignore this call
  454.  
  455. ans52d: call    tekend                  ; exit Tek graphics mode
  456.         mov     tekflg,0                ; end Tek sub mode (do after tekend)
  457.         mov     flags.vtflg,ttvt100     ; say VT100 now
  458.         mov     oldterm,ttvt100
  459.         or      ansflgs,decanm          ; set, go to VT100 mode
  460.         call    atrc                    ; restore cursor etc
  461.         cmp     flags.modflg,0          ; is mode line disabled?
  462.         je      ans52e                  ; e = yes, disabled
  463.         test    yflags,modoff           ; Mode line off?
  464.         jnz     ans52e                  ; nz = yes - just return
  465.         mov     al,yflags               ; get current flags
  466.         or      al,modoff               ; say mode line is off
  467.         call    telmsy                  ; let msy hear the news
  468.         call    trnmod                  ; turn it on
  469. ans52e: call    chrdef                  ; Set default character sets
  470.         call    atsc                    ; Save cursor etc
  471.         call    disleds                 ; Remove or redisplay "LEDs"
  472.         jmp     atnorm                  ; Say state is "normal" and return
  473. ans52t  endp
  474.  
  475.  
  476. ; Display "LEDs" routine. Note that this routine
  477. ; is not used internally in this module (because it updates the flags from
  478. ; MSYIBM). Internally, disleds is used instead. The yflags from MSYIBM are
  479. ; needed because we have to know if the mode line is enabled.
  480. ;
  481. ; Call:         al/     yflags from MSYIBM
  482. ;
  483. ; Return:       Current state of "LEDs" displayed on line 25.
  484. ;
  485.  
  486. ansdsl  proc    near                    ; Update flags and display "LEDs"
  487.         mov     yflags,al               ; Update the flags
  488.         call    disleds                 ; Display LEDs
  489.         ret
  490. ansdsl  endp
  491.  
  492. ; Internal routine to display LEDs.
  493.  
  494. disleds:test    yflags,modoff           ; Mode line off?
  495.         jnz     disled2                 ; Yes - just return
  496.         cmp     flags.modflg,1          ; mode line on and owned by us?
  497.         ja      disled2                 ; a = no, leave it intact
  498.         mov     ah,2                    ; Position cursor at (slen-1),70
  499.         mov     bh,0                    ; Page zero
  500.         mov     dh,byte ptr low_rgt+1   ; last screen line - 1
  501.         inc     dh                      ; status line
  502.         mov     dl,led_col              ; column for led display
  503.         int     screen
  504.         mov     cx,10                   ; Length of byte array is ten
  505.         mov     si,offset ansleds       ; The "LEDs"
  506.         cmp     flags.vtflg,ttvt100     ; VT100 mode?
  507.         je      disled1                 ; e = yes
  508.         mov     si,offset v52leds       ; try VT52
  509.         cmp     flags.vtflg,ttvt52      ; VT52?
  510.         je      disled1                 ; e = yes
  511.         mov     si,offset h19leds       ; use Heath-19
  512. disled1:lodsb                           ; Get a character
  513.         mov     ah,14                   ; Write character function
  514.         mov     bh,0                    ; Page zero
  515.         int     screen
  516.         loop    disled1                 ; Loop for all chars
  517.         mov     ah,2                    ; Reposition cursor when finished
  518.         mov     bh,0                    ; Page zero
  519.         mov     dx,cursor
  520.         call    direction               ; do Bios screen operation
  521.         call    atsctyp                 ; Reset right type of cursor
  522. disled2:ret
  523.  
  524.  
  525. ; ANSI terminal output routine.  Call with character in al.
  526.  
  527. anstty  proc    near                    ; ANSI terminal output
  528.         mov     dx,cursor               ; Some routines need cursor in dx
  529.         mov     kbiflg,0                ; Clear old flag value
  530.         test    yflags,trnctl           ; Debug mode?
  531.         jz      anstt1                  ; z = no
  532.         jmp     atdeb                   ; Yes - just translate control chars
  533. anstt1: cmp     ttkbi,0                 ; New keyboard input?
  534.         je      anstt2                  ; No - just continue
  535.         mov     kbiflg,1                ; Yes - set flag
  536.         mov     kbicsr,dx               ; Save old cursor
  537.         mov     ttkbi,0                 ; Clear this flag
  538.  
  539. anstt2: test    anspflg,vtcntp          ; print controller on?
  540.         jz      anstt4                  ; z = no
  541.         test    yflags,capt             ; capturing output?
  542.         jz      anstt3                  ; z = no, forget this part
  543.         push    ax                      ; save char
  544.         call    cptchr                  ; give it captured character
  545.         pop     ax                      ; restore character
  546. anstt3: jmp     ansmc                   ; print transparently
  547.                                         ; Set Display 7/8 bit filter
  548. anstt4: test    flags.remflg,d8bit      ; keep 8 bits for displays?
  549.         jnz     anstt5                  ; nz = yes, 8 bits if possible
  550.         and     al,7fh                  ; remove high bit
  551. anstt5: cmp     al,spc                  ; control char?
  552.         jb      anstt6                  ; b = yes
  553.         cmp     ttstate,offset atnrm    ; doing displayable text?
  554.         jne     anstt7                  ; ne = no, no translation
  555.                                         ; Set Translation filter
  556. anstt6: cmp     rxtable+256,0           ; translation turned off?
  557.         je      anstt7                  ; e = yes, no translation
  558.         mov     bx,offset rxtable       ; address of translate table
  559.         xlatb                           ; new char is in al
  560. anstt7: cmp     al,DEL                  ; ANSI Delete char?
  561.         je      atdel                   ; e = yes, ignore it before logging
  562.         cmp     al,0                    ; NUL char?
  563.         je      atign                   ; e = yes, ignore it before logging
  564.         test    yflags,capt             ; capturing output?
  565.         jz      anstt8                  ; z = no, forget this part
  566.         push    ax                      ; save char
  567.         call    cptchr                  ; give it captured character
  568.         pop     ax                      ; restore character and keep going
  569.                                         ; Direct char to processor module
  570. anstt8: cmp     al,20h                  ; Control character?
  571.         jb      atctrl                  ; b = yes, handle it
  572. anstt9: jmp     ttstate                 ; Nope, dispatch according to state
  573.  
  574. atign:  ret                             ; Something to be ignored
  575.  
  576. atctrl: mov     ah,0                    ; Make sure this is zero.
  577.         cmp     al,escape               ; an escape sequence starting?
  578.         je      atctrl1                 ; e = yes, don't print it
  579.         test    anspflg,vtautop+vtcntp  ; printing desired?
  580.         jz      atctrl1                 ; z = no
  581.         call    pntchr                  ; print char in al
  582. atctrl1:mov     di,ax                   ; Put it in an index register
  583.         shl     di,1                    ; Make it a word offset
  584.         jmp     ansspc[di]              ; Dispatch
  585.  
  586. atdel:  jmp     short atign             ; ignore DEL char
  587.  
  588. atdeb:  test    yflags,capt             ; capturing output?
  589.         jz      atdeb3                  ; z = no, forget this part
  590.         push    ax                      ; save char
  591.         call    cptchr                  ; give it captured character
  592.         pop     ax                      ; restore character and keep going
  593. atdeb3: mov     bh,ansflgs              ; Save flags and attribute
  594.         mov     bl,curattr
  595.         push    bx
  596.         push    word ptr mar_top        ; Save limited scrolling region
  597.         push    ax                      ; Save character for a second
  598.         mov     ah,curattr              ; Get attribute
  599.         call    brkatt                  ; Break it up
  600.         and     al,att_intensity        ; clear attributes, except bold bit
  601.         call    addatt                  ; Put it back together
  602.         mov     curattr,ah              ; Store
  603.         or      ansflgs,decawm          ; Set autowrap temporarily
  604.         mov     mar_top,0               ; Set scrolling region to entire page
  605.         mov     al,byte ptr low_rgt+1
  606.         mov     mar_bot,al
  607.         pop     ax                      ; Restore character
  608.         test    al,80h                  ; high bit set?
  609.         jz      atdeb0                  ; z = not set
  610.         push    ax                      ; Save the character for a second
  611.         mov     al,7eh                  ; Output a tilde
  612.         call    atnrm2
  613.         pop     ax                      ; Restore character
  614.         and     al,7fh                  ; and remove high bit
  615. atdeb0: cmp     al,del                  ; A DELETE?
  616.         je      atdeb1                  ; Yes - output "^?"
  617.         cmp     al,20h                  ; A control character?
  618.         jnb     atdeb2                  ; No - just output char in al
  619. atdeb1: push    ax                      ; Save the character for a second
  620.         mov     al,5eh                  ; Output a caret
  621.         call    atnrm2
  622.         pop     ax                      ; Restore character
  623.         add     al,40h                  ; Make ^letter (or ^? for DELETE)
  624.         and     al,7fh                  ; Clear bit 7 (for DELETE)
  625. atdeb2: call    atnrm2                  ; Output translated character
  626.         pop     word ptr mar_top        ; Restore scrolling region
  627.         pop     bx                      ; And flags and cursor attribute
  628.         mov     curattr,bl
  629.         mov     ansflgs,bh
  630.         ret
  631.  
  632. atnorm: mov     ttstate,offset atnrm    ; Reset state to "normal".
  633.         ret
  634.  
  635.                                         ; Normal character processor
  636. atnrm:  mov     bx,chr_set              ; Get character set
  637.         cmp     byte ptr [bx],ascset    ; standard US ascii?
  638.         je      atnrm2                  ; e = yes
  639.         cmp     byte ptr [bx],alcset    ; Alternate character set? [bk]
  640.         jne     atnrm0b                 ; ne = no [bk]
  641.         cmp     al,('a'-1)              ; replace a..z with 128d - (a..z) [bk]
  642.         jb      atnrm2                  ; b = out of range
  643.         cmp     al,'z'
  644.         ja      atnrm2                  ; a = out of range
  645.         add     al,(80h-('a'-1))        ; map up by 20h
  646.         jmp     short atnrm2
  647.  
  648. atnrm0b:cmp     byte ptr [bx],sgrset    ; "Special" set?
  649.         jne     atnrm1                  ; No - check UK
  650.         cmp     flags.vtflg,ttheath     ; Heath-19?
  651.         je      atnrm0a                 ; e = yes
  652.         cmp     al,137Q                 ; Yes - is it in the "special" range?
  653.         jb      atnrm2                  ; No - just output the char in al
  654.         mov     bl,al                   ; Yes - compute index in bx
  655.         mov     bh,0
  656.         sub     bx,137Q
  657.         mov     al,sgrtab[bx]           ; Fetch translation
  658.         jmp     short atnrm2            ; Output it
  659.  
  660. atnrm0a:cmp     al,94                   ; H-19, in range for special graphics?
  661.         jb      atnrm2                  ; b = no
  662.         cmp     al,126                  ; too large?
  663.         ja      atnrm2                  ; a = too large
  664.         sub     bx,94                   ; H-19, offset from caret
  665.         mov     bl,al
  666.         mov     bh,0
  667.         sub     bx,94
  668.         mov     al,hgrtab[bx]           ; fetch translation
  669.         jmp     short atnrm2
  670.  
  671. atnrm1: cmp     al,'#'                  ; This thing?
  672.         jne     atnrm2                  ; No - just output it
  673.         cmp     byte ptr [bx],ukset     ; Yes - UK set?
  674.         jne     atnrm2                  ; No - just output it
  675.         mov     al,156                  ; Yeah, show them our pound sign
  676. atnrm2: cmp     al,9bh                  ; ANSI CSI char?
  677.         jne     atnrm2b                 ; ne = no
  678.         jmp     at9bh                   ; yes, process ANSI CSI as "ESC ["
  679. atnrm2b:mov     dx,cursor               ; get cursor virtual position
  680.         push    ax                      ; save character
  681.         call    atscur                  ; set cursor physical position
  682.         pop     ax
  683.  
  684.         cmp     insmod,0                ; insert mode off?
  685.         je      atnrm3                  ; e = yes
  686.         push    ax                      ; save char
  687.         call    inschr                  ; open a char space in this line
  688.         push    bx
  689.         mov     bx,cursor               ; get current row
  690.         mov     bl,bh
  691.         mov     bh,0
  692.         cmp     linetype [bx],0         ; single width line?
  693.         je      atnrm2a                 ; e = yes
  694.         call    inschr                  ; open second space for double width
  695. atnrm2a:pop     bx
  696.         pop     ax                      ; restore char
  697. atnrm3:                                 ; set cursor before writing char
  698.         mov     bl,dh                   ; check for double characteristic
  699.         xor     bh,bh                   ; bx = row, in bl
  700.  
  701.         test    anspflg,vtautop         ; printing desired?
  702.         jz      atnrm4d                 ; e = no
  703.         call    pntchr                  ; print char in al
  704.         cmp     linetype [bx],0         ; normal characteristic?
  705.         je      atnrm4d                 ; e = yes
  706.         push    ax                      ; save current char
  707.         mov     al,' '                  ; add a space for double width
  708.         call    pntchr
  709.         pop     ax                      ; recover char to be processed
  710. atnrm4d:
  711.         cmp     linetype [bx],0         ; normal characteristic?
  712.         je      atnrm4a                 ; e = yes
  713.         push    ax                      ; save char
  714.         shl     dl,1                    ; double the column number
  715.         mov     ah,2                    ; set cursor (bh = 0 from above)
  716.         call    direction               ; do Bios screen operation
  717.         pop     ax                      ; recover the char
  718.         mov     ah,9                    ; Output char in al to screen
  719.         mov     bh,0                    ; Page zero
  720.         mov     bl,curattr              ; Current attribute
  721.         mov     cx,1                    ; Only one character
  722.         int     screen
  723.         inc     dl                      ; next column
  724.         mov     ah,2                    ; set cursor
  725.         call    direction               ; do Bios screen operation
  726.         mov     al,' '                  ; use a space for doubling
  727.         mov     ah,9                    ; Output to screen
  728.         mov     bh,0                    ; Page zero
  729.         mov     bl,curattr              ; Current attribute
  730.         mov     cx,1                    ; Only one character
  731.         int     screen
  732.         shr     dl,1                    ; keep "cursor" in single units
  733.         jmp     atnrm4b                 ; check autowrap in double width mode
  734.  
  735. atnrm4a:mov     ah,9                    ; Output to screen
  736.         mov     bh,0                    ; Page zero
  737.         mov     bl,curattr              ; Current attribute
  738.         mov     cx,1                    ; Only one character
  739.         int     screen
  740.                                         ; set physical cursor after this char
  741. atnrm4b:test    ansflgs,decawm          ; Autowrap?
  742.         jz      atnrm5                  ; No, continue
  743.         mov     cx,low_rgt              ; copy logical cursor margins to cx
  744.         push    bx
  745.         mov     bl,dh                   ; get row
  746.         xor     bh,bh
  747.         cmp     linetype[bx],0          ; single width line?
  748.         pop     bx                      ; pop preserves flags
  749.         je      atnrm4c                 ; e = yes, single
  750.         shr     cl,1                    ; halve right column # for wide chars
  751. atnrm4c:cmp     dl,cl                   ; wrote in right-most column?
  752.         jb      atnrm5                  ; b = no
  753.         inc     dl                      ; say want to use next column
  754.         cmp     flags.vtflg,ttheath     ; emulating a H-19? [uci]
  755.         je      atscur                  ; e = yes, show wrap now. [uci]
  756.         mov     cursor,dx               ; virtual cursor position
  757.         ret                             ; exit without moving cursor from eol
  758. atnrm5: mov     dx,cursor               ; Restore cursor position
  759.         inc     dl                      ; Bump cursor
  760.  
  761. atscur: cmp     dl,250                  ; To left of column zero?(wide screen)
  762.         jb      atscu1                  ; b = no, continue
  763.         mov     dl,0                    ; Yes - set at column zero
  764. atscu1: mov     cx,low_rgt              ; copy logical margins; cl=right col
  765.         push    bx
  766.         mov     bl,dh                   ; get row
  767.         xor     bh,bh
  768.         cmp     linetype [bx],0         ; single width lines?
  769.         pop     bx
  770.         je      atscu1a                 ; e = yes, single width
  771.         shr     cl,1                    ; halve column # for double wides
  772. atscu1a:cmp     dl,cl                   ; To right of right margin?
  773.         jbe     atscu3                  ; be = no, continue
  774.         mov     dl,cl                   ; Yes - assume no autowrap
  775.         test    ansflgs,decawm          ; Autowrap?
  776.         jz      atscu3                  ; No, continue
  777.         mov     dl,0                    ; Yes - set to column zero
  778.         cmp     dh,byte ptr low_rgt+1   ; at bottom of screen?
  779.         je      atscu1b                 ; e = yes
  780.         cmp     dh,mar_bot              ; At bottom of scrolling region?
  781.         jl      atscu2                  ; l = No - bump cursor and continue
  782. atscu1b:mov     scroll,1                ; scroll count = 1 line
  783.         call    atscru                  ; Scroll up
  784.         dec     dh                      ; offset inc dh below
  785. atscu2: inc     dh                      ; Just bump it
  786. atscu3: cmp     dh,0                    ; Constrain row to valid range
  787.         jge     atscu4                  ; ge = non-negative row, ok
  788.         mov     dh,0
  789. atscu4: cmp     dh,byte ptr low_rgt+1   ; 25th line?
  790.         jle     atscu5                  ; le = no
  791.         mov     dh,byte ptr low_rgt+1   ; set to 24th line
  792.         cmp     flags.vtflg,ttheath     ; emulating a Heath-19?
  793.         jne     atscu4a                 ; ne = no [hlk]
  794.         cmp     h19l25,0                ; Heath 25th line enabled?
  795.         je      atscu5                  ; e = no
  796. atscu4a:inc     dh                      ; yes, go to line 25 [hlk]
  797.         test    yflags,modoff           ; is mode line off?
  798.         jnz     atscu8                  ; nz = yes
  799.         push    dx                      ; save cursor position
  800.         call    trnmod                  ; no, turn it off now
  801.         and     yflags,not modoff       ; now say it's on (owned by host)
  802.         pop     dx
  803. atscu8: mov     flags.modflg,2          ; say mode line is owned by host
  804.         mov     al,yflags               ; place to communicate
  805.         call    telmsy                  ; tell msy the news
  806.  
  807. atscu5: push    cx                      ; save cx around screen call
  808.         mov     cursor,dx               ; Set cursor and return
  809.         mov     ah,2                    ; setup for position cursor call
  810.         mov     bl,dh                   ; get row
  811.         mov     bh,0
  812.         cmp     linetype [bx],0         ; single width line?
  813.         je      atscu5a                 ; e = yes
  814.         shl     dl,1                    ; double the column number
  815.         call    direction               ; do Bios screen operation
  816.         shr     dl,1                    ; restore dl (logical column)
  817.         jmp     short atscu5b
  818. atscu5a:call    direction               ; do Bios screen operation
  819. atscu5b:pop     cx
  820.         cmp     kbiflg,0                ; Is keyboard input flag set?
  821.         je      atscu6                  ; No - just return
  822.         test    vtflags,vsmarginbell    ; Yes - do we care?
  823.         jz      atscu6                  ; Return if no margin bell
  824.         mov     dx,cursor               ; Get new and old cursors
  825.         mov     bx,kbicsr
  826.         cmp     bh,dh                   ; Same row?
  827.         jne     atscu6                  ; No - just return
  828.         cmp     bl,belcol               ; Old cursor at or left of bell column?
  829.         ja      atscu6                  ; a = no, just return
  830.         cmp     dl,belcol               ; Yes - new cursor past bell column?
  831.         jbe     atscu6                  ; be = no, just return
  832.         call    vtbell                  ; Yes - ring the bell
  833. atscu6: ret
  834.  
  835. ; This routine is called to check the cursor position after any kind of cursor
  836. ; positioning command.  Note that cursor positioning does NOT cause scrolling
  837. ; on a VT100 (hence the need for a routine separate from this for "indexing".
  838. ;
  839. ; Call:         dx/     "new" cursor position (modified cursor)
  840. ;
  841. ; Return:       dx/     "new" cursor position adjusted for screen limits (if
  842. ;                       decom is reset), or scrolling region (if decom is set).
  843. ;
  844. ; Preserves ax, bx, and cx.
  845. ;
  846.  
  847. atccpc: push    bx                      ; save bx and cx
  848.         push    cx
  849. atccp7: mov     cx,low_rgt              ; margins, cl = right margin
  850.         mov     bl,dh                   ; get row
  851.         xor     bh,bh
  852.         cmp     linetype [bx],0         ; single width line?
  853.         je      atccp0                  ; e = yes, single width
  854.         shr     cl,1                    ; halve right margin for double wides
  855. atccp0: cmp     dl,250                  ; To left of left margin?(wide screen)
  856.         jb      atccp1                  ; b = no, go check right
  857.         mov     dl,0                    ; No, set to left margin
  858. atccp1: cmp     dl,cl                   ; To right of right margin
  859.         jbe     atccp2                  ; be = yes, go check top
  860.         mov     dl,cl                   ; No, set to right margin
  861. atccp2: test    ansflgs,decom           ; Origin mode set?
  862.         jnz     atccp5                  ; Yes, can't go out of scrolling region
  863.         cmp     dh,0                    ; Above top of screen?
  864.         jge     atccp3                  ; ge = no, check bottom
  865.         mov     dh,0                    ; Yes, stop here
  866. atccp3: cmp     dh,byte ptr low_rgt+1   ; Below bottom of screen?
  867.         jle     atccp4                  ; le = no, return
  868.         mov     dh,byte ptr low_rgt+1   ; Yes, stop at bottom margin
  869.         cmp     flags.vtflg,ttheath     ; Heath-19 mode?
  870.         jne     atccp4                  ; ne = no
  871.         cmp     h19l25,0                ; 25th line enabled?
  872.         je      atccp4                  ; e = no
  873.         inc     dh                      ; allow 25th line
  874. atccp4: pop     cx
  875.         pop     bx
  876.         ret
  877.  
  878. atccp5: cmp     dh,mar_top              ; Above top of scrolling region?
  879.         jge     atccp6                  ; ge = no, check bottom
  880.         mov     dh,mar_top              ; Yes, stop there
  881. atccp6: cmp     dh,mar_bot              ; Below bottom perhaps?
  882.         jle     atccp4                  ; le = no, return
  883.         mov     dh,mar_bot              ; Yes, stop at the bottom margin
  884.         pop     cx
  885.         pop     bx
  886.         ret
  887.  
  888.  
  889. ; This routine is called to adjust the cursor for the "indexing" like commands
  890. ; (e.g., index, reverse index, newline, etc.).  It contrains the cursor, and
  891. ; indicates if scrolling is necessary, and if so, in which direction.
  892. ;
  893. ; Call:         cursor/ "old" cursor position
  894. ;               dx/     "new" cursor position
  895. ;
  896. ; Return:       ax/     pointer to scrolling routine to call (or to a ret)
  897. ;               bx/     "old" cursor position
  898. ;               dx/     "new" cursor position adjusted for screen limits or
  899. ;                       scrolling region, depending on whether the original
  900. ;                       cursor position was inside or outside the scrolling
  901. ;                       region.
  902. ;
  903. ; On the VT100, a scroll does not occur unless the original cursor position
  904. ; was on the top or bottom margin.    This routine assumes that when decom is
  905. ; set the cursor position is set to the new origin, and that no other routine
  906. ; allows the cursor to be positioned outside the scrolling region as long
  907. ; as decom is set (which is the way a real VT100 works).  Note that for the
  908. ; normal case (no limited scrolling region defined) the margins are the same
  909. ; as the screen limits and scrolling occurs (as on a "normal" terminal) when
  910. ; an attempt is made to index off the screen. Preserves cx.
  911. ; Revised 16 June 1987 [jrd]
  912.  
  913. atccic: push    cx
  914.         mov     cx,low_rgt              ; get margins, cl = right margin
  915.         mov     bl,dh                   ; get row
  916.         xor     bh,bh
  917.         cmp     bl,ch                   ; Below screen?
  918.         ja      atcci0                  ; a = yes, use single width line
  919.         cmp     linetype[bx],0          ; single width chars?
  920.         je      atcci0                  ; e = yes, single width
  921.         shr     cl,1                    ; halve margin for double wides
  922. atcci0: mov     ax,offset atign         ; Assume no scrolling necessary
  923.         mov     bx,cursor               ; Get old cursor
  924.         cmp     dl,250                  ; To left of left margin?(wide screen)
  925.         jb      atcci1                  ; b = no, go check right
  926.         mov     dl,0                    ; No, set to left margin
  927. atcci1: cmp     dl,cl                   ; To right of right margin
  928.         jbe     atcci2                  ; be = yes, go check top
  929.         mov     dl,cl                   ; No, set to right margin
  930. atcci2: cmp     bh,mar_top              ; was old pos at scrolling top margin?
  931.         jne     atcci5                  ; ne = no, check other end
  932.         cmp     dh,mar_top              ; want to go above top margin?
  933.         jge     atcci7                  ; ge = no
  934.         mov     scroll,1
  935.         mov     ax,offset atscrd        ; Yes, indicate scroll down required
  936.         mov     dh,mar_top              ; Set to top margin
  937.         jmp     atcci7
  938.  
  939. atcci5: cmp     bh,mar_bot              ; Was old position at bottom margin?
  940.         jne     atcci7                  ; ne = no, so don't trap cursor
  941.         cmp     dh,mar_bot              ; want to go below?
  942.         jb      atcci7                  ; b = no, nothing to worry about
  943.         mov     scroll,1                ; 1 line
  944.         mov     ax,offset atscru        ; Yes, indicate scroll up required
  945. atcci6: mov     dh,mar_bot              ; Set to bottom margin
  946.         pop     cx
  947.         ret
  948. atcci7: pop     cx                      ; old pos was outside scrolling region
  949.         jmp     atccpc                  ; do full screen check and return
  950.  
  951. ; This routine picks an attribute apart into its component "parts" - the
  952. ; base attribute for the screen and the "extras" - i.e., blink, intensity
  953. ; and underline.
  954. ;
  955. ; Call:         ah/     a cursor attribute
  956. ;
  957. ; Return:       ah/     base attribute for screen (07H normal, 70H reverse).
  958. ;               al/     "extra" attributes
  959. ;
  960. ; Note that there is a complementary routine, addatt, for putting attributes
  961. ; back together.
  962. ;
  963.  
  964. brkatt: mov     al,0                    ; Clear returned "extra" attributes
  965.         cmp     crt_mode,7              ; monochrome display adapter mode?
  966.         jne     brkat2                  ; ne = no. cut this short for color
  967.         test    ah,att_low_mask         ; Any of these on?
  968.         jnz     brkat1                  ; Yes, can't be underline
  969.         test    ah,att_underline        ; Underline?
  970.         jz      brkat2                  ; No, some kind of reverse video
  971.         or      al,att_underline        ; Yes, say underline
  972.         test    ah,70h ;;att_reverse    ; Reverse video + underline?
  973.         jz      brkat1                  ; No, fix up low nibble
  974.         and     ah,not att_underline    ; Yes, clear the underline bit in ah
  975.         jmp short brkat2                ; And forge on
  976.  
  977. brkat1: or      ah,att_normal           ; Normal - turn on all normal bits
  978. brkat2: test    ah,att_intensity        ; Intensity attribute on?
  979.         jz      brkat3                  ; No - check blink
  980.         or      al,att_intensity        ; Yes - turn on the bit
  981. brkat3: test    ah,att_blink            ; Blink on?
  982.         jz      brkat4                  ; No - forge on
  983.         or      al,att_blink            ; Yes - turn on the bit
  984. brkat4: and     ah,not(att_intensity+att_blink) ;strip blink/bold, leave color
  985.         ret
  986.  
  987. ; This routine builds a cursor attribute given the base attribute for the
  988. ; screen background and the "extra" attributes we want (blink, etc.).
  989. ;
  990. ; Call:         ah/     base attribute for background (07H or 70H)
  991. ;               al/     "extra" attributes (89H for all three)
  992. ;
  993. ; Return:       ah/     base combined with "extras".
  994. ;
  995.  
  996. addatt: test    al,att_underline        ; Want underline?
  997.         jz      addat1                  ; No - no need for hack
  998.         and     ah,not att_low_mask     ; Yes - clear these bits
  999. addat1: or      ah,al                   ; Or in the attributes
  1000.         ret
  1001.  
  1002.  
  1003. ; This routine is called when we want to reverse everything on the screen
  1004. ; from normal to reverse video, or vice versa.  It is called only when
  1005. ; the decscnm attribute is changed.
  1006. ;
  1007. ; Call:         no arguments.
  1008. ;
  1009. ; This routine may destroy ax-dx
  1010. ;
  1011.  
  1012. revscn: mov     dh,byte ptr low_rgt+1   ; Compute last screen offset in ax
  1013.         inc     dh                      ; One more row to catch mode line
  1014.         mov     dl,crt_cols             ; physical width
  1015.         dec     dl                      ; and we count from 0
  1016.         call    scrloc
  1017.         mov     cx,ax                   ; Save it in cx for a minute
  1018.         mov     dx,0                    ; Compute first screen offset in ax
  1019.         call    scrloc
  1020.         sub     cx,ax                   ; Compute number of locs to change.
  1021.         add     cx,2
  1022.         sar     cx,1                    ; In 16-bit words please
  1023.         push    di                      ; Save some more acs
  1024.         push    es
  1025.         push    cx                      ; save word count for Topview
  1026.         push    ax                      ; save screen displacement
  1027.         call    scrseg                  ; Get address of screen in ax, es:di
  1028.         pop     ax                      ; recover displacement
  1029.         add     di,ax                   ; displacement addr of start of change
  1030.         call    scroff                  ; Turn screen off if color card
  1031. revsc1: mov     ax,es:[di]              ; Fetch a word
  1032.         mov     bl,al                   ; Save the character
  1033.         call    brkatt                  ; Break up the attributes
  1034.         rol     ah,1                    ; Reverse the video
  1035.         rol     ah,1                    ; Reverse the video
  1036.         rol     ah,1                    ; Reverse the video
  1037.         rol     ah,1                    ; Reverse the video
  1038.         call    addatt                  ; Put attributes back together
  1039.         mov     al,bl                   ; Restore character
  1040.         mov     es:[di],ax              ; Stuff into screen memory
  1041.         add     di,2                    ; Point di to next word of screen mem
  1042.         loop    revsc1                  ; Loop for entire screen
  1043.         pop     cx                      ; recover word count for Topview
  1044.         call    scrsync                 ; synch with Topview
  1045.         call    scron                   ; Turn screen back on if color card
  1046.         pop     es                      ; Restore segment register
  1047.         pop     di                      ; And destination index
  1048.         ret
  1049.  
  1050.  
  1051. ; Reset-everything routine.
  1052.  
  1053. atreset:mov     al,0                    ; Make cursor disappear for a while
  1054. ;;      call    csrtype
  1055.         mov     cursor,0                ; Cursor is at 0,0
  1056.         mov     ansflgs,0               ; reset these flags
  1057.         mov     escdec,0
  1058.         cmp     flags.vtflg,ttvt100     ; VT100?
  1059.         jne     atres7                  ; ne = no
  1060.         mov     ansflgs,decanm          ; turn on ANSI mode flag
  1061. atres7: mov     mar_top,0               ; Reset scrolling region
  1062.         mov     al,byte ptr low_rgt+1
  1063.         mov     mar_bot,al
  1064.         mov     ah,vtemu.vtflgst
  1065.         mov     vtemu.vtflgop,ah
  1066.         mov     vtflags,ah
  1067.         mov     insmod,0                ; reset insert mode
  1068.         mov     h19l25,0                ; clear heath 25th line enable
  1069.         mov     h19ctyp,1               ; Heath-19 cursor to underline
  1070.         mov     anspflg,0               ; clear printer flag
  1071.         mov     cx,4                    ; Initialize the "LEDs"
  1072.         mov     al,led_off              ; Turn them all off
  1073.         mov     di,offset ansleds+6     ; Point to the "LEDs"
  1074.         push    es                      ; save es
  1075.         push    ds
  1076.         pop     es                      ; use datas segment for es:di below
  1077.         cld                             ; set forward direction
  1078.         rep     stosb                   ; Do it
  1079.         pop     es
  1080.         call    disleds                 ; update mode line
  1081.         mov     vttabs,offset deftabs
  1082.         call    cpytabs                 ; Initialize tab stops
  1083.         call    chrdef                  ; Set default character set
  1084.         call    vtbell                  ; Ding bell like VT100
  1085.         test    vtflags,vsnewline       ; Want ANSI newline mode?
  1086.         jz      atres1                  ; No
  1087.         or      ansflgs,anslnm          ; Yes - set it in the mode flags
  1088. atres1: test    vtflags,vswrap          ; How about autowrap?
  1089.         jz      atres2                  ; No
  1090.         or      ansflgs,decawm          ; Yes - set it in the mode flags
  1091. atres2: mov     ah,att_normal           ; get present normal coloring
  1092.         call    brkatt                  ; separate color and blink/bold
  1093.         rol     ah,1                    ; reverse fore/back color fields
  1094.         rol     ah,1
  1095.         rol     ah,1
  1096.         rol     ah,1
  1097.         call    addatt                  ; put back blink/bold
  1098.         mov     att_reverse,ah          ; this is the reverse video code
  1099.         mov     al,att_normal           ; Assume normal video
  1100.         test    vtflags,vsscreen        ; Want reverse video?
  1101.         jz      atres3                  ; No
  1102.         or      ansflgs,decscnm         ; Yes - turn on the mode flag
  1103.         xchg    al,ah                   ; And reverse the video
  1104. atres3: mov     cx,slen                 ; typically 24 but do max lines
  1105.         mov     di,0
  1106. atres8: mov     linetype[di],0          ; clear the linetype array to single
  1107.         inc     di                      ; width/height characters
  1108.         loop    atres8
  1109.         mov     curattr,al              ; Give cursor and screen nice
  1110.         mov     scbattr,al              ; attributes.
  1111.         mov     oldbatr,al              ; place to remember long term
  1112.         mov     mlbattr,ah              ; Give the other to the mode line
  1113.         and     mlbattr,not att_intensity       ; turn off intensity bit
  1114.         mov     video_state,0           ; say normal video
  1115.         mov     ax,0                    ; Clear entire screen
  1116.         mov     bx,low_rgt
  1117.         mov     bl,crt_cols
  1118.         dec     bl                      ; do physical screen
  1119.         call    atsclr
  1120.         mov     dx,cursor               ; Set cursor to 0,0
  1121.         call    atscu5
  1122.         call    atsc                    ; Give saved cursor reasonable values
  1123.         call    atsctyp                 ; Set right cursor type
  1124.         mov     al,yflags
  1125.         call    telmsy                  ; update msy about ansflgs state
  1126.  
  1127.         test    yflags,modoff           ; is mode line off?
  1128.         jnz     atres9                  ; nz = yes
  1129.         push    dx                      ; save cursor position
  1130.         call    trnmod                  ; toggle off then on again so we
  1131.         call    trnmod                  ;   use it with current coloring
  1132.         pop     dx
  1133. atres9: ret
  1134.  
  1135. ; Routine to set cursor type (block, underline).
  1136.  
  1137. atsctyp:cmp     flags.vtflg,ttheath     ; Heath-19?
  1138.         jne     atsct0                  ; ne = no
  1139.         mov     al,h19ctyp              ; get cursor kind and on/off bit
  1140.         test    al,4                    ; is cursor to be off?
  1141.         jz      atsct1                  ; z = no, al has kind
  1142.         mov     al,0                    ; turn off cursor
  1143.         jmp     short atsct1            ; do it
  1144. atsct0: mov     al,1                    ; Assume underline
  1145.         test    vtemu.vtflgop,vscursor  ; Want block?
  1146.         jnz     atsct1                  ; nz = no, underline
  1147.         mov     al,2                    ; Yes
  1148. atsct1: call    csrtype                 ; Do it
  1149.         ret
  1150.  
  1151. ; Routine to set default character set.
  1152.  
  1153. chrdef: mov     al,vtemu.vtchset        ; get setup default character set
  1154. chrde1: mov     chr_sg0,al              ; reset character sets
  1155.         mov     chr_sg1,al
  1156.         mov     ax,offset chr_sg0       ; select character set zero
  1157.         mov     chr_set,ax
  1158.         ret
  1159. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;; end of part one ;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  1160. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;; start of part two ;;;;;;;;;;;;;;;;;;;;;;;;;;
  1161. ; Routine to set special graphics character set (used in VT52 mode).
  1162.  
  1163. chrsgs: mov     al,sgrset               ; Select "graphics" set
  1164.         jmp     chrde1                  ; Do it and return
  1165.  
  1166. ; Control-character handling routines
  1167.  
  1168. atbel:  call    vtbell                  ; Just ring bell and return
  1169.         ret
  1170.  
  1171. atbs:   cmp     dl,0                    ; Backspace. too far?
  1172.         je      atbs1                   ; e = at column 0 already
  1173.         dec     dl                      ; Backup cursor
  1174. atbs1:  call    atccpc                  ; Check range
  1175.         jmp     atscu5                  ; Set cursor and return
  1176.  
  1177. atht:   cmp     flags.vtflg,ttheath     ; Heath-19 mode?
  1178.         je      atht2                   ; e = yes. handle specially
  1179.         mov     ch,0
  1180.         mov     cl,byte ptr low_rgt
  1181.         cmp     dl,cl                   ; At or beyond last column?
  1182.         jae     atbs1                   ; Yes, check range, set cursor and ret
  1183.         mov     bh,0                    ; Make an index
  1184.         mov     bl,dl                   ; For column
  1185.         sub     cl,dl                   ; number of columns to examine
  1186. atht1:  inc     bx                      ; Tab always moves at least one space
  1187.         cmp     tabs[bx],0              ; Look for non-zero
  1188.         loopz   atht1
  1189.         mov     dl,bl                   ; Get the new row index
  1190.         jmp     atbs1                   ; Check range, set cursor, and return
  1191. atht2:  mov     dx,cursor               ; Heath-19. get cursor position
  1192.         add     dl,8                    ; tabs are every 8 columns
  1193.         and     dl,not 7                ; do modulo 8
  1194.         cmp     dl,byte ptr low_rgt     ; check against right edge
  1195.         jae     atht3                   ; ae = out of range
  1196.         jmp     atscu5                  ; set cursor and return
  1197. atht3:  test    ansflgs,decawm          ; doing line wrapping?
  1198.         jnz     atht4                   ; nz = yes. wrap to next line
  1199.         mov     dl,byte ptr low_rgt     ; else go to right margin
  1200.         jmp     atscu5                  ; set cursor and return
  1201. atht4:  inc     dh                      ; say want next line down
  1202.         xor     dl,dl                   ; and left margin
  1203.         call    atccic                  ; index check
  1204.         call    ax                      ; do any needed scrolling
  1205. atht4a: jmp     atscu5                  ; reset cursor
  1206.  
  1207. atlf:   cmp     flags.vtflg,ttheath     ; Heath-19 mode?
  1208.         je      atlf2                   ; e = yes
  1209.         test    ansflgs,anslnm          ; New-line mode?
  1210.         jz      atlf2                   ; No - just move to next line down
  1211.         mov     dl,0                    ; Yes - move to left margin also
  1212. atlf2:  inc     dh                      ; Index line down
  1213.         call    atccic                  ; Check indexing
  1214.         call    ax                      ; Call scrolling routine
  1215.         jmp     atscu5                  ; Set cursor
  1216.  
  1217. atcr:   mov     dl,0                    ; Go to left margin
  1218.         jmp     atscu5                  ; Set cursor and return
  1219.  
  1220. atff:   cmp     ttstate,offset atescf   ; parsing escape sequence?
  1221.         jne     atlf                    ; ne = no, do as line feed
  1222.         test    denyflg,200h            ; is auto Tek mode disabled?
  1223.         jnz     atlf                    ; nz = yes, treat as line feed
  1224.         call    atsc                    ; save cursor and associated data
  1225.         JMP     TEKESC                  ; Jump to Tektronix Emulator, al=FF
  1226.  
  1227. atso:   mov     ax,offset chr_sg1       ; Select set G1 and return
  1228.         mov     chr_set,ax
  1229.         ret
  1230.  
  1231. atsi:   mov     ax,offset chr_sg0       ; Select set G0 and return
  1232.         mov     chr_set,ax
  1233.         ret
  1234.  
  1235. atcan:  cmp     ttstate,offset atnrm    ; doing normal chars (vs esc seq)?
  1236.         jne     atcan1                  ; ne = no, assume esc seq
  1237.         jmp     atign                   ; ignore ^X, ^Z in normal mode
  1238. atcan1: mov     ttstate,offset atnrm    ; Reset state to "normal"
  1239.         mov     al,sgrtab+2             ; replace CAN (^X) by checkerboard
  1240.         jmp     atnrm                   ; Process char as a normal one
  1241.  
  1242. atesc:  mov     nansarg,0               ; Clear ANSI arguments
  1243.         mov     al,0
  1244.         mov     cx,lansarg
  1245.         mov     di,offset ansargs
  1246.         push    es
  1247.         push    ds
  1248.         pop     es                      ; use datas segment for es:di below
  1249.         cld                             ; set direction forward
  1250.         rep     stosb
  1251.         pop     es
  1252.         and     escdec,not decmode      ; Clear "DEC modes" flag
  1253.         mov     h19mod,0                ; clear Heath-19 mode flag
  1254.         mov     ttstate,offset atescf   ; Next state is escape follower
  1255.         ret
  1256.  
  1257. atescf: cmp     flags.vtflg,ttvt100     ; VT100?
  1258.         jne     atv52f                  ; ne = not VT100, try others
  1259. atescf0:mov     cx,lansesc              ; Escape follower - get table length
  1260.         mov     di,offset ansesc        ; Point di at table
  1261.         push    es
  1262.         push    ds
  1263.         pop     es                      ; use datas segment for es:di below
  1264.         cld                             ; set direction forward
  1265.         repne   scasb                   ; Find it
  1266.         pop     es
  1267.         je      atescf1                 ; Found - now go do something with it
  1268.         jmp     atnorm                  ; Not there - just ignore it
  1269.  
  1270. atescf1:mov     di,lansesc - 1          ; Compute word index into jump table
  1271.         sub     di,cx
  1272.         shl     di,1
  1273.         jmp     ansejt[di]              ; Dispatch to the routine
  1274.  
  1275. atv52f: cmp     flags.vtflg,ttheath     ; Heath-19?
  1276.         je      ath19f                  ; e = yes. Use Heath esc seqs
  1277.         mov     ttstate,offset atnrm    ; Assume state "normal" on return
  1278.         mov     cx,lv52esc              ; Get table length
  1279.         mov     di,offset v52esc        ; Point di at table
  1280.         push    es
  1281.         push    ds
  1282.         pop     es                      ; use datas segment for es:di below
  1283.         cld                             ; set direction forward
  1284.         repne   scasb                   ; Find it
  1285.         pop     es
  1286.         je      atv52f1                 ; Found - do something with it
  1287.         ret                             ; Not there - just ignore it
  1288.  
  1289. atv52f1:mov     di,lv52esc - 1          ; Compute word index into jump table
  1290.         sub     di,cx
  1291.         shl     di,1
  1292.         jmp     v52ejt[di]              ; Dispatch to the routine
  1293.  
  1294. ath19f: mov     ttstate,offset atnrm    ; Assume state "normal" on return
  1295.         test    ansflgs,decanm          ; ansi mode?
  1296.         jnz     atescf0                 ; nz = yes, use ansi table
  1297.         mov     cx,lh19esc              ; Get table length
  1298.         mov     di,offset h19esc        ; Point di at table
  1299.         push    es
  1300.         push    ds
  1301.         pop     es                      ; use datas segment for es:di below
  1302.         cld                             ; set direction forward
  1303.         repne   scasb                   ; Find it
  1304.         pop     es
  1305.         je      ath19f1                 ; Found - do something with it
  1306.         ret                             ; Not there - just ignore it
  1307.  
  1308. ath19f1:mov     di,lh19esc - 1          ; Compute word index into jump table
  1309.         sub     di,cx
  1310.         shl     di,1
  1311.         jmp     h19ejt[di]              ; Dispatch to the routine
  1312.  
  1313. at9bh:  call    atesc                   ; 9bH char (ANSI CSI == ESC [)
  1314.         mov     ttstate,offset atpaa    ; next state is parse ansi sequences
  1315.         ret
  1316.  
  1317. ; Escape follower routines.
  1318.  
  1319. atcsi:  mov     ttstate,offset atpaa    ; Next state is parse ansi args
  1320.         ret
  1321.  
  1322. atpaa:  test    al,80h                  ; high bit set?
  1323.         jz      atpaa6                  ; z = no
  1324.         and     al,7fh                  ; strip high bit
  1325.         cmp     al,' '                  ; control code remainder?
  1326.         jae     atpaa6                  ; ae = no, use 7 bit result
  1327.         mov     ttstate,offset atnrm    ; reset state to normal text
  1328.         jmp     atctrl                  ; execute 7 bit control code
  1329. atpaa6: cmp     al,'0'                  ; A digit?
  1330.         jb      atpaa1                  ; No - just ignore it
  1331.         cmp     al,'9'                  ; Maybe - A separator or final char?
  1332.         ja      atpaa2                  ; Perhaps - go check it out
  1333.         mov     cl,al                   ; A digit - convert ASCII to binary
  1334.         sub     cl,'0'
  1335.         mov     ch,0
  1336.         mov     bl,nansarg              ; put index in bx [dlk]
  1337.         xor     bh,bh
  1338.         mov     al,ansargs[bx]          ; Pick up what we've done so far [dlk]
  1339.         shl     al,1                    ; multiply by 10.  2 * al
  1340.         mov     ah,al                   ; save
  1341.         shl     al,1                    ; 4 * al
  1342.         shl     al,1                    ; 8 * al
  1343.         add     al,ah                   ; 10 * al
  1344.         mov     ah,0                    ; clear high field
  1345.         add     ax,cx                   ; add in this digit [dlk]
  1346.         cmp     ax,0feh                 ; max value is 0ffh [dlk]
  1347.         jbe     atpaa0                  ; be = ok [dlk]
  1348.         mov     al,0ffh                 ; set to max value [dlk]
  1349. atpaa0: mov     ansargs[bx],al          ; Put result back for next time [dlk]
  1350. atpaa1: ret                             ; And return
  1351.  
  1352. atpaa2: cmp     al,'?'                  ; The deadly question mark?
  1353.         jne     atpaa2a                 ; No - check further
  1354.         or      escdec,decmode          ; Yes - say DEC modes are coming
  1355.         ret                             ; And return
  1356. atpaa2a:cmp     al,'>'                  ; Heath private mode?
  1357.         jne     atpaa3                  ; ne = no
  1358.         cmp     flags.vtflg,ttheath     ; emulating a Heath-19?
  1359.         jne     atpaa3                  ; ne = no, ignore this sequence
  1360.         mov     h19mod,1                ; say Heath mode sequence follows
  1361.         ret
  1362.  
  1363. atpaa3: cmp     al,';'                  ; Argument separator?
  1364.         jne     atpaa4                  ; No - check for final char
  1365.         mov     al,nansarg              ; Get argument index
  1366.         inc     al                      ; Bump it
  1367.         cmp     al,lansarg              ; Too many?
  1368.         jl      atpa3a                  ; l = no, continue
  1369.         mov     ttstate,offset atnrm    ; Reset state to "normal"
  1370.         ret                             ; and pretend all is well
  1371. ; [jrd] jmp     atcan                   ; Yes - abandon sequence on error
  1372. atpa3a: mov     nansarg,al              ; Save it
  1373.         ret
  1374.  
  1375. atpaa4: mov     cx,lanstab
  1376.         mov     di,offset anstab        ; Look for it in the table
  1377.         push    es
  1378.         push    ds
  1379.         pop     es                      ; use datas segment for es:di below
  1380.         cld                             ; set direction forward
  1381.         repne   scasb
  1382.         pop     es
  1383.         je      atpaa5                  ; Found it - go dispatch
  1384.         cmp     al,40h                  ; in range for a legal terminator?
  1385.         jb      atpaa4a                 ; b = not in range, ignore
  1386.         cmp     al,7eh                  ; other end of the range
  1387.         ja      atpaa4a                 ; a = out of range, ignore
  1388.                                         ; in range, absorb and become normal
  1389.         mov     ttstate,offset atnrm    ; Put state back to normal
  1390. atpaa4a:ret                             ; Just return if it is unknown
  1391.  
  1392. atpaa5: mov     ttstate,offset atnrm    ; Put state back to normal
  1393.         mov     di,lanstab - 1          ; Compute word index into jump table
  1394.         sub     di,cx
  1395.         shl     di,1
  1396.         jmp     ansjmp[di]              ; Off into the wild blue
  1397.  
  1398. atind:  inc     dh                      ; Index - move cursor down one
  1399. atind1: call    atccic                  ; Check cursor position
  1400.         call    ax                      ; Scroll if necessary
  1401.         mov     ttstate,offset atnrm    ; Reset state
  1402.         jmp     atscu5                  ; Set cursor, etc. and return
  1403.  
  1404. atnel:  mov     dl,0                    ; Next line - sort of like CRLF
  1405.         inc     dh                      ; ... all in one command
  1406.         jmp     atind1                  ; Check cursor, etc., and return
  1407.  
  1408. atri:   dec     dh                      ; Reverse index
  1409.         jmp     atind1                  ; Check cursor, etc., and return
  1410.  
  1411. athts:  call    atccpc                  ; Make sure we have valid column number
  1412.         mov     dh,0                    ; Zap row
  1413.         mov     al,0FFH                 ; Indicates a tab stop
  1414.         mov     di,dx                   ; Dumb specialized registers
  1415.         mov     tabs[di],al             ; Store it
  1416.         jmp     atnorm                  ; Reset state and return
  1417.  
  1418. atsc:   mov     si,offset curattr       ; Save cursor, attribute, char set etc
  1419.         mov     di,offset savecu        ; Place to save the stuff
  1420.         mov     cx,lsavecu              ; Length of save area
  1421.         push    es                      ; save es
  1422.         push    ds
  1423.         pop     es                      ; set es to datas segment
  1424.         cld
  1425.         rep     movsb                   ; Save it
  1426.         pop     es
  1427.         mov     cl,ansflgs              ; Save a copy of the flags
  1428.         mov     savflgs,cl
  1429.         jmp     atnorm                  ; Reset state and return
  1430.  
  1431. atrc:   mov     si,offset savecu        ; Restore cursor, attributes, etc.
  1432.         mov     di,offset curattr       ; Where stuff goes
  1433.         mov     cx,lsavecu              ; Length of save area
  1434.         push    es                      ; save es
  1435.         push    ds
  1436.         pop     es                      ; set es to datas segment
  1437.         cld
  1438.         rep     movsb                   ; Put the stuff back
  1439.         pop     es
  1440.         mov     al,savflgs              ; Get saved flags
  1441.         xor     al,ansflgs              ; Exclusive-or with current flags
  1442.         test    al,decscnm              ; Did screen mode change?
  1443.         jz      atrc1                   ; No, just reset saved flags and leave
  1444.         mov     ah,curattr              ; Get cursor attribute that was saved
  1445.         call    brkatt                  ; Break into background & extra stuff
  1446.         rol     ah,1                    ; Reverse the background
  1447.         rol     ah,1                    ; Reverse the background
  1448.         rol     ah,1                    ; Reverse the background
  1449.         rol     ah,1                    ; Reverse the background
  1450.         call    addatt                  ; Put it all back together
  1451.         mov     curattr,ah              ; Store
  1452. atrc1:  mov     al,ansflgs              ; Reset flags in case called again
  1453.         and     al, not(decckm+deckpam+decom)  ; remove old bits [dlk]
  1454.         and     savflgs,(decckm+deckpam+decom) ; remove all but new bits [dlk]
  1455.         or      al,savflgs              ; restore saved bits [dlk]
  1456.         mov     ansflgs,al              ; update these flags [dlk]
  1457.         mov     savflgs,al
  1458.         mov     dx,cursor               ; Get cursor
  1459.         mov     kbiflg,0                ; Don't bother them with beeps here
  1460.         call    atscu5                  ; Set cursor
  1461.         jmp     atnorm                  ; Reset state and return
  1462.  
  1463. atkpam: or      ansflgs,deckpam         ; Turn on the bit
  1464.         mov     al,yflags
  1465.         call    telmsy                  ; inform msy of new state
  1466.         jmp     atnorm                  ; Reset state and return
  1467.  
  1468. atkpnm: and     ansflgs,not deckpam     ; Turn off the bit
  1469.         mov     al,yflags
  1470.         call    telmsy                  ; inform msy of new state
  1471.         jmp     atnorm                  ; Reset state and return
  1472.  
  1473. atris:  call    atreset                 ; Reset everything
  1474.         jmp     atnorm                  ; And state too, return, etc
  1475.  
  1476. atsg0:  mov     ttstate,offset atsg01   ; Setup to get last character
  1477.         ret
  1478.  
  1479. atsg01: call    atscs                   ; Get code for character set
  1480.         mov     chr_sg0,al              ; Store it
  1481.         jmp     atnorm                  ; Reset state etc. and return
  1482.  
  1483. atsg1:  mov     ttstate,offset atsg11   ; Setup to get last character
  1484.         ret
  1485.  
  1486. atsg11: call    atscs                   ; Get code for character set
  1487.         mov     chr_sg1,al              ; Store it
  1488.         jmp     atnorm                  ; Reset state etc. and return
  1489.  
  1490. atscs:  cmp     al,'A'                  ; UK ASCII set?
  1491.         jne     atscs1                  ; No
  1492.         mov     al,ukset                ; Yes - give them that and return
  1493.         ret
  1494.  
  1495. atscs1: cmp     al,'B'                  ; US ASCII set?
  1496.         jne     atscs3                  ; No
  1497. atscs2: mov     al,ascset               ; Yes - give them that and return
  1498.         ret
  1499.  
  1500. atscs3: cmp     al,'0'                  ; Special graphics set?
  1501.         jne     atscs4                  ; ne = no
  1502.         mov     al,sgrset               ; Yes - say that's what it is
  1503.         ret
  1504.  
  1505. atscs4: cmp     al,'1'                  ; alt char ROM, std char set?
  1506.         jne     atscs5                  ; ne = no
  1507.         mov     al,alcset               ; use Alternate character set
  1508.         ret
  1509.  
  1510. atscs5: cmp     al,'2'                  ; alt char ROM, special graphics?
  1511.         jne     atscs2                  ; ne = no, use US ASCII
  1512.         mov     al,sgrset               ; set graphics
  1513.         ret
  1514.  
  1515.                                         ; ESC # Pn  series
  1516. atsdhl: mov     ttstate,offset atsdbl   ; set up to parse argument
  1517.         ret
  1518. atsdbl: cmp     al,'3'                  ; Double high lines. Top half?
  1519.         je      atsdh2                  ; e = yes
  1520.         cmp     al,'4'                  ; bottom half?
  1521.         je      atsdh2                  ; e = yes
  1522.         cmp     al,'5'                  ; restore line to single width?
  1523.         je      atsdh1                  ; e = yes
  1524.         cmp     al,'6'                  ; double width single height?
  1525.         je      atsdh2                  ; e = yes
  1526.         cmp     al,'8'                  ; screen alignment?
  1527.         je      atsdh8                  ; e = yes
  1528.         jmp     atnorm                  ; else ignore
  1529. atsdh1: call    linesgl                 ; set line to single width
  1530.         jmp     atnorm
  1531. atsdh2: call    linedbl                 ; expand the line to double width
  1532.         jmp     atnorm                  ; set state to normal and ret
  1533. atsdh8: call    atalign                 ; do screen alignment
  1534.         jmp     atnorm
  1535. atpriv: mov     ttstate,offset atnorm   ; ignore next char
  1536.         ret                             ; and return to normal afterward
  1537.  
  1538. atalign proc    near                    ; Fill screen with 'E'
  1539.         call    atreset                 ; clear system
  1540.         or      ansflgs,decawm          ; set wrap
  1541.         mov     cl,byte ptr low_rgt     ; number of columns-1
  1542.         inc     cl
  1543.         mov     al,byte ptr low_rgt+1   ; number of rows-1
  1544.         inc     al
  1545.         mul     cl                      ; ax = number of chars on screen
  1546.         mov     cx,ax
  1547. atalig1:push    cx
  1548.         mov     al,'E'                  ; write screen full of E's
  1549.         call    atnrm                   ; write the 'E'
  1550.         pop     cx
  1551.         loop    atalig1                 ; cx times
  1552.         ret
  1553. atalign endp
  1554.  
  1555. ; This routine may be used to repeat a call to a selected action routine
  1556. ; for all of the ANSI parameters given in a call.   When the action routine
  1557. ; is called, si will contain the index for the current ANSI parameter (i.e.,
  1558. ; the current ANSI parameter may be gotten using ansargs[si] for an effective
  1559. ; address).     The action routine may modify any ACs it wants, but cx, si,
  1560. ; and di are preserved over the call to the action routine, so these may
  1561. ; not be used for building return values for the original caller.   Note that
  1562. ; if there are no ANSI parameters, the effect is the same as if one ANSI
  1563. ; parameter with a value of zero was given.
  1564. ;
  1565. ; Call:         di/     offset of action routine in code seqment
  1566. ;
  1567.  
  1568. atreps: mov     cl,nansarg              ; Pick up number of parameters
  1569.         inc     cl                      ; Zero parms is same as 1 zero parm
  1570.         mov     ch,0
  1571.         mov     si,0                    ; Init parm index
  1572. atrep1: push    cx                      ; Save important acs
  1573.         push    si
  1574.         push    di
  1575.         call    di                      ; Call indicated routine
  1576.         pop     di                      ; Restore acs
  1577.         pop     si
  1578.         pop     cx
  1579.         inc     si                      ; Advance to next parameter
  1580.         loop    atrep1                  ; Loop for all
  1581.         ret                             ; And return
  1582.  
  1583.  
  1584. ; Final char (ANSI) routines.
  1585.  
  1586. atcup:  mov     dh,ansargs              ; Get the two arguments
  1587.         mov     dl,ansargs+1
  1588.         cmp     dh,0                    ; Zero line number?
  1589.         jne     atcup1                  ; No - continue
  1590.         mov     dh,1                    ; Yes - default to one
  1591. atcup1: cmp     dl,0                    ; Ditto for row
  1592.         jne     atcup2
  1593.         mov     dl,1
  1594. atcup2: dec     dh                      ; Now normalize
  1595.         dec     dl
  1596.         test    ansflgs,decom           ; Origin mode?
  1597.         jz      atcup4                  ; No - skip this stuff
  1598.         add     dh,mar_top              ; Yes - it was relative to top margin
  1599.         jno     atcup4                  ; If no overflow, continue
  1600.         mov     dh,byte ptr low_rgt+1   ; Otherwise just set to screen bottom
  1601. atcup4: cmp     dh,byte ptr low_rgt+1   ; going to 25th line? [hlk]
  1602.         jbe     atcup5                  ; be = no [dlk]
  1603.         cmp     flags.vtflg,ttheath     ; emulating a Heath-19?
  1604.         jne     atcup6                  ; ne = no [hlk]
  1605.         cmp     h19l25,0                ; Heath 25th line enabled?
  1606.         je      atcup5                  ; e = no
  1607. atcup6: mov     dh,byte ptr low_rgt+1   ; bottom normal line
  1608.         inc     dh                      ; the 25th line
  1609.         jmp     atscu4                  ; set cursor position and return
  1610. atcup5: call    atccpc                  ; Check position
  1611.         jmp     atscu5                  ; Set cursor position and return
  1612.  
  1613. atcuarg:mov     al,ansargs              ; Get a cursor move argument
  1614.         cmp     al,0                    ; Zero?
  1615.         jne     atcua1                  ; No - return
  1616.         mov     al,1                    ; Yes - default to one
  1617. atcua1: ret                             ; Return
  1618.                                         ; Disallow movement to 25th line
  1619. atcuu:  call    atcuarg                 ; Get cursor move argument in al
  1620.         sub     dh,al                   ; Compute new cursor position
  1621.         jnc     atcuu1                  ; nc = ok [dlk]
  1622.         xor     dh,dh                   ; overflow, restrict range. [dlk]
  1623. atcuu1: call    atccic                  ; check indexing, ignore action in ax
  1624.         jmp     atscu5                  ; set the cursor at its new position
  1625.  
  1626. atcud:  call    atcuarg                 ; Get the argument
  1627.         add     dh,al                   ; Compute new cursor position
  1628.         jnc     atcud1                  ; nc = ok [dlk]
  1629.         mov     dh,byte ptr low_rgt+1   ; default bottom [dlk]
  1630. atcud1: call    atccic                  ; check indexing, ignore action in ax
  1631.         jmp     atscu5                  ; set the cursor at its new position
  1632.  
  1633.                                         ; Allow horiz movement on 25th line
  1634. atcuf:  call    atcuarg                 ; Get the argument
  1635.         add     dl,al                   ; Compute new cursor position
  1636.         jnc     atcup4                  ; If no carry, continue [dlk]
  1637.         mov     dl,byte ptr low_rgt     ; Else set to right margin
  1638.         jmp     atcup4                  ; Check/set cursor, return
  1639.  
  1640. atcub:  call    atcuarg                 ; Get the argument
  1641.         sub     dl,al                   ; Compute new cursor position
  1642.         jnc     atcup4                  ; If no carry, continue [dlk]
  1643.         mov     dl,0                    ; Else set to left margin
  1644.         jmp     atcup4                  ; Check/set cursor, return
  1645.  
  1646. ated:   mov     di,offset ated0         ; Routine to process parm
  1647.         call    atreps                  ; Do all selected parms
  1648.         ret
  1649.  
  1650. ated0:  cmp     ansargs[si],0           ; Was arg zero?
  1651.         jne     ated2                   ; No - continue
  1652.         mov     ax,dx               ; Yes - erase from cursor to end of screen
  1653.         cmp     dx,0                    ; cursor at home position?
  1654.         je      atedcom                 ; e = yes, roll screen before clear
  1655.         push    dx                      ; save dx
  1656.         mov     bl,dh                   ; get row number
  1657.         xor     bh,bh
  1658.         cmp     linetype [bx],0         ; single width line?
  1659.         je      ated0a                  ; e = yes
  1660.         shl     dl,1                    ; physical column is twice logical
  1661. ated0a: or      dl,dl                   ; starting at left margin?
  1662.         je      ated0b                  ; e = yes, this goes to single width
  1663.         inc     bl                      ; else start on next line
  1664. ated0b: cmp     bl,byte ptr low_rgt+1   ; at the end of the screen?
  1665.         ja      ated0c                  ; a = yes, stop singling-up
  1666.         mov     byte ptr linetype [bx],0 ; set to single width
  1667.         inc     bx
  1668.         jmp     short ated0b            ; loop, reset lines to end of screen
  1669. ated0c: mov     bx,low_rgt              ; erase from cursor to end of screen
  1670.         mov     bl,crt_cols
  1671.         dec     bl                      ; do physical screen width
  1672.         call    vtsclr                  ; Clear it
  1673.         pop     dx                      ; restore dx
  1674. ated1:  ret
  1675.  
  1676. ated2:  cmp     ansargs[si],1           ; Was arg one?
  1677.         jne     ated3                   ; No - continue
  1678.         mov     ax,0                    ; Yes -  erase from start of screen
  1679.                                         ;  to cursor, inclusive
  1680.         xor     bx,bx                   ; start at top row (0)
  1681. ated2b: cmp     bl,dh                   ; check rows from the top down
  1682.         jae     ated2c                  ; ae = at or below current line
  1683.         mov     byte ptr linetype [bx],0; set line to single width
  1684.         inc     bx                      ; inc row
  1685.         jmp     short ated2b            ; look at next line
  1686. ated2c: or      dl,dl                   ; at left margin of current line?
  1687.         jne     ated2d                  ; ne = no, leave line width intact
  1688.         mov     byte ptr linetype [bx],0 ; convert to single width
  1689. ated2d: mov     bl,dh                   ; get row number
  1690.         xor     bh,bh
  1691.         cmp     linetype [bx],0         ; single width line?
  1692.         je      ated2a                  ; e = yes
  1693.         shl     dl,1                    ; physical column is twice logical
  1694. ated2a: mov     bx,dx                   ; cursor position to bx
  1695.         call    vtsclr                  ; Clear it
  1696.         ret
  1697.  
  1698. ated3:  cmp     ansargs[si],2           ; Was arg two?
  1699.         jne     ated1                   ; ne = no, else erase entire screen
  1700.                                         ; entry to roll screen before erasing
  1701. atedcom:mov     al,byte ptr low_rgt+1   ; number of lines on screen
  1702.         mov     scroll,al
  1703.         call    atscru                  ; scroll them up before erasure
  1704.                                         ; removes double w/h lines too.
  1705.         mov     ax,0                    ; erase from here (home)
  1706.         mov     bx,low_rgt
  1707.         mov     bl,crt_cols
  1708.         dec     bl                      ; physical width (to here)
  1709.         call    vtsclr                  ; clear screen
  1710.         ret
  1711.  
  1712. atel:   mov     di,offset atel0         ; Get routine to call
  1713.         call    atreps                  ; Repeat for all parameters
  1714.         ret
  1715.  
  1716. atel0:  cmp     ansargs[si],0           ; Was arg zero?
  1717.         jne     atel2                   ; No - continue
  1718.         mov     ax,dx                   ; Yes - erase from cursor
  1719.         mov     bh,dh                   ; ...to end of line, inclusive
  1720.         push    bx
  1721.         mov     bl,bh                   ; get row
  1722.         mov     bh,0
  1723.         cmp     linetype [bx],0         ; single width line?
  1724.         je      atel0a                  ; e = yes
  1725.         shl     al,1                    ; physical column is twice logical
  1726. atel0a: pop     bx
  1727.         mov     bl,byte ptr low_rgt
  1728.         call    vtsclr                  ; Clear it
  1729. atel1:  ret
  1730.  
  1731. atel2:  cmp     ansargs[si],1           ; Was arg one?
  1732.         jne     atel3                   ; No - continue
  1733.         mov     ah,dh                   ; Yes -  erase from start of line
  1734.         mov     al,0
  1735.         mov     bx,dx                   ; ...to cursor, inclusive
  1736.         push    bx
  1737.         mov     bl,dh                   ; get row
  1738.         mov     bh,0
  1739.         cmp     linetype [bx],0         ; single width line?
  1740.         pop     bx                      ; pop does not affect flags
  1741.         je      atel2a                  ; e = yes
  1742.         shl     bl,1                    ; physical column is twice logical
  1743. atel2a:
  1744.         call    vtsclr                  ; Clear it
  1745.         ret
  1746.  
  1747. atel3:  cmp     ansargs[si],2           ; Was arg two?
  1748.         jne     atel1                   ; No - ignore it
  1749.         mov     ah,dh                   ; Yes - erase entire line
  1750.         mov     al,0
  1751.         mov     bh,dh
  1752.         mov     bl,byte ptr low_rgt
  1753.         mov     bl,crt_cols
  1754.         dec     bl                      ; physical line
  1755.         call    vtsclr                  ; Clear it
  1756.         ret
  1757.  
  1758. atsgr:  mov     ah,curattr              ; Get current cursor attribute
  1759.         call    brkatt                  ; Break it apart
  1760.         mov     di,offset atsgr1        ; Routine to call
  1761.         call    atreps                  ; Repeat for all parms
  1762.         call    addatt                  ; Put the attributes back together
  1763.         mov     curattr,ah              ; Store
  1764.         ret
  1765.  
  1766. atsgr1: mov     bl,ansargs[si]          ; Fetch an argument
  1767.         cmp     bl,0                    ; Zero?
  1768.         jne     atsgr2                  ; No
  1769.         mov     al,0                    ; Yes - clear the "extras"
  1770.         mov     ah,scbattr              ; And reset background
  1771.         and     ah,77h                  ; clear blink/bold here
  1772.         mov     video_state,0           ; say normal video now
  1773.         ret
  1774.  
  1775. atsgr2: cmp     bl,1                    ; One?
  1776.         jne     atsgr3                  ; No
  1777.         or      al,att_intensity        ; Yes - set bold
  1778.         ret
  1779.  
  1780. atsgr3: cmp     bl,4                    ; Four? Underline. Mods by [jrd]
  1781.         jne     atsgr4                  ; ne = no
  1782.         or      al,att_underline        ; Yes, set underscore
  1783.         cmp     crt_mode,7              ; monochrome display adapter mode?
  1784.         je      atsgr3a                 ; e = yes. Otherwise reverse video
  1785.                         ; use reversed video rather than blue on black
  1786.         and     al,not att_underline    ; clear underline and
  1787.         rol     ah,1                    ; reverse the colors
  1788.         rol     ah,1
  1789.         rol     ah,1
  1790.         rol     ah,1
  1791. atsgr3a:ret
  1792.  
  1793. atsgr4: cmp     bl,5                    ; Five?
  1794.         jne     atsgr5                  ; No
  1795.         or      al,att_blink            ; Yes - set blink
  1796.         ret
  1797.  
  1798. atsgr5: cmp     bl,7                    ; Seven?
  1799.         jne     atsgr6                  ; No - just ignore it
  1800.         cmp     video_state,0           ; is video normal?
  1801.         jne     atsgr6                  ; ne = no, reversed already, ignore
  1802.         rol     ah,1                    ; reverse the colors
  1803.         rol     ah,1
  1804.         rol     ah,1
  1805.         rol     ah,1
  1806.         mov     video_state,1           ; say reversed now
  1807.         ret
  1808.  
  1809. atsgr6: cmp     bl,30                   ; ANSI color series?
  1810.         jb      atsgrx                  ; b = no
  1811.         cmp     bl,37                   ; foreground set (30-37)?
  1812.         ja      atsgr7                  ; a = no, try background set
  1813.         sub     bl,30                   ; take away the bias
  1814.         and     ah,not 07H              ; clear foreground bits
  1815.         test    bl,1                    ; ANSI red?
  1816.         jz      atsgr6a                 ; z = no
  1817.         or      ah,4                    ; IBM red foreground bit
  1818. atsgr6a:test    bl,2                    ; ANSI & IBM green?
  1819.         jz      atsgr6b                 ; z = no
  1820.         or      ah,2                    ; IBM green foreground bit
  1821. atsgr6b:test    bl,4                    ; ANSI blue?
  1822.         jz      atsgr6c                 ; z = no
  1823.         or      ah,1                    ; IBM blue foreground bit
  1824. atsgr6c:ret
  1825.  
  1826. atsgr7: cmp     bl,40                   ; background color set?
  1827.         jb      atsgrx                  ; b = no
  1828.         cmp     bl,47                   ; background set is 40-47
  1829.         ja      atsgrx                  ; nb = no, not a color command
  1830.         sub     bl,40                   ; take away the bias
  1831.         and     ah,not 70H              ; clear background bits
  1832.         test    bl,1                    ; ANSI red?
  1833.         jz      atsgr7a                 ; z = no
  1834.         or      ah,40h                  ; IBM red background bit
  1835. atsgr7a:test    bl,2                    ; ANSI & IBM green?
  1836.         jz      atsgr7b                 ; z = no
  1837.         or      ah,20h                  ; IBM green background bit
  1838. atsgr7b:test    bl,4                    ; ANSI blue?
  1839.         jz      atsgrx                  ; z = no
  1840.         or      ah,10h                  ; IBM blue background bit
  1841.  
  1842. atsgrx: ret
  1843.  
  1844. attbc:  call    atccpc                  ; Make sure cursor is kosher
  1845.         mov     di,offset attbc0        ; Routine to call
  1846.         call    atreps                  ; Do for all parms
  1847.         ret
  1848.  
  1849. attbc0: cmp     ansargs[si],0           ; Was argument zero?
  1850.         jne     attbc2                  ; No - check further
  1851.         mov     dh,0                    ; Zap row for indexing
  1852.         mov     di,dx
  1853.         mov     tabs[di],0              ; clear tab stop
  1854. attbc1: ret
  1855.  
  1856. attbc2: cmp     ansargs[si],3           ; Was arg 3 (clear all tab stops)?
  1857.         jne     attbc1                  ; No - just ignore it
  1858.         mov     cx,swidth               ; Get ready to zap swidth columns
  1859.         mov     di,offset tabs          ; Point to the tab stop table
  1860.         mov     al,0                    ; zero indicates no tab stop
  1861.         push    es                      ; save es
  1862.         push    ds
  1863.         pop     es                      ; use datas segment for es:di below
  1864.         cld                             ; set direction forward
  1865.         rep     stosb                   ; Blit full of zeros
  1866.         pop     es
  1867.         ret
  1868.  
  1869. atstbm: mov     al,ansargs              ; Get the two line number args
  1870.         mov     ah,ansargs+1
  1871.         cmp     al,0                    ; Was first zero?
  1872.         jne     atstb1                  ; No - continue
  1873.         mov     al,1                    ; Yes - default is one
  1874. atstb1: cmp     ah,0                    ; Was second zero?
  1875.         jne     atstb2                  ; No - continue
  1876.         mov     ah,byte ptr low_rgt+1   ; Yes - default is last line on screen
  1877.         inc     ah
  1878. atstb2: dec     al                      ; Normalize to our coord. system
  1879.         dec     ah
  1880.         cmp     ah,al                   ; Is size of region at least two lines?
  1881.         jbe     atstb3                  ; be = if not, indicate an error
  1882.         cmp     al,0                    ; Check against screen limits
  1883.         jl      atstb3
  1884.         cmp     ah,byte ptr low_rgt+1
  1885.         ja      atstb3
  1886.         mov     mar_top,al              ; Set the limits
  1887.         mov     mar_bot,ah
  1888.         mov     dx,0                    ; Home cursor
  1889.         call    atccpc                  ; Check cursor (get it inside window)
  1890.         jmp     atscu5                  ; Set cursor position and return
  1891.  
  1892. atstb3: ret                             ; ignore bad requests
  1893. ;;;     jmp     atcan                   ; Indicate error and return
  1894.  
  1895. atda:   cmp     ansargs,0               ; Was argument zero?
  1896.         je      decid                   ; Yes - send the i.d. string
  1897.         ret                             ; No - only an echo
  1898. at52id: mov     ttstate,offset atnrm    ; ensure state is correct
  1899. decid:  mov     cx,20                   ; assumed length of asciiz string
  1900.         mov     si,offset dastr         ; Point to the string
  1901.         cmp     flags.vtflg,ttvt100     ; VT100?
  1902.         je      decid1                  ; e = yes
  1903.         mov     si,offset v52str        ; No - try VT52 i.d.
  1904.         cmp     flags.vtflg,ttvt52      ; Heath-19 mode?
  1905.         je      decid1                  ; e = yes
  1906.         mov     si,offset h19str        ; say Heath-19
  1907. decid1: cld
  1908.         lodsb                           ; Get a byte
  1909.         cmp     al,0                    ; end of string?
  1910.         je      decid2                  ; e = yes
  1911.         push    cx                      ; Save the important registers
  1912.         push    si
  1913.         call    prtbout                 ; Send it to port with no local echo
  1914.         pop     si
  1915.         pop     cx
  1916.         loop    decid1                  ; Loop for all characters
  1917. decid2: ret
  1918.  
  1919. atll:   mov     di,offset atleds        ; Get pointer to routine to call
  1920.         call    atreps                  ; Repeat for selective parameters
  1921.         ret
  1922.  
  1923. atleds: cmp     ansargs[si],0           ; Zero argument?
  1924.         jne     atled3                  ; No - check further
  1925.         mov     cx,4                    ; Reset the "LEDs"
  1926.         mov     al,led_off              ; to all off
  1927.         mov     di,offset ansleds+6     ; Point to the "LEDs"
  1928.         push    es                      ; save es
  1929.         push    ds
  1930.         pop     es                      ; make es:di point to datas seg
  1931.         cld                             ; move forward
  1932.         rep     stosb
  1933.         pop     es
  1934. atled1: call    disleds                 ; Update "LEDs" display and return
  1935. atled2: ret
  1936.  
  1937. atled3: mov     al,ansargs[si]          ; Get the argument
  1938.         cmp     al,1                    ; Must be .GE. 1
  1939.         jb      atled2                  ; If not just ignore it. [dlk]
  1940.         cmp     al,4                    ; Must be .LE. 4
  1941.         ja      atled2                  ; Ignore if not so. [dlk]
  1942.         dec     al                      ; Zero base it
  1943.         cbw                             ; Convert to index in ax
  1944.         mov     di,ax                   ; Dumb specialized registers
  1945.         add     al,'1'                  ; add ascii offset for digit
  1946.         mov     ansleds[di+6],al        ; Turn the "LED" on by storing digit
  1947.         jmp     atled1                  ; Update display and return
  1948.  
  1949. atreqt: cmp     ansargs,0               ; Want report?
  1950.         je      atreq1                  ; Yes - give report
  1951.         cmp     ansargs,1               ; Want report?
  1952.         je      atreq1                  ; Yes - give the report
  1953.         ret                             ; Gee, must have been an echo
  1954.  
  1955. atreq1: mov     al,escape               ; Send an escape to start off
  1956.         call    prtbout
  1957.         mov     al,'['                  ; Then one of these
  1958.         call    prtbout
  1959.         mov     al,'3'                  ; We only report on request
  1960.         cmp     ansargs,0               ; was argument a zero?
  1961.         jne     atreq1a                 ; ne = no
  1962.         mov     al,'2'                  ; yes
  1963. atreq1a:call    prtbout
  1964.         mov     al,';'                  ; Separate
  1965.         call    prtbout
  1966.         mov     bl,parcode              ; Get the parity code
  1967.         mov     bh,0
  1968.         mov     al,partab[bx]           ; Get VT100 parity code
  1969.         push    ax                      ; save parity code
  1970.         call    prtnout                 ; Send number to the port.
  1971.         mov     al,';'                  ; Separate
  1972.         call    prtbout
  1973.         mov     al,'2'                  ; Assume 7 data bits
  1974.         pop     bx                      ; get parity code into bl
  1975.         cmp     bl,1                    ; is parity none?
  1976.         jne     atreq2                  ; ne = no, so 7 data bits
  1977.         test    flags.remflg,d8bit      ; 8 bit display?
  1978.         jz      atreq2                  ; z = no
  1979.         mov     al,'1'                  ; must be eight
  1980. atreq2: call    prtbout                 ; Send it to the port
  1981.         mov     al,';'                  ; Separate
  1982.         call    prtbout
  1983.         mov     bl,baudidx              ; Baud rate index
  1984.         mov     bh,0
  1985.         mov     al,baudtab[bx]          ; Get DEC baud rate code
  1986.         push    ax
  1987.         call    prtnout                 ; Send it to the port
  1988.         mov     al,';'                  ; Separate
  1989.         call    prtbout                 ; Send it to the port
  1990.         pop     ax
  1991.         call    prtnout                 ; Send it to the port
  1992.         mov     al,';'                  ; Separate
  1993.         call    prtbout
  1994.         mov     al,'1'                  ; Clock rate multiplier is always 1
  1995.         call    prtbout
  1996.         mov     al,';'                  ; Separate (gasp - for the last time)
  1997.         call    prtbout
  1998.         mov     al,'0'                  ; Flags are always zero (no STP)
  1999.         call    prtbout
  2000.         mov     al,'x'                  ; Finally, say what this all was
  2001.         call    prtbout
  2002.         ret
  2003.  
  2004. atdsr:  mov     di,offset atdsr1        ; Routine to call
  2005.         call    atreps                  ; Do for all parms
  2006.         ret
  2007.  
  2008. atdsr1: cmp     ansargs[si],5           ; Want status?
  2009.         je      rpstat                  ; Yes - report status
  2010.         cmp     ansargs[si],6           ; Want cursor position?
  2011.         je      rpcup                   ; Yes - do it
  2012.         cmp     ansargs[si],15          ; Printer status?
  2013.         je      rpstap                  ; e = yes, do so
  2014.         ret                             ; No - must have been an echo
  2015.  
  2016. rpstat: mov     al,escape               ; Tell them we think we are OK
  2017.         call    prtbout
  2018.         mov     al,'['
  2019.         call    prtbout
  2020.         mov     al,'0'
  2021.         call    prtbout
  2022.         mov     al,'n'
  2023.         call    prtbout
  2024.         ret
  2025.  
  2026. rpstap: test    escdec,decmode          ; Printer status report from
  2027.         jz      rpstap3                 ; ESC [ ? 15 n  request
  2028.         mov     al,escape
  2029.         call    prtbout
  2030.         mov     al,'['
  2031.         call    prtbout
  2032.         mov     al,'?'
  2033.         call    prtbout
  2034.         mov     al,'1'
  2035.         call    prtbout
  2036.         mov     ah,ioctl                ; get printer status, via DOS
  2037.         mov     al,7                    ; status for output
  2038.         push    bx
  2039.         mov     bx,4                    ; std handle for system printer
  2040.         int     dos
  2041.         pop     bx
  2042.         jc      rpstap1                 ; c = call failed
  2043.         cmp     al,0ffh                 ; code for Ready
  2044.         jne     rpstap1                 ; ne = not ready
  2045.         mov     al,'0'                  ; ready, send final digit
  2046.         jmp     rpstap2
  2047. rpstap1:mov     al,'3'                  ; not ready, say printer disconnected
  2048. rpstap2:call    prtbout
  2049.         mov     al,'n'                  ; final char of response
  2050.         call    prtbout
  2051. rpstap3:ret
  2052.  
  2053. rpcup:  mov     al,escape               ; Cursor position - send an escape
  2054.         call    prtbout
  2055.         mov     al,'['                  ; And one of these
  2056.         call    prtbout
  2057.         mov     al,byte ptr cursor+1    ; Get row
  2058.         inc     al                      ; They use coords that start at 1
  2059.         test    ansflgs,decom           ; Origin mode set?
  2060.         jz      rpcup1                  ; No - continue
  2061.         sub     al,mar_top              ; Yes - subtract off top margin
  2062. rpcup1: call    prtnout                 ; Output the number
  2063.         mov     al,';'                  ; Separate
  2064.         call    prtbout
  2065.         mov     al,byte ptr cursor      ; Now get the column number
  2066.         inc     al                      ; Their coords start at 1
  2067.         call    prtnout                 ; Send it off to the port
  2068.         mov     al,'R'                  ; Finally end it with this
  2069.         call    prtbout
  2070.         ret
  2071.  
  2072.                                         ; ESC [ ? xxx h/l  series
  2073. atrm:   mov     modeset,0               ; Say we are resetting modes
  2074.         mov     di,offset atrsm         ; Reset/set modes
  2075.         call    atreps                  ; Repeat for all parms
  2076.         test    ansflgs,decanm          ; Did this get reset?
  2077.         jnz     atrm1                   ; No - return
  2078.         cmp     flags.vtflg,ttheath     ; were we a Heath-19?
  2079.         je      atrm0                   ; e = yes, don't change terminal types
  2080.         mov     flags.vtflg,ttvt52      ; Yes. Say VT52 now
  2081. atrm0:  call    chrdef                  ; Yes - set default char sets
  2082.         call    atsc                    ; Save cursor status
  2083.         call    disleds                 ; update terminal type
  2084. atrm1:  ret
  2085.  
  2086. atsm:   mov     modeset,1               ; Say we are setting modes
  2087.         mov     di,offset atrsm         ; Reset/set modes
  2088.         call    atreps                  ; Repeat for all parms
  2089.         ret
  2090.  
  2091. atrsm:  mov     al,ansargs[si]          ; Pick up the argument
  2092.         test    escdec,decmode          ; Is this DEC private mode ([ ?)stuff?
  2093.         jnz     atrsm1                  ; nz = yes - go check it out
  2094.         cmp     h19mod,0                ; Heath-19 private mode ([ >)?
  2095.         je      atrsma                  ; e = no
  2096.         jmp     htrsm1                  ; yes, do Heath specific things
  2097. atrsma: cmp     al,20                   ; No - ANSI new-line mode?
  2098.         jne     atrsm0                  ;  but try insert mode
  2099.         and     vtemu.vtflgop,not vsnewline ; assume resetting
  2100.         cmp     modeset,0               ; resetting?
  2101.         je      atrsmb                  ; e = yes
  2102.         or      vtemu.vtflgop,vsnewline ; setting
  2103. atrsmb: mov     al,anslnm               ; Yes - get the bit
  2104.         call    atrsflg                 ; Set or reset it
  2105.         ret
  2106. atrsm0: cmp     al,4                    ; toggle insert mode?
  2107.         jne     atrsmc                  ; ne = no
  2108.         mov     al,modeset              ; set/reset insert mode
  2109.         mov     insmod,al               ; store it
  2110.         ret
  2111. atrsmc: cmp     al,12                   ; 12? Control local echo
  2112.         jne     atrsmx                  ; ne = no
  2113.         cmp     modeset,0               ; resetting mode (ESC [ 12 l)?
  2114.         jne     atrsmc1                 ; ne = no
  2115.         or      ansflgs,dececho         ; remember state here too
  2116.         or      yflags,lclecho          ; (l) turn on local echoing
  2117.         jmp     short atrsmc2
  2118. atrsmc1:and     yflags,not lclecho      ; (h) turn off local echoing
  2119.         and     ansflgs,not dececho
  2120. atrsmc2:mov     al,yflags
  2121.         call    telmsy                  ; inform msy about echoing state
  2122.         test    yflags,modoff           ; is mode line off?
  2123.         jnz     atrsmx                  ; nz = yes
  2124.         push    dx                      ; save cursor position
  2125.         call    trnmod                  ; toggle off then on again so we
  2126.         call    trnmod                  ;   use it with current coloring
  2127.         pop     dx
  2128. atrsmx: ret
  2129.  
  2130. atrsm1: cmp     al,1                    ; Cursor keys mode?
  2131.         jne     atrsm2                  ; No - check some more
  2132.         mov     al,decckm               ; Yes - get the bit
  2133.         jmp     atrsflg                 ; Set or reset it and return
  2134.  
  2135. atrsm2: cmp     al,7                    ; Auto-wrap?
  2136.         jne     atrsm3                  ; No - check some more
  2137.         and     vtemu.vtflgop,not vswrap ; assume resetting line wrap
  2138.         cmp     modeset,0               ; resetting?
  2139.         je      atrsm2a                 ; e = yes
  2140.         or      vtemu.vtflgop,vswrap    ; set the bit
  2141. atrsm2a:mov     al,decawm               ; Yes - get the bit
  2142.         jmp     atrsflg                 ; Set or reset it and return
  2143.  
  2144. atrsm3: cmp     al,6                    ; Origin mode?
  2145.         jne     atrsm4                  ; No - check for video change
  2146.         jmp     atrsom                  ; Yes - change decom and return
  2147.  
  2148. atrsm4: cmp     al,5                    ; Change the video?
  2149.         jne     atrsm5                  ; No - check for VT52 mode set/reset
  2150.         jmp     atrsscnm                ; Yes - change it if we have to and ret
  2151.  
  2152. atrsm5: cmp     al,2                    ; Change VT52 compatibility mode?
  2153.         jne     atrsm6                  ; No - ignore unknown DEC private modes
  2154.         cmp     flags.vtflg,ttheath     ; Heath-19 mode?
  2155.         je      atrsm5a                 ; e = yes, handle specially
  2156.         mov     al,ascset               ; return to US ascii graphics sets
  2157.         mov     chr_sg0,al              ; Store it
  2158.         mov     chr_sg1,al              ; Store it
  2159.         mov     al,decanm               ; Yes - get the flag
  2160.         jmp     atrsflg                 ; Set or reset it and return
  2161.  
  2162. atrsm5a:mov     modeset,0               ; Heath-19 ESC [ ? 2 h, reset ansi
  2163.         mov     al,decanm               ; the flag needing adjustment
  2164.         jmp     atrsflg                 ; reset the flag and return
  2165.  
  2166. atrsm6: cmp     al,3                    ; 132/80 column mode change?
  2167.         jne     atrsm7                  ; ne = no
  2168.         push    chr_set                 ; save character set pointer
  2169.         push    word ptr chr_sg0        ; and the G0/G1 values
  2170.         mov     al,ansflgs              ; these flags
  2171.         mov     ah,vtflags
  2172.         push    ax
  2173.         mov     al,curattr              ; and current video attributes
  2174.         push    ax
  2175.         mov     al,modeset              ; pass set/reset request to chgdsp[dlk]
  2176.         call    chgdsp                  ; call Change Display proc in msy [dlk]
  2177.         call    scrmod                  ; get current screen mode
  2178.         cmp     modeset,1               ; want 132 cols?
  2179.         jne     atrsm6n                 ; ne = no, so use 80 columns
  2180.         mov     al,crt_cols             ; get current physical screen width
  2181.         dec     al                      ; we count from column 0 here
  2182.         mov     byte ptr low_rgt,al     ; screen capability
  2183.         mov     linelen,131             ; say using wide screen, if possible
  2184.         jmp     short atrsm6e
  2185. atrsm6n:mov     linelen,79              ; say using 80 columns
  2186.         cmp     byte ptr low_rgt,79     ; want 80 cols, is it wider?
  2187.         jbe     atrsm6e                 ; be = no
  2188.         mov     byte ptr low_rgt,79     ; narrow down to 80 columns
  2189. atrsm6e:CALL    ATRES2                  ; do partial reset of emulator
  2190.         pop     ax
  2191.         mov     curattr,al              ; restore saved items
  2192.         pop     ax
  2193.         mov     ansflgs,al
  2194.         mov     vtflags,ah
  2195.         pop     word ptr chr_sg0        ; restore the G0/G1 values
  2196.         pop     chr_set                 ; and character set pointer
  2197.         mov     dl,byte ptr low_rgt+1   ; text lines (leave status line intact)
  2198.         mov     mar_top,0
  2199.         mov     mar_bot,dl              ; reset scrolling region
  2200.         xor     dx,dx                   ; new cursor position is 0,0
  2201.         mov     cursor,dx
  2202.         jmp     atscu5                  ; place it there and return
  2203.  
  2204. atrsm7: cmp     al,18                   ; 18?  18 & 19 = printer support
  2205.         jne     atrsm8                  ; ne = no
  2206.         cmp     modeset,0               ; resetting?
  2207.         jne     atrsm7a                 ; ne = no, setting
  2208.         and     anspflg,not vtffp       ; no form feed after printing
  2209.         ret
  2210. atrsm7a:or      anspflg,vtffp           ; use form feed after printing
  2211.         ret
  2212.  
  2213. atrsm8: cmp     al,19                   ; 19?
  2214.         jne     atrsm9                  ; ne = no
  2215.         cmp     modeset,0               ; resetting?
  2216.         jne     atrsm8a                 ; ne = no, setting
  2217.         and     anspflg,not vtextp      ; reset print region to scrolling reg
  2218.         ret
  2219. atrsm8a:or      anspflg,vtextp          ; set print region to whole screen
  2220.         ret
  2221.  
  2222. atrsm9: cmp     al,34                   ; ESC [ ? 34 h/l? Invoke special macro
  2223.         jne     atrsm10                 ; ne = no
  2224.         cmp     modeset,0               ; resetting?
  2225.         jne     atrsm9a                 ; ne = no, setting
  2226.         jmp     vtrmac                  ; jump to perform on-line macro
  2227.                                         ;  code is located in file msy
  2228. atrsm9a:jmp     vtsmac                  ; do set macro
  2229.  
  2230. atrsm10:cmp     al,38                   ; 38? Enter Tek sub-mode. VT340 seq
  2231.         jne     atrsm11                 ; ne = no
  2232.         cmp     modeset,1               ; setting mode (ESC [ ? 38 h)?
  2233.         jne     atrsm11                 ; ne = no, ignore sequence
  2234.         test    denyflg,200h            ; is auto Tek mode disabled?
  2235.         jnz     atrsm11                 ; nz = yes, just ignore command
  2236.         call    atsc                    ; save cursor and associated data
  2237.         mov     al,0                    ; enter with this received character
  2238.         JMP     TEKEMU                  ; Jump to Tektronix Emulator, al=null
  2239.  
  2240. atrsm11:ret
  2241.                 ; Heath-19  ESC [ > Ps h or l where Ps = 1, 4, 7, or 9
  2242. htrsm1: cmp     al,1                    ; 25th line?
  2243.         jne     htrsm4                  ; ne = no
  2244.         mov     al,modeset              ; set/reset flag
  2245.         mov     h19l25,al
  2246.         cmp     al,0                    ; resetting? Mods from Dave Tweten
  2247.         jne     htrsmx                  ; ne = no, enabling. we are done
  2248.         mov     ah,byte ptr low_rgt+1   ; point to status (25th) line
  2249.         inc     ah                      ;  which is here
  2250.         xor     al,al                   ; from column 0
  2251.         mov     bh,ah                   ; to same line
  2252.         mov     bl,crt_cols             ; physical width
  2253.         dec     bl                      ; we count from 0
  2254.         jmp     vtsclr                  ; disabling status line clears it
  2255.  
  2256. htrsm4: cmp     al,4                    ; block/line cursor?
  2257.         jne     htrsm5                  ; ne = no
  2258.         and     h19ctyp,4               ; save on/off bit (4)
  2259.         cmp     modeset,0               ; reset?
  2260.         je      htrsm4a                 ; e = yes
  2261.         or      h19ctyp,2               ; remember block kind here
  2262.         jmp     atsctyp
  2263. htrsm4a:or      h19ctyp,1               ; remember underline kind here
  2264.         jmp     atsctyp
  2265.  
  2266. htrsm5: cmp     al,5                    ; on/off cursor?
  2267.         jne     htrsm7                  ; ne = no
  2268.         cmp     modeset,0               ; on?
  2269.         je      htrsm5a                 ; e = yes
  2270.         or      h19ctyp,4               ; remember off state in this bit
  2271.         jmp     atsctyp
  2272. htrsm5a:and     h19ctyp,not 4           ; set cursor on
  2273.         jmp     atsctyp
  2274.  
  2275. htrsm7: cmp     al,7                    ; alternate application keypad?
  2276.         jne     htrsm9                  ; ne = no
  2277.         mov     al,deckpam              ; get keypad application mode bit
  2278.         jmp     atrsflg                 ; set or reset appl keypad mode
  2279.  
  2280. htrsm9: cmp     al,9                    ; auto newline mode? (add cr to lf)
  2281.         jne     htrsmx                  ; ne = no
  2282.         mov     al,anslnm               ; get the bit
  2283.         jmp     atrsflg                 ; set or reset newline mode
  2284.  
  2285. htrsmx: ret                             ; ignore the code
  2286.  
  2287. atrsflg:cmp     modeset,0               ; Want to reset
  2288.         je      atrsf1                  ; Yes - reset it
  2289.         or      ansflgs,al              ; No, set. OR in the flag
  2290.         test    al,decanm               ; Changing terminal type?
  2291.         jz      atrsfx                  ; z = no
  2292.         cmp     flags.vtflg,ttheath     ; in Heath-19 mode?
  2293.         je      atrsfx                  ; e = yes, don't flip terminal kinds
  2294.         mov     flags.vtflg,ttvt100     ; say VT100 now
  2295.         jmp     short atrsfx
  2296. atrsf1: not     al                      ; Complement
  2297.         and     ansflgs,al              ; Clear the bit
  2298.         not     al                      ; recover the bit
  2299.         test    al,decanm               ; Changing terminal type?
  2300.         jz      atrsfx                  ; z = no
  2301.         cmp     flags.vtflg,ttheath     ; in Heath-19 mode?
  2302.         je      atrsfx                  ; e = yes, don't flip terminal kinds
  2303.         mov     flags.vtflg,ttvt52      ; say VT52 now
  2304. atrsfx: push    ax
  2305.         mov     al,yflags
  2306.         call    telmsy                  ; tell msy file about new state
  2307.         pop     ax
  2308.         ret
  2309.  
  2310. atrsom: cmp     modeset,0               ; Clearing DEC origin mode?
  2311.         jne     atrsom1                 ; ne = no, setting
  2312.         and     ansflgs,not (decom)     ; clear the bit
  2313.         mov     dx,0                    ; go to the home position
  2314.         jmp     atscu5                  ; set cursor and return
  2315. atrsom1:or      ansflgs,decom           ; Set Origin mode
  2316.         mov     dx,cursor               ; Get the cursor
  2317.         mov     dl,0                    ; go to right margin
  2318.         mov     dh,mar_top              ; go to home of scrolling region
  2319.         jmp     atscu5                  ; Set the cursor and return
  2320.  
  2321. atrsscnm:
  2322.         cmp     modeset,0               ; Setting or resetting?
  2323.         je      atrss1                  ; Do reset
  2324.         test    ansflgs,decscnm         ; Setting. Is it set already?
  2325.         jnz     atrss3                  ; Yes. Don't do it again
  2326.         or      ansflgs,decscnm         ; No. Set it
  2327.         or      vtemu.vtflgop,vsscreen  ; tell Status display
  2328.         or      vtflags,vsscreen        ; and our local flags
  2329.         mov     al,att_reverse          ; Want reverse video
  2330.         jmp     short atrss2            ; Do it
  2331.  
  2332. atrss1: test    ansflgs,decscnm         ; Resetting. Is it reset already?
  2333.         jz      atrss3                  ; Yes.  Don't do it again
  2334.         and     ansflgs,not decscnm     ; No. Clear it
  2335.         and     vtemu.vtflgop,not vsscreen      ; tell Status display
  2336.         and     vtflags,not vsscreen    ; and our local flags
  2337.         mov     al,att_normal           ; Want normal video
  2338.                                         ; Fall through to atrss2
  2339.  
  2340. ; Note: This is also called from the stblmds initialization routine.
  2341.  
  2342. atrss2: push    ax
  2343.         mov     scbattr,al              ; Set screen background attribute
  2344.         mov     oldbatr,al              ; update long term memory too
  2345.         mov     ah,al                   ; place where brkatt works
  2346.         call    brkatt                  ; separate color and specials
  2347.         rol     ah,1                    ; Reverse the reversal (sic.)
  2348.         rol     ah,1                    ; Reverse the reversal (sic.)
  2349.         rol     ah,1                    ; Reverse the reversal (sic.)
  2350.         rol     ah,1                    ; Reverse the reversal (sic.)
  2351.         call    addatt                  ; put blink/bold bits back in
  2352.         mov     mlbattr,ah              ; For mode line background
  2353.         mov     ah,curattr              ; Get current cursor attribute
  2354.         call    brkatt                  ; Break it up
  2355.         rol     ah,1                    ; Reverse its background
  2356.         rol     ah,1                    ; Reverse its background
  2357.         rol     ah,1                    ; Reverse its background
  2358.         rol     ah,1                    ; Reverse its background
  2359.         call    addatt                  ; Put it back together
  2360.         mov     curattr,ah              ; And store it
  2361.         pop     ax
  2362.         call    revscn                  ; Reverse everything on the screen
  2363. atrss3: ret
  2364.  
  2365.  
  2366. atctst: mov     al,0                    ; Init test weight
  2367.         mov     di,offset atcts2        ; Routine to call
  2368.         call    atreps                  ; Repeat for all parms
  2369.         test    al,80H                  ; Want to reset?
  2370.         jz      atcts1                  ; No - return
  2371.         call    atreset                 ; Yes - reset everything
  2372. atcts1: ret
  2373.  
  2374. atcts2: mov     ah,ansargs[si]          ; Pick up an argument
  2375.         cmp     ah,0                    ; Zero?
  2376.         jne     atcts3                  ; No - ignore others
  2377.         or      al,80H                  ; Yes - say we want reset
  2378. atcts3: ret
  2379.  
  2380.  
  2381. ; VT52 compatibility mode routines.
  2382.  
  2383. ; Return to ANSI mode.
  2384.  
  2385. v52ans: or      ansflgs,decanm          ; Turn ANSI flag back on
  2386.         mov     flags.vtflg,ttvt100     ; Say VT100 now
  2387.         call    chrdef                  ; Set default char sets
  2388.         call    atsc                    ; Save cursor status
  2389.         call    disleds                 ; Put "LEDs" back
  2390.         jmp     atnorm                  ; Reset state to normal and return
  2391.  
  2392. ; Reset VT52 (does NOT cause return to VT100 mode)
  2393.  
  2394. v52ris: call    atreset                 ; Reset everything
  2395.         call    disleds                 ; Put "LEDs" back
  2396.         ret
  2397.  
  2398. ; Enter VT52 "graphics" mode.
  2399.  
  2400. v52egm: call    chrsgs                  ; Set "graphics" char set
  2401.         jmp     atnorm                  ; Reset state to normal and return
  2402.  
  2403. ; Exit VT52 "graphics" mode.
  2404.  
  2405. v52xgm: call    chrdef                  ; Set default character set
  2406.         jmp     atnorm                  ; Reset state to normal and return
  2407.  
  2408. ; VT52 cursor positioning.
  2409.  
  2410. v52pos: mov     ttstate,offset v52pc1   ; Next state
  2411.         ret
  2412.  
  2413. v52pc1: sub     al,' '-1                ; Minus offset
  2414.         mov     ansargs,al              ; Stash it here
  2415.         mov     ttstate,offset v52pc2   ; Next state
  2416.         ret
  2417.  
  2418. v52pc2: sub     al,' '-1                ; Minus offset
  2419.         mov     ansargs+1,al            ; Stash here
  2420.         call    atnorm                  ; Reset state to "normal"
  2421.         jmp     atcup                   ; Position and return
  2422.  
  2423. ; VT52 print controls
  2424.  
  2425. v52apb: mov     ansargs,5               ; Enter auto print mode
  2426.         or      escdec,decmode          ; simulate ESC [ ? 5 i
  2427.         jmp     ansprt                  ; process command
  2428.  
  2429. v52ape: mov     ansargs,4               ; Exit auto print mode
  2430.         or      escdec,decmode          ; simulate ESC [ ? 4 i
  2431.         jmp     ansprt                  ; process command
  2432.  
  2433. v52pcb: mov     ansargs,5               ; Enter printer controller on
  2434.         or      escdec,decmode          ; simulate ESC [ ? 5 i
  2435.         jmp     ansprt                  ; process command
  2436.  
  2437. v52pce: mov     ansargs,4               ; Exit printer controller on
  2438.         or      escdec,decmode          ; simulate ESC [ ? 4 i
  2439.         jmp     ansprt                  ; process command
  2440.  
  2441. v52ps:  mov     ansargs,0               ; print screen
  2442.         and     escdec,not decmode      ; simulate ESC [ 0 i
  2443.         jmp     ansprt                  ; process command
  2444.  
  2445. v52pl:  mov     ansargs,1               ; print line
  2446.         or      escdec,decmode          ; simulate ESC [ ? 1 i
  2447.         jmp     ansprt                  ; process command
  2448.  
  2449.                                         ; Heath-19 special functions
  2450.  
  2451. h19ans: or      ansflgs,decanm          ; Turn on ANSI flag. ESC <
  2452.         call    chrdef                  ; Set default char sets
  2453.         jmp     atnorm                  ; Reset state to normal and return
  2454.  
  2455.                                         ; do several "ESC ["  ANSI commands
  2456.                                         ; but don't change terminal types
  2457. h19ansa:jmp     atcsi                   ; parse ansi arguments
  2458.  
  2459.                                         ; clear screen and go home
  2460. h19clrs:mov     dx,0                    ; go to upper left corner
  2461.         call    atscu5                  ; do it
  2462.         mov     ax,0                    ; clear screen from (0,0)
  2463.         mov     bh,byte ptr low_rgt+1   ; to lower right corner
  2464.         mov     bl,crt_cols             ; physical width
  2465.         dec     bl                      ; we count from 0
  2466.         jmp     vtsclr                  ; Clear it
  2467.                                         ; cursor down (scrolls)
  2468. h19cud: mov     dx,cursor               ; get cursor position
  2469.         inc     dh                      ; say next row down
  2470.         call    atccic                  ; check position cursor (scrolls)
  2471.         mov     cursor,dx
  2472.         call    ax                      ; do scrolling
  2473.         jmp     atscu5
  2474.                                         ; cursor forward (right). ESC C
  2475. h19cuf: mov     dx,cursor               ; get cursor position
  2476.         inc     dl                      ; move cursor right
  2477.         cmp     dl,byte ptr low_rgt     ; beyond right margin
  2478.         jb      h19cuf1                 ; b = no. do it
  2479.         test    ansflgs,decawm          ; wrap mode on?
  2480.         jz      h19cuf2                 ; z = no. just ignore movement
  2481.         xor     dl,dl                   ; set to left margin
  2482.         inc     dh                      ; and down a row
  2483.         call    atccic                  ; adjust position
  2484.         call    ax                      ; call scrolling routine
  2485. h19cuf1:jmp     atscu5                  ; do positioning and return
  2486. h19cuf2:ret                             ; just return
  2487.  
  2488.                                         ; set line wrap on
  2489. h19wrap:or      ansflgs,decawm          ; turn on the flag
  2490.         jmp     atnorm
  2491.  
  2492.                                         ; turn off line wrap
  2493. h19nowrp:and    ansflgs,not decawm      ; turn off the flag
  2494.         jmp     atnorm
  2495.  
  2496. h19erb: mov     bx,cursor               ; erase home to cursor, incl
  2497.         xor     ax,ax                   ; home
  2498.         jmp     vtsclr                  ; clear the area, cursor stays put???
  2499.  
  2500. h19erl: mov     bx,cursor               ; erase whole line
  2501.         mov     ax,bx                   ; get row
  2502.         xor     al,al                   ; column 0
  2503.         mov     bl,crt_cols             ; physical width
  2504.         dec     bl                      ; we count from 0
  2505.         jmp     vtsclr                  ; erase whole line, cursor stays put
  2506.  
  2507. h19ero: mov     bx,cursor               ; erase start of line to cursor
  2508.         mov     ax,bx
  2509.         xor     al,al                   ; start in column 0
  2510.         jmp     vtsclr                  ; clear that part of line
  2511.  
  2512. h19herv:cmp     video_state,0           ; is video normal? ESC p
  2513.         jne     h19hrv1                 ; ne = no, reversed already, ignore
  2514.         mov     ah,curattr              ; current cursor attributes
  2515.         call    brkatt                  ; breakup attributes byte
  2516.         rol     ah,1                    ; reverse foreground to background
  2517.         rol     ah,1
  2518.         rol     ah,1
  2519.         rol     ah,1
  2520.         call    addatt                  ; put things together again
  2521.         mov     curattr,ah              ; and store it
  2522.         mov     video_state,1           ; say we are reversed
  2523. h19hrv1:ret
  2524.  
  2525. h19hxrv:cmp     video_state,0           ; is video normal? ESC q
  2526.         je      h19hxr1                 ; e = yes, so just ignore
  2527.         mov     ah,curattr              ; current cursor attributes
  2528.         call    brkatt                  ; breakup attributes byte
  2529.         rol     ah,1                    ; reverse foreground to background
  2530.         rol     ah,1
  2531.         rol     ah,1
  2532.         rol     ah,1
  2533.         call    addatt                  ; put things together again
  2534.         mov     curattr,ah              ; and store it
  2535.         mov     video_state,0           ; say we are normal
  2536. h19hxr1:ret
  2537.  
  2538. h19mbr: mov     ttstate,offset hmbr     ; Modify baud rate ESC r char
  2539.         ret                             ; setup to parse next char
  2540. hmbr:   jmp     atnorm                  ; discard char (in al)
  2541.  
  2542. htsc:   cmp     flags.vtflg,ttheath     ; Heath-19? ESC [ s
  2543.         jne     htscx                   ; ne = no, ignore
  2544.         call    atsc                    ; store cursor position and attr
  2545. htscx:  jmp     atnorm                  ; reset state & return
  2546.  
  2547. htrc:   cmp     flags.vtflg,ttheath     ; Heath-19? ESC [ u
  2548.         jne     htrcx                   ; ne = no, ignore
  2549.         call    atrc                    ; restore cursor pos and attr
  2550. htrcx:  jmp     atnorm                  ; reset state & return
  2551.  
  2552.                                         ; Heath-19 set mode "ESC x "
  2553. h19smod:mov     ttstate,offset hsmod    ; setup to parse rest of seq
  2554.         ret
  2555.  
  2556. hsmod:  mov     modeset,1               ; say set mode
  2557.         mov     ttstate,offset atnrm
  2558.         sub     al,'0'                  ; remove ascii bias
  2559.         jmp     htrsm1                  ; perform mode set
  2560.  
  2561. h19cmod:mov     ttstate,offset hcmod    ; setup to parse rest of seq
  2562.         ret
  2563.  
  2564. hcmod:  mov     modeset,0               ; say reset mode
  2565.         mov     ttstate,offset atnrm
  2566.         sub     al,'0'                  ; remove ascii bias
  2567.         jmp     htrsm1                  ; perform mode reset
  2568.  
  2569. htrest: cmp     flags.vtflg,ttheath     ; Heath-19? ESC [ z
  2570.         jne     htrestx                 ; ne = no, ignore
  2571.         call    atreset                 ; do a hard reset
  2572. htrestx:jmp     atnorm                  ; reset state and return
  2573.  
  2574. hrcup:  mov     al,escape               ; send "ESC Y row col" cursor report
  2575.         call    prtbout                 ; send with no local echo
  2576.         mov     al,'Y'
  2577.         call    prtbout
  2578.         mov     al,byte ptr cursor+1    ; get row
  2579.         add     al,' '                  ; add ascii bias
  2580.         call    prtbout                 ; send it
  2581.         mov     al,byte ptr cursor      ; get column
  2582.         add     al,' '                  ; add ascii bias
  2583.         call    prtbout                 ; and send it too
  2584.         jmp     atnorm                  ; return to terminal mode
  2585.  
  2586.                                         ; Heath-19 and VT102 additions
  2587.  
  2588. inslin: cmp     ansargs,0               ; insert line(s). Any args?
  2589.         jne     insli1                  ; ne = yes. If no arg use 1
  2590.         mov     ansargs,1               ; insert one line
  2591. insli1: mov     dl,ansargs
  2592.         mov     scroll,dl
  2593.         mov     dx,cursor               ; current position
  2594.         cmp     dh,mar_bot              ; below bottom margin?
  2595.         jae     insli3                  ; ae = at or below bottom margin
  2596.         push    word ptr mar_top
  2597.         mov     mar_top,dh              ; call present position the top
  2598. insli2: call    atscrd                  ; scroll down
  2599.         pop     word ptr mar_top        ; restore margins
  2600.         xor     dl,dl                   ; go to left margin
  2601.         jmp     atscu5                  ; reposition cursor and return
  2602. insli3: ret
  2603.  
  2604. dellin: cmp     ansargs,0               ; delete line(s). Any args?
  2605.         jne     delli1                  ; no arg; use 1
  2606.         mov     ansargs,1               ; insert one line
  2607. delli1: mov     dl,ansargs
  2608.         mov     scroll,dl               ; line count
  2609.         mov     dx,cursor               ; where we are presently
  2610.         cmp     dh,mar_bot              ; at or below bottom margin?
  2611.         jae     delli3                  ; ae = yes
  2612.         push    word ptr mar_top        ; save current scrolling margins
  2613.         mov     mar_top,dh              ; temp top margin is here
  2614. delli2: call    atscru                  ; scroll up
  2615.         pop     word ptr mar_top        ; restore scrolling margins
  2616.         jmp     atscu5                  ; restore cursor and return
  2617. delli3: ret
  2618.  
  2619.                                         ; Delete character(s)
  2620. atdelc: cmp     ansargs,0               ; zero becomes one operation
  2621.         jne     atdelc1
  2622.         mov     ansargs,1               ; delete one char. Heath ESC N
  2623. atdelc1:mov     cl,byte ptr low_rgt     ; number of columns on screen
  2624.         mov     dx,cursor               ; get present cursor position
  2625.         push    bx
  2626.         mov     bl,dh                   ; get row
  2627.         mov     bh,0
  2628.         cmp     linetype [bx],0         ; single width line?
  2629.         je      atdelc5                 ; e = yes
  2630.         shl     dl,1                    ; double the column number
  2631.         mov     bl,ansargs
  2632.         shl     bl,1                    ; double # chars to delete
  2633.         mov     ansargs,bl
  2634. atdelc5:pop     bx
  2635.         sub     cl,dl                   ; end of screen - current column #
  2636.         xor     ch,ch                   ; cx = number of chars to move
  2637.         cmp     cx,0                    ; zero means just this char
  2638.         ja      atdelc4
  2639.         inc     cx                      ; say one, this one
  2640. atdelc4:push    es
  2641.         push    cx                      ; save word count for Topview
  2642.         cld
  2643.         test    vtemu.vtflgop,vswdir    ; writing left to right?
  2644.         jz      atdelc4a                ; z = yes
  2645.         sub     dl,byte ptr low_rgt     ; reflect about logical right column
  2646.         neg     dl                      ; convert to positive value
  2647. atdelc4a:
  2648.         call    scrloc                  ; compute current cursor location
  2649.         mov     di,ax                   ; temporary storage places
  2650.         mov     si,ax
  2651.         mov     al,ansargs              ; get delete count
  2652.         xor     ah,ah                   ; clear high byte of delete count
  2653.         cmp     al,cl                   ; clear more than rest of line?
  2654.         jb      atdelc2                 ; b = no. some chars left at end
  2655.         mov     al,cl                   ; say delete all to right, inclusive
  2656. atdelc2:cmp     al,0                    ; zero?
  2657.         jne     atdelc3
  2658.         inc     al                      ; none or 0 implies one
  2659. atdelc3:shl     ax,1                    ; double: char and its attribute byte
  2660.         push    di                      ; destination offset
  2661.         cld                             ; assume forward for left to right
  2662.         test    vtemu.vtflgop,vswdir    ; writing left to right
  2663.         jz      atdelc3a                ; z = yes
  2664.         neg     ax                      ; minus ax, work the other way
  2665.         std                             ; movement reverses too
  2666. atdelc3a:
  2667.         add     ax,si                   ; src offset = dest + # deleted words
  2668.         push    ax                      ; save it
  2669.         call    scroff
  2670.         call    scrseg                  ; pick up screen segment
  2671.         mov     si,di                   ; align memory addresses
  2672.         pop     ax                      ; recover source offset
  2673.         add     si,ax                   ; add to starting memory address
  2674.         pop     ax                      ; recover destination offset
  2675.         add     di,ax                   ; add to destination memory address
  2676.         push    ds                      ; save ds around the move
  2677.         push    es                      ; move es into ds to
  2678.         pop     ds                      ; make ds point to screen memory too
  2679.         rep     movsw
  2680.         cld                             ; reset direction to forward
  2681.         pop     ds                      ; recover normal ds
  2682.         pop     cx                      ; count for Topview
  2683.         test    vtemu.vtflgop,vswdir    ; writing left to right?
  2684.         jz      atdelc6                 ; z = yes
  2685.         sub     di,cx                   ; get correct es:di ending address
  2686.         sub     di,cx                   ; for scrsync
  2687. atdelc6:call    scrsync                 ; synch Topview
  2688.         pop     es
  2689.         call    scron
  2690.         mov     ax,cursor               ; get current row
  2691.         mov     bx,cursor
  2692.         mov     bl,byte ptr low_rgt     ; last col on screen
  2693.         mov     al,bl
  2694.         sub     al,ansargs              ; minus number of locations cleared
  2695.         inc     al
  2696.         test    vtemu.vtflgop,vswdir    ; writing left to right?
  2697.         jz      atdelc7                 ; z = yes
  2698.         mov     cl,byte ptr low_rgt     ; reflect about logical right margin
  2699.         sub     cl,al
  2700.         mov     bl,cl                   ; end of line to be cleared
  2701.         mov     al,0                    ; start of line to be cleared
  2702. atdelc7:call    atsclr                  ; clear end of line
  2703. atdelcx:mov     dx,cursor
  2704.         jmp     atscu5                  ; reposition cursor
  2705.  
  2706. inschr: mov     dx,cursor               ; open one char space in current line
  2707.         push    bx
  2708.         mov     bl,dh                   ; get row
  2709.         mov     bh,0
  2710.         cmp     linetype [bx],0         ; single width line?
  2711.         je      insch2                  ; e = yes
  2712.         shl     dl,1                    ; double the column number
  2713. insch2: pop     bx
  2714.         mov     ch,0
  2715.         mov     cl,byte ptr low_rgt     ; number of columns on screen
  2716.         push    dx
  2717.         mov     dh,0
  2718.         sub     cx,dx                   ; compute distance to end
  2719.         pop     dx
  2720.         or      cx,cx
  2721.         jle     insch1                  ; le = nothing to move [dlk]
  2722.         mov     dl,byte ptr low_rgt
  2723.         dec     dl                      ; last col to move
  2724.         push    ax                      ; save regs
  2725.         push    es                      ; ditto
  2726.         push    cx                      ; save count for Topview
  2727.         test    vtemu.vtflgop,vswdir    ; writing left to right?
  2728.         jz      insch3                  ; z = yes
  2729.         mov     dl,1                    ; right-to-left physical EOL-1
  2730.         call    scrloc                  ; compute position of end of line-1
  2731.         push    ax                      ; save offset
  2732.         cld                             ; remember to move forward
  2733.         call    scroff                  ; turn off color screen
  2734.         call    scrseg                  ; get memory address in es:di
  2735.         pop     ax                      ; recover offset
  2736.         add     di,ax                   ; source memory address
  2737.         mov     si,di                   ; align addresses. destination
  2738.         sub     di,2                    ;   is one char over
  2739.         jmp short insch4                ; join common code
  2740. insch3:                                 ; do normal left to right material
  2741.         call    scrloc                  ; compute position of end of line-1
  2742.         push    ax                      ; save offset
  2743.         std                             ; remember to move backward
  2744.         call    scroff                  ; turn off color screen
  2745.         call    scrseg                  ; get memory address in es:di
  2746.         pop     ax                      ; recover offset
  2747.         add     di,ax                   ; source memory address
  2748.         mov     si,di                   ; align addresses. destination
  2749.         add     di,2                    ;   is one char over
  2750. insch4: push    di
  2751.         push    ds                      ; save ds around move
  2752.         push    es                      ; put es into ds
  2753.         pop     ds                      ;   ds points to screen memory too
  2754.         rep     movsw
  2755.         pop     ds                      ; recover normal ds
  2756.         cld                             ; reset direction to be forward
  2757.         pop     di
  2758.         pop     cx                      ; count for Topview
  2759.         test    vtemu.vtflgop,vswdir    ; writing left to right?
  2760.         jz      insch5                  ; z = yes
  2761.         add     di,cx                   ; get correct es:di ending address
  2762.         add     di,cx                   ; for scrsync
  2763. insch5: call    scrsync                 ; synch Topview
  2764.         pop     es                      ; restore regs
  2765.         pop     ax                      ; ditto
  2766.         call    scron                   ; turn on screen again
  2767.         cld                             ; reset direction
  2768. insch1: mov     dx,cursor
  2769.         jmp     atscu5                  ; position cursor
  2770.  
  2771. noins:  mov     insmod,0                ; turn off insert mode
  2772.         jmp     atnorm                  ; and return
  2773.  
  2774. entins: mov     insmod,0ffh             ; enter insert mode
  2775.         jmp     atnorm                  ; and return
  2776.  
  2777. ansich  proc    near                    ; ANSI insert characters ESC [ Pn @
  2778.         cmp     ansargs,0               ; any arguments?
  2779.         jne     ansic1                  ; ne = no, ignore
  2780.         mov     ansargs,1               ; use one
  2781. ansic1: push    dx                      ; save cursor
  2782.         mov     insmod,1                ; enter insert mode
  2783.         push    cx
  2784.         mov     cl,ansargs              ; get count of inserts
  2785.         mov     ch,0
  2786.         mov     ah,ansflgs              ; save flags in ah
  2787.         and     ansflgs,not decawm      ; turn off autowrap
  2788.         push    ax                      ; save char
  2789. ansic2: push    cx                      ; save counter
  2790.         mov     al,' '                  ; character to write
  2791.         call    atnrm                   ; do display
  2792.         pop     cx                      ; recover counter
  2793.         loop    ansic2                  ; do cx times
  2794.         pop     ax                      ; restore char
  2795.         mov     ansflgs,ah              ; recover flags
  2796.         mov     ah,0                    ; clear register
  2797.         pop     cx
  2798.         mov     insmod,0                ; turn off insert mode
  2799.         pop     dx                      ; get original cursor
  2800.         jmp     atscu5                  ; set cursor
  2801. ansich  endp
  2802.  
  2803. ; routines supporting scrolling and double width/height chars
  2804. ; scroll has number of lines to scroll
  2805. atscru  proc    near                    ; scroll screen up one line
  2806.         push    ax                      ; assumes dx holds cursor position
  2807.         push    bx                      ; returns with dx = old row, new col
  2808.         push    cx
  2809.         push    si
  2810.         xor     bh,bh
  2811.         mov     bl,mar_top              ; top line to move
  2812.         xor     ch,ch
  2813.         mov     cl,scroll               ; number of lines to move
  2814.         jcxz    atscru5                 ; cx = 0. nothing to do
  2815.         mov     al,mar_bot              ; bottom line to scroll
  2816.         sub     al,bl                   ; number of lines minus 1
  2817.         inc     al                      ; number of lines
  2818.         cmp     al,cl                   ; scrolling region smaller than scroll?
  2819.         jge     atscru1                 ; ge = no, is ok
  2820.         mov     scroll,al               ; limit to region
  2821.         cmp     al,1                    ; at least one line to scroll?
  2822.         jge     atscru1                 ; ge = yes
  2823.         mov     scroll,1                ; no, force one
  2824. atscru1:push    bx
  2825.         mov     bl,dh                   ; get row of cursor
  2826.         mov     bh,0
  2827.         cmp     linetype[bx],0          ; single width?
  2828.         pop     bx
  2829.         je      atscru7                 ; e = yes
  2830.         shr     dl,1                    ; reindex to single width columns
  2831. atscru7:mov     al,scroll
  2832.         xor     ah,ah
  2833.         cmp     al,byte ptr low_rgt+1   ; number of lines on screen
  2834.         jbe     atscru8                 ; be = scrolling not more than that
  2835.         mov     al,byte ptr low_rgt+1   ; limit to screen length
  2836.         mov     scroll,al
  2837. atscru8:mov     si,ax                   ; scroll interval
  2838.         mov     bl,mar_top
  2839.         mov     cl,mar_bot
  2840.         sub     cl,bl
  2841.         inc     cl                      ; number  of lines in region
  2842.         sub     cl,scroll               ; cx = those needing movement
  2843.         jcxz    atscru3
  2844. atscru2:mov     al,linetype[bx+si]      ; get old type
  2845.         mov     linetype[bx],al         ; copy to new higher position
  2846.         inc     bx
  2847.         loop    atscru2
  2848. atscru3:mov     bl,mar_bot              ; set fresh lines to single attribute
  2849.         mov     cl,scroll
  2850.         mov     ch,0
  2851.         inc     cx
  2852. atscru4:mov     linetype[bx],0
  2853.         dec     bx
  2854.         loop    atscru4                 ; clear old bottom lines
  2855. atscru5:pop     si
  2856.         pop     cx
  2857.         pop     bx
  2858.         pop     ax
  2859.         test    anspflg,vtcntp          ; controller print active?
  2860.         jz      atscru6                 ; z = no, ok to change screen
  2861.         ret                             ;  else keep screen intact
  2862. atscru6:jmp     vtscru                  ; call & ret the msy scroll routine
  2863. atscru  endp
  2864.  
  2865. atscrd  proc    near                    ; scroll screen down one line
  2866.         push    ax                      ; assumes dx holds cursor position
  2867.         push    bx                      ; returns with dx = old row, new col
  2868.         push    cx
  2869.         push    si
  2870.         xor     ch,ch
  2871.         mov     cl,scroll               ; number of lines to scroll
  2872.         jcxz    atscrd5                 ; cx = 0. nothing to do
  2873.         xor     bh,bh
  2874.         mov     bl,mar_bot              ; bottom line to move
  2875.         mov     al,bl
  2876.         mov     ah,0
  2877.         sub     al,mar_top              ; number of lines minus 1
  2878.         inc     al                      ; number of lines
  2879.         cmp     al,cl                   ; scrolling region smaller than scroll?
  2880.         jge     atscrd1                 ; ge = no, is ok
  2881.         mov     scroll,al               ; limit to region
  2882.         cmp     al,1                    ; at least one line to scroll?
  2883.         jge     atscrd1                 ; ge = yes
  2884.         mov     scroll,1                ; no, force one
  2885. atscrd1:push    bx
  2886.         mov     bl,dh                   ; get row of cursor
  2887.         mov     bh,0
  2888.         cmp     linetype[bx],0          ; single width?
  2889.         pop     bx
  2890.         je      atscrd7                 ; e = yes
  2891.         shr     dl,1                    ; reindex to single wide columns
  2892. atscrd7:mov     al,scroll
  2893.         mov     si,ax                   ; si = scroll
  2894.         sub     bl,scroll               ; si + this bx will be new bottom line
  2895.         mov     cl,bl
  2896.         sub     cl,mar_top
  2897.         inc     cl                      ; number of movements
  2898.         jcxz    atscrd3
  2899. atscrd2:mov     al,linetype[bx]         ; get old line's type
  2900.         mov     linetype[bx+si],al      ; copy to new lower position
  2901.         dec     bx
  2902.         loop    atscrd2
  2903. atscrd3:mov     bl,mar_top
  2904.         mov     bh,0
  2905.         mov     cl,scroll
  2906.         mov     ch,0
  2907.         inc     cx
  2908. atscrd4:mov     linetype[bx],0          ; clear new top lines
  2909.         inc     bx
  2910.         loop    atscrd4
  2911. atscrd5:pop     si
  2912.         pop     cx
  2913.         pop     bx
  2914.         pop     ax
  2915.         test    anspflg,vtcntp          ; controller print active?
  2916.         jz      atscrd6                 ; z = no, ok to change screen
  2917.         ret                             ;  else keep screen intact
  2918. atscrd6:jmp     vtscrd                  ; call & ret the msy scroll routine
  2919. atscrd  endp
  2920.  
  2921. linesgl proc    near                    ; convert line to single width char
  2922.         push    ax
  2923.         push    bx
  2924.         push    cx
  2925.         push    dx
  2926.         mov     bx,cursor
  2927.         mov     bl,bh
  2928.         xor     bh,bh                   ; bx now holds row
  2929.         cmp     linetype [bx],0         ; is line already single width?
  2930.         je      linsglx                 ; e = yes
  2931.         mov     linetype [bx],0         ; say will be single now
  2932.         call    scroff                  ; turn off video
  2933.         mov     dx,cursor
  2934.         mov     dl,0                    ; start in column 0
  2935.         mov     cl,byte ptr low_rgt     ; number of columns on screen
  2936.         inc     cl
  2937.         shr     cl,1                    ; number of columns to do
  2938.         mov     ch,0
  2939.         push    cx                      ; save around loop below
  2940. linsgl1:push    cx                      ; save loop counter
  2941.         shl     dl,1                    ; double column number
  2942.         mov     ah,2                    ; set cursor
  2943.         xor     bh,bh                   ; page 0
  2944.         call    direction               ; do Bios screen operation
  2945.         mov     ah,8                    ; read char and attribute
  2946.         int     screen
  2947.         push    ax                      ; save char and attribute
  2948.         shr     dl,1                    ; restore column
  2949.         mov     ah,2                    ; set cursor
  2950.         call    direction               ; do Bios screen operation
  2951.         pop     ax                      ; recover char and attribute
  2952.         mov     bl,ah                   ; set attribute
  2953.         mov     cx,1                    ; one char
  2954.         mov     ah,9                    ; write char and attribute
  2955.         int     screen
  2956.         inc     dl                      ; next column
  2957.         pop     cx
  2958.         loop    linsgl1
  2959.         pop     cx                      ; recover column counter
  2960.         mov     dl,cl
  2961. linsgl2:push    cx                      ; save counter
  2962.         mov     ah,2                    ; set cursor
  2963.         call    direction               ; do Bios screen operation
  2964.         mov     bh,0
  2965.         mov     bl,scbattr              ; screen background
  2966.         mov     al,' '
  2967.         mov     ah,9                    ; write char
  2968.         mov     cx,1                    ; do one character
  2969.         call    direction               ; do Bios screen operation
  2970.         inc     dl                      ; next column
  2971.         pop     cx
  2972.         loop    linsgl2                 ; repeat for all characters
  2973.         call    scron                   ; turn on the video
  2974. linsglx:pop     dx
  2975.         pop     cx
  2976.         pop     bx
  2977.         pop     ax
  2978.         jmp     atscur                  ; update cursor and return
  2979. linesgl endp
  2980.  
  2981. linedbl proc    near                    ; convert line to double width char
  2982.         push    ax                      ; must reset physical cursor
  2983.         push    bx                      ; to same char as before expansion
  2984.         push    cx                      ; but does not modify variable cursor
  2985.         push    dx
  2986.         mov     bx,cursor
  2987.         mov     bl,bh
  2988.         xor     bh,bh                   ; bx now holds row
  2989.         cmp     linetype [bx],0         ; is line single width?
  2990.         jne     lindblx                 ; ne = no. nothing to do
  2991.         mov     linetype [bx],1         ; say will be double width now
  2992.         mov     dx,cursor
  2993.         mov     cl,byte ptr low_rgt     ; number of columns on the screen
  2994.         inc     cl
  2995.         mov     ch,0
  2996.         shr     cl,1                    ; number of items to do
  2997.         mov     dl,cl
  2998.         dec     dl
  2999.         call    scroff                  ; turn off the video
  3000. lindbl1:push    cx                      ; save loop counter
  3001.         mov     ah,2                    ; set cursor
  3002.         mov     bh,0                    ; page 0
  3003.         call    direction               ; do Bios screen operation
  3004.         mov     ah,8                    ; read char and attribute
  3005.         int     screen
  3006.         push    ax                      ; save char and attribute
  3007.         shl     dl,1                    ; double the column number
  3008.         mov     ah,2                    ; set cursor
  3009.         call    direction               ; do Bios screen operation
  3010.         pop     ax                      ; recover char and attribute
  3011.         mov     bl,ah                   ; set attribute
  3012.         mov     cx,1                    ; one char
  3013.         mov     ah,9                    ; write char and attribute
  3014.         int     screen
  3015.         inc     dl                      ; move to second column of double
  3016.         mov     ah,2                    ; set cursor
  3017.         call    direction               ; do Bios screen operation
  3018.         mov     al,' '                  ; space as filler
  3019.         mov     ah,9                    ; write that char
  3020.         int     screen
  3021.         dec     dl
  3022.         shr     dl,1
  3023.         dec     dl
  3024.         pop     cx
  3025.         loop    lindbl1
  3026.         call    scron                   ; turn on the video
  3027. lindblx:pop     dx
  3028.         pop     cx
  3029.         pop     bx
  3030.         pop     ax
  3031.         jmp     atscur                  ; update the cursor and return
  3032. linedbl endp
  3033.  
  3034. anstty  endp
  3035.  
  3036. ansprt  proc near                       ; printer support routines
  3037.         mov     di,offset ansprt0       ; routine to process arguments
  3038.         call    atreps                  ; Repeat for all parms
  3039.         ret
  3040.  
  3041. ansprt0:mov     ah,ansargs[si]          ; Pick up the argument
  3042.         cmp     ah,0                    ; 0 (print all/part of screen)?
  3043.         jne     ansprt1                 ; ne = no
  3044.         call    pntchk                  ; check printer
  3045.         jc      ansprtx                 ; c = printer not ready
  3046.         call    pntext                  ; do whole screen or scrolling extent
  3047.         jmp     atscu5                  ; reposition cursor and return
  3048.  
  3049. ansprt1:cmp     ah,1                    ; 1 (print current line)?
  3050.         jne     ansprt4                 ; ne = no
  3051.         call    pntchk                  ; check for printer ready
  3052.         jc      ansprtx                 ; c = printer not ready
  3053.         call    pntlin                  ; print current line
  3054.         call    pntflsh                 ; flush printer buffer
  3055. anspr1a:jmp     atscu5                  ; reposition cursor and return
  3056.  
  3057. ansprt4:cmp     ah,4                    ; 4 (auto print disable)?
  3058.         jne     ansprt5                 ; ne = no
  3059.         test    escdec,decmode          ; was it ESC [ ? 4 i
  3060.         jz      anspr4a                 ; z = no, so it was ESC [ 4 i
  3061.         test    anspflg,vtautop         ; check state of print flag
  3062.         jz      anspr4a                 ; z = off already
  3063.         and     anspflg,not vtautop     ; auto-print disable
  3064.         call    trnprs                  ; toggle mode line PRN indicator
  3065. anspr4a:jmp     ansprtx
  3066.  
  3067. ansprt5:cmp     ah,5                    ; 5 (auto print enable)?
  3068.         jne     ansprtx                 ; ne = no
  3069.         call    pntchk                  ; check printer, ignore carry ret
  3070.         jc      ansprtx                 ; c = printer not ready
  3071.         test    escdec,decmode          ; was it ESC [ ? 5 i
  3072.         jz      anspr5a                 ; z = no
  3073.         test    anspflg,vtautop         ; is print already enabled?
  3074.         jnz     ansprtx                 ; nz = yes, leave trnprs intact
  3075.         or      anspflg,vtautop         ; auto-print enabled
  3076.         jmp     short anspr5b
  3077. anspr5a:test    anspflg,vtcntp          ; controller print already enabled?
  3078.         jnz     ansprtx                 ; nz = yes
  3079.         or      anspflg,vtcntp          ; controller print enabled
  3080. anspr5b:call    trnprs                  ; toggle on mode line PRN indicator
  3081. ansprtx:jmp     atnorm
  3082. ansprt  endp
  3083.  
  3084. ; State machine active while Media Copy On (Print Controller ON). Copies all
  3085. ; chars to the printer until (and excluding) Media Copy Off (ESC [ 4 i) has
  3086. ; been received or the emulator reset. New char is in al. 6 March 1987 [jrd]
  3087.  
  3088. ansmc   proc    near
  3089.         mov     ah,al                   ; copy active character
  3090.         and     ah,7fh                  ; strip high bit
  3091.         cmp     ah,escape               ; start of MC Off sequence?
  3092.         jne     ansmc1                  ; ne = no
  3093.         call    ansmc6                  ; playback previously matched chars
  3094.         mov     mccnt,1                 ; count matched chars (one now)
  3095.         mov     mcoffs,al               ; save full character, with high bit
  3096.         mov     ansargs,0               ; clear first ansi argument
  3097.         mov     nansarg,0               ; number of arguments
  3098.         ret
  3099.  
  3100. ansmc1: mov     bx,mccnt                ; number of chars matched in MC Off
  3101.         cmp     bx,0                    ; have first?
  3102.         jne     ansmc1a                 ; ne = yes, one or more
  3103.         jmp     pntchr                  ; print it, ignore errors
  3104.  
  3105. ansmc1a:mov     mcoffs[bx],al           ; save this char, with high bit
  3106.         inc     mccnt                   ; count saved characters
  3107.         and     al,7fh                  ; strip high bit
  3108.         cmp     al,'0'                  ; A digit?
  3109.         jge     ansmc2                  ; ge = maybe
  3110.         jmp     ansmc6                  ; b = out of range for everything
  3111. ansmc2: cmp     al,'9'                  ; maybe, separator or final char?
  3112.         ja      ansmc3                  ; a = perhaps, go check it out
  3113.         mov     cl,al                   ; digit, convert ASCII to binary
  3114.         sub     cl,'0'
  3115.         mov     ch,0
  3116.         mov     bl,nansarg              ; put index in bx
  3117.         xor     bh,bh
  3118.         mov     al,ansargs[bx]          ; Pick up what we've done so far [dlk]
  3119.         shl     al,1                    ; multiply by 10.  2 * al
  3120.         mov     ah,al                   ; save
  3121.         shl     al,1                    ; 4 * al
  3122.         shl     al,1                    ; 8 * al
  3123.         add     al,ah                   ; 10 * al
  3124.         mov     ah,0                    ; clear high field
  3125.         add     ax,cx                   ; add in this digit [dlk]
  3126.         cmp     ax,0feh                 ; max value is 0ffh [dlk]
  3127.         jbe     ansmc2a                 ; be = ok [dlk]
  3128.         mov     al,0ffh                 ; set to max value [dlk]
  3129. ansmc2a:mov     ansargs[bx],al          ; Put result back for next time [dlk]
  3130.         ret                             ; And return
  3131.  
  3132. ansmc3: cmp     al,'['                  ; ANSI sequence?
  3133.         jne     ansmc4                  ; ne = no, check further
  3134.         cmp     mccnt,2                 ; is it the second character?
  3135.         je      ansmc3a                 ; e = yes, accept and continue
  3136.         jmp     ansmc6                  ; no, end match
  3137. ansmc3a:ret                             ; continue
  3138.  
  3139. ansmc4: cmp     al,';'                  ; Argument separator?
  3140.         jne     ansmc5                  ; ne = no, check for final char
  3141.         inc     nansarg                 ; yes, count it
  3142.         mov     bl,nansarg              ; get argument index
  3143.         mov     bh,0
  3144.         mov     ansargs[bx],0           ; clear next arg field
  3145.         cmp     bl,lansarg              ; too many?
  3146.         jl      ansmc4a                 ; l = no, continue
  3147.         dec     nansarg                 ; yes, do not add more
  3148.         jmp     ansmc6                  ; end match now
  3149. ansmc4a:ret                             ; accept separator and continue
  3150.  
  3151. ansmc5: cmp     al,'i'                  ; sequence terminator?
  3152.         jne     ansmc6                  ; ne = no, end match
  3153.         mov     bx,-1
  3154.         mov     cl,nansarg              ; number of argument values
  3155.         mov     ch,0
  3156.         inc     cx                      ; no args is same as one
  3157. ansmc5a:inc     bx
  3158.         mov     al,ansargs[bx]          ; get ansi argument
  3159.         mov     ansargs[bx],0ffh        ; and zap it to absorb early values
  3160.         cmp     al,4                    ; MC OFF value?
  3161.         loopne  ansmc5a                 ; ne = no, examine all non-matches
  3162.         jne     ansmc6                  ; ne = no match, end matching
  3163.                                         ; MC OFF sequence discovered
  3164.         mov     mccnt,0                 ; clear counter
  3165.         call    pntflsh                 ; flush printer buffer
  3166.         test    anspflg,vtcntp          ; was printing active?
  3167.         jz      ansmc5b                 ; z = no, do nothing
  3168.         and     anspflg,not vtcntp      ; yes, disable print controller
  3169.         call    trnprs                  ; toggle mode line PRN indicator
  3170. ansmc5b:jmp     ansprt                  ;  done, process arguments in order
  3171.  
  3172.                                         ; MC OFF sequence not found, playback
  3173. ansmc6: push    ax                      ; save break char (in al)
  3174.         push    cx                      ; playback partial sequence to printer
  3175.         mov     cx,mccnt                ; number of chars matched before break
  3176.         jcxz    ansmc6b                 ; z = none
  3177.         push    si
  3178.         mov     si,offset mcoffs        ; string to be played back
  3179.         cld
  3180. ansmc6a:lodsb                           ; get a char into al
  3181.         call    pntchr                  ; print it, ignore errors
  3182.         loop    ansmc6a                 ; do all that came in previously
  3183.         pop     si
  3184. ansmc6b:pop     cx
  3185.         pop     ax                      ; recover break char
  3186.         mov     mccnt,0                 ; reset to no match and exit
  3187.         mov     nansarg,0
  3188.         ret
  3189. ansmc   endp
  3190.  
  3191. pntlin  proc    near                    ; print whole line given by dx
  3192.         push    ax
  3193.         push    bx
  3194.         push    cx
  3195.         push    dx
  3196.         xor     ch,ch
  3197.         mov     cl,byte ptr low_rgt     ; number of columns
  3198.         mov     dl,cl                   ; Bios column counter, dh = row
  3199.         inc     cl                      ; actual line length, count it down
  3200.         test    vtemu.vtflgop,vswdir    ; writing right to left?
  3201.         jnz     pntlin2                 ; nz = yes, do not trim spaces
  3202. pntlin1:mov     ah,2                    ; set cursor
  3203.         xor     bh,bh                   ; page 0
  3204.         int     screen
  3205.         mov     ah,8                    ; read char (al) and attribute (ah)
  3206.         int     screen
  3207.         cmp     al,' '                  ; is this a space?
  3208.         jne     pntlin2                 ; no, we have the end of the line
  3209.         dec     dl                      ; else move left one column
  3210.         loop    pntlin1                 ; and keep looking for non-space
  3211.  
  3212. pntlin2:jcxz    pntlin4                 ; z = empty line
  3213.         xor     dl,dl                   ; start in column 0, do cl chars
  3214. pntlin3:mov     ah,2                    ; set cursor
  3215.         xor     bh,bh                   ; page 0
  3216.         int     screen
  3217.         mov     ah,8                    ; read char and attribute
  3218.         int     screen
  3219.         inc     dl                      ; inc to next column
  3220.         call    pntchr                  ; print the char (in al)
  3221.         jc      pntlin5                 ; c = printer error
  3222.         loop    pntlin3                 ; do cx columns
  3223. pntlin4:mov     al,cr                   ; add trailing cr/lf for printer
  3224.         call    pntchr
  3225.         jc      pntlin5
  3226.         mov     al,lf
  3227.         call    pntchr
  3228. pntlin5:pop     dx
  3229.         pop     cx
  3230.         pop     bx
  3231.         pop     ax
  3232.         ret                             ; C bit controlled by pntchr
  3233. pntlin  endp
  3234.  
  3235. pntext  proc    near                    ; print an extent of lines, depending
  3236.         push    ax                      ; on flag bit vtextp
  3237.         push    bx
  3238.         push    dx
  3239.         xor     dx,dx                   ; assume starting at top left
  3240.         mov     bx,low_rgt              ;  and extending to lower right
  3241.         test    anspflg,vtextp          ; full screen wanted?
  3242.         jnz     pntext1                 ; nz = yes, else scrolling region
  3243.         mov     dh,mar_top              ; top of scrolling region
  3244.         mov     bh,mar_bot              ; bottom of scrolling region
  3245. pntext1:call    pntlin                  ; print a line
  3246.         jc      pntext2                 ; c = printer error
  3247.         inc     dh
  3248.         cmp     dh,bh                   ; done all requested lines?
  3249.         jbe     pntext1                 ; be = not yet, do another
  3250.         test    anspflg,vtffp           ; form feed needed at end?
  3251.         jz      pntext2                 ; z = no
  3252.         mov     al,ff
  3253.         call    pntchr                  ; print the form feed char
  3254. pntext2:pop     dx
  3255.         pop     bx
  3256.         pop     ax
  3257.         ret
  3258. pntext  endp
  3259.  
  3260. ; Do Bios screen operation with consideration for writing direction.
  3261. ; Enter with normal registers set, preserves register dx.
  3262.  
  3263. direction proc  near
  3264.         push    dx
  3265.         test    vtemu.vtflgop,vswdir    ; writing left to right?
  3266.         jz      direct1                 ; z = yes, do Bios function
  3267.         sub     dl,byte ptr low_rgt     ; right margin column number
  3268.         neg     dl                      ; make a positive value again
  3269. direct1:int     screen
  3270.         pop     dx
  3271.         ret
  3272. direction endp
  3273.  
  3274. ; Clear screen from AX to BX, where AH = row, AL = column, ditto for BX.
  3275. ; This routine accomodates right to left writing. BX >= AX.
  3276. vtsclr  proc    near
  3277.         test    vtemu.vtflgop,vswdir    ; writing left to right?
  3278.         jz      vtsclr4                 ; z = yes
  3279.         cmp     bh,ah                   ; same row?
  3280.         je      vtsclr2                 ; e = yes
  3281.         push    ax                      ; multiple lines
  3282.         push    bx                      ; save both coordinates
  3283.         mov     bl,byte ptr low_rgt     ; get right most logical column
  3284.         mov     bh,ah                   ; pick just top line
  3285.         call    vtsclr2                 ; delete fraction of top line
  3286.         pop     bx                      ; recover ending position
  3287.         push    bx
  3288.         inc     ah                      ; omit top row, now done
  3289.         dec     bh                      ; omit last line, could be fractional
  3290.         cmp     bh,ah                   ; any whole lines remaining to delete?
  3291.         jb      vtsclr1                 ; b = no, finish up
  3292.         mov     bl,byte ptr low_rgt     ; get right most physical column
  3293.         mov     al,0                    ; to end of line (on left)
  3294.         call    atsclr                  ; clear top line and whole remainders
  3295. vtsclr1:pop     bx                      ; setup for last line to be cleared
  3296.         push    bx                      ; get last row again
  3297.         mov     al,0                    ; start at logical left margin
  3298.         jmp     short vtsclr3           ; ax and bx are already pushed
  3299.  
  3300. vtsclr2:push    ax                      ; erase single line, whole or part
  3301.         push    bx
  3302. vtsclr3:mov     ah,byte ptr low_rgt     ; borrow reg ah (same as bh)
  3303.         sub     ah,bl                   ; reflect right to left
  3304.         mov     bl,ah
  3305.         or      bl,bl                   ; overflow?
  3306.         jns     vtsclr5                 ; ns = no, is ok
  3307.         mov     bl,0                    ; limit to logical screen
  3308. vtsclr5:mov     ah,byte ptr low_rgt
  3309.         sub     ah,al
  3310.         mov     al,ah
  3311.         jns     vtsclr6
  3312.         mov     al,byte ptr low_rgt     ; limit to logical screen
  3313. vtsclr6:mov     ah,bh                   ; restore ah
  3314.         xchg    al,bl                   ; reverse to get physical ax < bx
  3315.         call    atsclr                  ; erase part/all of single line
  3316.         pop     bx
  3317.         pop     ax
  3318.         ret
  3319.                                         ; for writing left to right
  3320. vtsclr4:jmp     atsclr                  ; do normal erasure and return
  3321. vtsclr  endp
  3322.  
  3323.  
  3324. code    ends
  3325.  
  3326. if1
  3327.         %out [End of pass 1]
  3328. else
  3329.         %out [End of assembly]
  3330. endif
  3331.  
  3332.         end
  3333.