home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
kermit.columbia.edu
/
kermit.columbia.edu.tar
/
kermit.columbia.edu
/
mskermit
/
msz55x.asm
< prev
next >
Wrap
Assembly Source File
|
2018-01-01
|
159KB
|
3,751 lines
NAME msz55x
; File MSZ55X.ASM
; System dependent file for Sanyo 55x series.
; Done by Robert W. Babcock and Joe H. White.
; For version which replaces the BIOS keycode translation table,
; use -dMODIFIED flag to MASM.
page 60,132
; Terminal emulator module for IBM PC's and compatibles. Emulates Heath-19,
; VT52, and VT102. Original version done by James Harvey, Indiana Purdue
; Univ, for MS Kermit 2.27. Taken from there by Joe Doupnik, Utah State Univ
; for MS Kermit 2.29 et seq.
; Edit history
; Last edit 20 April 1988, add color trans. table for monochrome systems [rwb]
; 15 Sept 1987 version which runs with or without optional video board [rwb]
; Use bios calls for video output. Also change test for monochrome [jhw]
; monitor from crt_mode = 7 to 2. Set swidth and slen back to 80 and 25 [jhw]
; Make vtsound public so it can be called from msx55x. [rwb]
;
; 1 Jan 1988 version 2.30
; 29 Dec 1987 Absorb escape sequences of the form ESC [ ... <40h to 7fh>
; to sense but not act on unknown legally formatted ANSI escapes. [jrd]
; 28 Dec 1987 Add corrections from Frank da Cruz: home cursor on select/desel
; origin mode, make select/deselect ansi mode return to US ascii graphics
; rendition sets (where is this item documented?). [jrd]
; 12 Dec 1987 Sense denyflg to supress automatic Tek mode when ESC Control-L
; is received; part of ENABLE/DISABLE command. [jrd]
; 4 Dec 1987 Strip high bit of chars within escape sequences, test for end of
; transparent print without high bit but playback 8 bit intermediates. [jrd]
; 16 Nov 1987 Add multiple timed retries on printer status. [jrd]
; 5 Nov 1987 Add Tektronix terminal type, including ESC FF branch to Tek
; mode and toggling among terminal types. [jrd]
; 28 Oct 1987 Remove NUL and DEL chars from normal logging and display,
; ignore Control-X and -Z unless in an esc sequence. [jrd]
; 3 Oct 1987 Remove cursor action for DEL when local echo is on. [jrd]
; 11 Sept 1987 Remove Translation Input from emulator proper.
; 23 Aug 1987 Add byte vtemu.vtflgop to hold emulator runtime values as
; distinct from the vtemu.vtflgst setup values so a reset restores setups.
; 19 Aug 1987 Make sure cursor type is correct on warm start, from Bob Babcock
; 18 Aug 1987 Change ESC to escape for MASM 4.5+. Add Heath graphics,
; add screen alignment, redo line wrap material, size screen from crt_cols
; and crt_rows given by MSYxxx. [jrd]
; 31 June 1987 Clear counter mccnt when completing transparent print. [jrd]
; 17 June 1987 Correct jump from atreset to atres2 when changing 80/132 cols
; and always copy all 132 columns of tabs. [jrd]
; 16 June 1987 Fix bug in cursor positioning when outside scrolling region,
; thanks to Richard Saxton. Remove global byte jwait (for msy), add code to
; clear the status line when the Heath-19 is commanded to disable that line
; (wierd, but Dave says that's the way H-19's work), thanks to Dave Tweten.
; 8 June 1987 Tell file msy... about change of keypad applications mode. [jrd]
; 31 May 1987 Correct several Heath-19 problems: use ansi escape table when
; in ansi mode, reject ESC [ (hold screen mode), use correct cursor left,
; remember cursor type (underline/block/on/off) separately from VT100 setup.
; Thanks to Dave Tweten. [jrd]
; 10 May 1987 Move input translate table rxtable within this emulator,
; don't translate if debug is active, don't translate escape sequences,
; no translation if controller print is active, make byte anspflg global
; so msyibm can sense print screen status. Add print controls for VT52. [jrd]
; 4 May 1987 Correct several jumps to be signed for scrolling region. [jrd]
; 7 April 1987 Fix cursor wrap for H-19's, from Mike Iglesias [uci]
; Fix cursor wrap top to bottom when reverse indexing, from Matt Tomlinson.
; Fix tests for cursor left of left margin for wide screens by comparing
; column number exceeding 250D. [jrd]
; 28 March 1987 Use global variable low_rgt vs proc call for it. [jrd]
; 24 March 1987 In vtsound, always use most recent port 61h state. [jrd]
; 22 March 1987 Add call to proc chgdsp (change display adapter) to shift
; between 80 and 132 columns, from David L. Knoell. [jrd]
; 14 March 1987 Correct small bugs. Change signed jumps to unsigned plus
; allow screen widths to 132 columns, thanks to David Knoell.
; Add constants Swidth (132) and Slen (43) as max screen dimensions and
; base screen ops on low_rgt (high = row, low = column of lower right corner,
; counted from 0,0) dimensions stated by msyibm. [jrd]
; 6 March 87 Add transparent printing when ANSI Media Copy (ESC [ 5 i) is
; active. [jrd]
; 19 Feb 1987 correct problem in atccic of cursor being forced into scrolling
; region if starting point was outside the region. [jrd]
; 27 Oct 1986 correct typo for anspflg under atnrm3: [jrd]
; 16 Oct 1986 keep several ansflg bits under warm start, correct screen,
; linewrap, and newline status under warm start.
; 1 Oct 1986 Version 2.29a
; 20 Sept 1986 revise procedure atccic to use proper scrolling limits. [jrd]
; 1 Sept 1986 Add 8 bit wide comms when parity = none. In debug mode high bit
; set shows as tilde then rest of 7 bit code. [jrd]
; 27 August 1986 Add full VT102 printer support. DOS printer operations used
; so printer can be redirected; requires Kermit's Critical Error routine in
; mssker.asm to avoid "Abort, Retry, Ignore" msgs on screen. Shows printer
; not ready msg on mode line and quits printing operation if PRN not ready.
; Correct indexing of cursor when it is outside limited scrolling region.[jrd]
; Fix parameter decanm not being updated in stblmds under soft reset.
; 21 May 1986 [jrd]
; [2.29] code frozen on 6 May 1986 [jrd]
; [Joe R. Doupnik, Utah State Univ]
;
public anstty, ansini, ansrei, ansdsl, anstat, anskbi ; Entry points
public ans52t, vclick, vsinit
public vtsound ; [rwb]
public mar_top, mar_bot, anspflg ; data for msyibm
include mssdef.h
; * Disclaimer *
;
; DEC and VT are trademarks of Digital Equipment Corporation.
;
; There is a naming convention
; for the ANSI and VT100 functions and flags; generally, the stuff in the
; symbol after "ans" or "at" is the function or mode mnemonic used in the
; VT100 manual.
;
; Every effort has been made to make the VT100 emulation as much like the
; real thing as possible. The reference used was the VT100 User's Guide, 2nd
; ed. Jan. 1979, DEC part no. EK-VT100-UG. Some aspects of the behavior
; of the terminal (e.g., the interaction of the "origin mode", limited
; scrolling region, and indexing), were gleaned from programming experiments
; on an actual VT100 terminal. Implemented features include: (1) Limited
; scolling region, (2) Settable tab stops, (3) Special "graphics" character
; set and UK ASII set, (4) All graphic renditions (underline, blink, and
; high intensity), (5) Simulated "LEDs" on the mode line, (6) Screen mode
; (normal or reverse video), (7) All terminal reports (status, active position,
; terminal parameters, and device attributes), (8) The ANSI new-line mode and
; several of the DEC private modes, including keypad application, cursor key,
; screen, auto-wrap, and origin, (9) cursor position/graphic rendition/
; character set save/restore, and last (and probably least): (10) VT52 com-
; patibility mode. Also, various details of behavior required by the ANSI
; standard (e.g. most control characters do not affect the interpretation of
; the current escape sequence, relative cursor positioning (up, down, left
; right, and of course tab) stop at the screen margins, etc.) have been
; scrupulously observed.
;
; This was the first thing I ever wrote in 8088 assembler (some of it was
; stolen from MSYIBM), and one of the constraints was that the emulator
; should work with a vanilla PC with a monochrome monitor. Given these and
; other constraints, no attempt was made to implement the following VT100
; features: (1) Smooth scolling, (2) 132 column lines, (3) Auto repeat,
; (5) Interlace/no interlace, (6) Double-width/double-height lines. The
; escape sequences to set and reset these are recognized, but ignored.
;
; - James A. Harvey, IUPUI Computing Services, DEC Systems Group
;
; * End of Disclamer *
; ---------------------------------------------------------------------------
;
; Description of the global entry points and calls on external routines
; needed by this emulator. [jrd]
;
; vsinit - start up routine called as Kermit initializes. Takes no arguments.
; Sets up address pointers to tabs, reads default terminal parameters
; reads current screen coloring. Examines and updates structure
; "vtemu." which is how mssset communicates changed information
; about many Set Term parameters; "flags." is a Kermit structure
; carrying the other Set Term parameters.
; anstty - starting point for displaying a character, delivered in AL.
; Returns when the display operation is completed and that may
; take many many instructions. All normal "characters received by
; the terminal" are provided by calling anstty with the char in AL.
; ansini - entry point to initialize the emulator. It requires information
; from msy in four registers: the Kermit terminal routine flags
; "yflags" (used mainly to sense debug mode and the mode line toggle)
; "low_rgt" (bh = row, bl = column of the lower right display corner)
; "lbaudtab" (index into baud rate table, for status reporting)
; "lpartab" (index into parity table, for status reporting)
; Ansini causes a full reset of the emulator, including screen
; clearing and a beep. Ansini is also called by msy in response to
; sensing the Alt = key combination to fully reset the emulator.
; ansrei - entry point to reinitialize the emulator. Nearly the same as
; ansini except operating flags, tabs, etc are retained from the
; previous emulator session. Items which can be changed by Set Term
; are examined and updated. The msy flags "yflags" are needed.
; This is the warm-restart entry point used when connect mode
; is reentered gracefully. The screen is cleared only if the coloring
; has changed. The starting cursor location is whereever msy puts it.
; ansdsl - display "led" (status line) information. Invoked by msy when
; the mode line is constructed so the emulator can write the
; terminal type and the VT100 led status lights when Connect mode
; is started. Requires "yflags" from msy to sense whether the mode
; line is to be shown.
; anstat - reports our working flags and screen coloring to msy. Nearly
; obselete but not quite. Reads msy "yflags" and reports "mlbattr"
; the video attributes used on the mode line, "scbattr" the video
; attributes of an empty character cell (background), "curattr"
; the video attributes of displayable characters, and "ansflgs"
; the emulator's working flags (needed for keyboard translations
; done in msy).
; anskbi - a routine called by msy to notify the emulator that a character
; is available from the keyboard. No character is read, just flag
; ttkbi is set. This is actually used only to beep when the cursor
; goes beyond column 72 and the margin bell flag is on.
; ans52t - called by msy to change terminal types "on the fly" without
; fully updating all operating parameters and without losing setup
; information. Msy senses the Alt minus key and calls ans52t with
; no arguments. Ans52t cycles among VT102, VT52 and Heath-19 modes.
; vclick - called by msy to cause a click sound. Simulates keyboard clicks,
; sort of anyway. No arguments.
; other modules in msy are called by this file to handle screen scrolling
; mode line on/off, output to the serial port (reports), screen
; particulars (location, cursor shape, blanking). The list is
; the set of code extrn procedures below; all are in file msy.
;
; data exchange is directly with msy to assist in scrolling (varaibles
; "mar_top", "mar_bot") and in sensing the non-connect
; mode screen coloring ("scbattr"). Screen coloring controlled by
; the emulator is not permitted to influence the non-connect mode
; screens whereas the emulator attempts to use the regular Kermit
; screen colors as defaults. The kind of terminal to emulate is
; held in byte "flags.vtflg" which is set by Set Term and by this
; module for global information within Kermit.
;
; The emulator assumes the screen is laid out in the manner of a conventional
; IBM monochrome or color graphics adapter running in 80 column TEXT
; modes. That layout is one word per displayable location starting at
; the upper left corner (0,0) and running contiguously to the lower
; right corner (24,79). Each word holds the displayable character in
; the low order byte and the display attributes in the high order
; byte. Attributes are, from high to low bits: blinking on, back-
; ground red, green, and blue on, high intensity, foreground red,
; green, and blue on. Normal white chars on a black field is 07H.
; The starting segment of screen memory is given by msy module
; "scrseg" to be TopView/MS Windows compatible. Msy module "scrsync"
; is used to inform these windowing environments of memory updates.
; Variable "crt_mode" is set by msy to indicate which IBM display
; mode is active; only the monochrome and CGA modes are recognized.
; Direct reading and writing of display memory is done, compatibly
; with TopView/Windows, to attain speed over Bios and DOS calls
; when editing of previously entered text is needed. However, IBM
; Bios interrupt 10H is used where possible for normal cursor
; movement/sensing and writing of new characters. See the IBM PC
; hardware Technical Reference Manuals for further details.
;
; Many things have been added, or modified since James Harvey donated this
; code to Columbia University for use in Kermit. [jrd]
; ---------------------------------------------------------------------------
screen equ 10h ; Bios screen call
swidth equ 132 ; assumed max screen width [dlk]
slen equ 43 ; assumed max screen length [jrd]
att_low_mask equ 06H ; Various attribute-related equates
;;;att_reverse equ 70H ; these two are now storable items
;;;att_normal equ 07H ; to allow external settings. [jrd]
att_underline equ 01H
att_intensity equ 08H
att_blink equ 80H
; VT100 status flags ansflg
;anslnm equ 01H ; ANSI line feed/new line mode
;decckm equ 02H ; VT100 cursor keys mode
;deckpam equ 04H ; VT100 keypad application mode
;decscnm equ 08H ; VT100 screen mode (n.y.i.)
;decom equ 10H ; VT100 origin mode
;decawm equ 20H ; VT100 autowrap mode
;decanm equ 40H ; ANSI(VT100)/VT52 mode
;decmode equ 80H ; "?" seen in lead-in
;;;;;;;;;;;;;;;; items for reference from mssdef.h ;;;;;;;;;;;;;
; VT100 SETUP mode flags
;vsscreen equ 40H ; Screen mode (0 = normal video)
;vscursor equ 20H ; Cursor (0 = block)
;vsmarginbell equ 10H ; Margin bell (0 = off)
;vskeyclick equ 08H ; Keyclick (0 = off)
;vsshift3 equ 04H ; Shift-3 (0 = American pound sign)
;vswrap equ 02H ; Line wrap around (0 = no wrap)
;vsnewline equ 01H ; ANSI new line (0 = off)
;vsdefaults equ 0+vscursor
;[IU1] Definitions for terminal emulation
;TTGENRC EQU 0 ; Type 0 - TTY (no special emulation)
;TTHEATH EQU 1 ; Type 1 - HEATH 19
;TTVT52 EQU 2 ; Type 2 - VT52
;TTVT100 EQU 3 ; Type 3 - ANSI (VT100 subset)
;TTTEK EQU 4 ; Type 4: Tektronix 4010
;TTTYPES equ 5 ; Number of terminal types defined
;emulst struc ; structure of vtemu.xxx for VT100 emulator
;vtflgst db 0 ; VT100 setup flags (from SET)
;vtflgop db 0 ; VT100 runtime flags, like setup flags (here & STAT)
;vttbs dw 0 ; pointer to default tab stops, for SET
;vttbst dw 0 ; pointer to active tab stops, for STATUS
;att_ptr dw 0 ; pointer to normal & reverse video attributes
;emulst ends
;;;;;;;;;;;;;;;; end references ;;;;;;;;;;;;;;;;;;;;
datas segment public 'datas'
extrn vtemu:byte, crt_mode:byte, scbattr:byte, flags:byte
extrn crt_lins:byte, crt_cols:byte, rxtable:byte, denyflg:word
extrn usevb:byte
extrn tekflg:byte
; Early versions of MASM have a bug that causes it to consider the
; expression (offset foo) as non-relocatable if used in an arithmetic
; operation (for example, "sub di,offset foo"), and if foo is defined
; within the first 256 bytes of the data segment.
; ANSI special character table - 32 entries indexed by control char value
ansspc dw 5 dup (atign) ; ignore NUL,SOH,STX,ETX,EOT
dw atign ; ENQ - answerback message
dw atign ; ACK - ignore
dw atbel ; BEL - ring terminal bell
dw atbs ; BS - ANSI backspace
dw atht ; HT - ANSI tab
dw atlf ; LF - ANSI line feed
dw atlf ; VT - Interpreted as ANSI LF
dw atff ; FF - do as LF (but ESC FF does Tek)
dw atcr ; CR - ANSI carriage-return
dw atso ; SO - Select char set G1
dw atsi ; SI - Select char set G0
dw 8 DUP (atign) ; ignore DLE,DC1,DC2,DC3,DE4,NAK,SYN,ETB
dw atcan ; CAN - cancel ANSI sequence
dw atign ; EM - ignore
dw atcan ; SUB - treat as CAN
dw atesc ; ESC - ANSI CSI.
dw 4 DUP (atign) ; ignore FS,GS,RS,US
; Heath-19 mode escape follower table
h19esc db 'YABCD', 'KIHJF', 'G=><Z', 'ELM'
db 'NO@p', 'qvwjk', 'xynz', 'blor'
lh19esc equ $-h19esc
; Dispatch table for Heath-19 escape sequence table h19esc.
; Two byte sequences of the form ESC char, where char is not in the
; table above, are completely ignored.
h19ejt dw v52pos,atcuu,h19cud,h19cuf,atbs ; 'YABCD'
dw atel,atri,atcup,ated,v52egm ; 'KIHJF'
dw v52xgm,atkpam,atkpnm,h19ans,decid ; 'G=><Z'
dw h19clrs,inslin,dellin ; 'ELM'
dw atdelc,noins,entins,h19herv ; 'NO@p'
dw h19hxrv,h19wrap,h19nowrp,atsc,atrc ; 'qvwjk'
dw h19smod,h19cmod,hrcup,atreset ; 'xynz'
dw h19erb,h19erl,h19ero,h19mbr ; 'blor'
; Heath-19 special graphics characters. Use as offsets from caret (94D) [jrd]
hgrtab db 249,17,179,196,197 ; caret,underscore,accent grave,a,b
db 191,217,192,218,241 ; c,d,e,f,g
db 26,219,246,25,220 ; h,i,j,k,l
db 220,223,223,223,222 ; m,n,o,p,q
db 16,203,185,202,204 ; r,s,t,u,v
db 'X','/','\','-','-' ; w,x,y,z,{
db 221,222,20 ; |,},~
; VT52 compatibility mode escape follower table
v52esc db 'Y','A','B','C','D'
db 'K','I','H','J','F'
db 'G','=','>','<','Z'
db '7','8','c','^','_'
db 'W','X',']','V'
lv52esc equ $-v52esc ; length of table
; Dispatch for v52esc table
v52ejt dw v52pos,atcuu,atcud,atcuf,atcub
dw atel,atri,atcup,ated,v52egm
dw v52xgm,atkpam,atkpnm,v52ans,decid
dw atsc,atrc,v52ris,v52apb,v52ape
dw v52pcb,v52pce,v52ps,v52pl
; ANSI escape special character table
ansesc db '[','D','E','M','H'
db '7','8','=','>','c'
db '(',')','#','Z','<'
db 'P','*'
lansesc equ $-ansesc ; length of table
; Dispatch for ansesc table
ansejt dw atcsi,atind,atnel,atri,athts
dw atsc,atrc,atkpam,atkpnm,atris
dw atsg0,atsg1,atsdhl,at52id,atnorm
dw atpriv,atpriv
; Final char table for ANSI escape sequences (ESC [ Pn ; ... Pm ch)
anstab db 'H','A','B','C','D'
db 'K','J','m','g','r'
db 'c','q','x','n','f'
db 'l','h','y','P','L'
db 'M','i','s','u','z'
db '@'
lanstab equ $-anstab ; Define table length
; Dispatch for anstab table
ansjmp dw atcup,atcuu,atcud,atcuf,atcub
dw atel,ated,atsgr,attbc,atstbm
dw atda,atll,atreqt,atdsr,atcup
dw atrm,atsm,atctst,atdelc,inslin
dw dellin,ansprt,htsc,htrc,htrest
dw ansich
; "Special graphics" set translation table for characters 137 (octal)
; through 176 when the special graphics set is selected. Some characters
; (142, 143, 144, 145, 150, 151, 157, 160, 162, 163, and 174) do not
; have exact equivalents in the available set on the IBM, so a (some-
; times reasonably close) substitution is made. Table is indexed by
; ASCII char value minus 137 octal for chars 137-176 octal.
sgrtab db 032,004,177,026,023
db 027,025,248,241,021
db 018,217,191,218,192
db 197,196,196,196,196
db 196,195,180,193,194
db 179,243,242,227,157
db 156,250
; Device attributes response string. (Note: If "with AVO" causes problems,
; change the last parameter from "2" to "0". The default is to indicate
; the AVO option is present because the emulator can set all of the graphic
; rendition attributes (bold, blink, etc.) independently). A VT100 reports
; as ESC [ ? 1 ; 2 c but a VT102 uses ESC [ ? 6 ; 2 c.
dastr db escape,'[?6;2c' ; VT102
ldastr equ $-dastr
; Identify response used while in VT52 compatibility mode...
v52str db escape,'/Z'
lv52str equ $-v52str
; Identify response when a Heath-19 terminal. [jrd]
h19str db escape,'/K'
lh19str equ $-h19str
; ANSI Escape sequence to turn off Media Copy (Print Controller Off)
mcoff db escape,'[4i'
mcofflen equ $-mcoff ; length of sequence
mcoffs db 4 dup (0) ; received chars in sequence
mccnt dw ? ; counter of matched char in mcoff
; Parity code translation table
partab db 5 ; Even
db 3 ; Mark
db 1 ; None
db 4 ; Odd
db 2 ; Space
lpartab equ $-partab
; Baud rate code translation table
baudtab db 0 ; 45.5 - no VT100 code (call it 50)
db 0 ; 50
db 8 ; 75
db 16 ; 110
db 24 ; 134.5
db 32 ; 150
db 48 ; 300
db 56 ; 600
db 64 ; 1200
db 72 ; 1800
db 80 ; 2000
db 88 ; 2400
db 104 ; 4800
db 112 ; 9600
db 120 ; 19200
db 128 ; 38400 extended beyond DEC [jrd]
lbaudtab equ $-baudtab
belcol db ? ; column at which to ring margin bell
yflags db ? ; Flags from MSYxxx term routine.
video_state db 0 ; video state (0=normal,1=reversed)
oldbatr db ? ; old scbattr [jrd]
oldterm db ? ; terminal type from previous entry
baudidx db ? ; Index into baud rate table
parcode db ? ; Parity code (0-4)
datbits db ? ; Number of databits (7 or 8)
savflgs db ? ; Saved flags for atsc/atrc.
modeset db ? ; Temp for atsm/atrm.
h19mod db ? ; flag for atsm/atrm.
h19l25 db ? ; Heath-19 25th line enabled flag
insmod db ? ; Insert mode on (1) or off (0).[jrd]
kbicsr dw ? ; Cursor when keyboard input typed
kbiflg db ? ; Set/reset for keyboard input
ttstate dw offset atnrm ; terminal automata state.
; Start of stuff to save for ESC 7 fxn
ukset equ 0 ; Set 1 = UK ASCII set
ascset equ 1 ; Set 2 = US ASCII set
sgrset equ 2 ; Set 3 = "Special graphics set"
svattr_index equ 0 ; To set saved cursor attribute only.
curattr db 07h ; Cursor attribute
cursor dw 0 ; Cursor position
chr_set dw offset chr_sg0 ; Ptr. to currently selected char set
chr_sg0 db ascset ; Current SG0 set
chr_sg1 db ascset ; Current SG1 set
lsavecu equ $-curattr ; Length of stuff to save.
savecu db lsavecu dup (?) ; Saved cursor, attr., charset, etc.
h19ctyp db 1 ; H-19 cursor type (1=ul, 2=bk, 4=off)
att_normal db 07H ; retain order: normal then reverse
att_reverse db 70H
mlbattr db ? ; Mode line background attribute
ansflgs db 0 ; ANSI/VT100 mode flags
; (flags are defined in mssdefs.h)
vtflags db 0 ; VT100 SETUP flags
; (SETUP flags are defined in mssdefs.h)
tmpflags db 0 ; (Temporary for asnrei/stblmds).
; (tab stops are stored here) ; [jrd]
tabs db swidth dup (?) ; active tab stops.
deftabs db swidth dup (?) ; default tab stops
vttabs dw 0 ; Pointer to default VT100 tab stops
; byte per line, type of line: 0=normal, 1=double wide, 2=double high [jrd]
linetype db slen dup (?)
linelen db 79 ; active screen line length (79, 131)
low_rgt dw 0 ; text screen dimensions.
; byte low_rgt = max columns (79)
; byte low_rgt+1 = max rows (23)
ttkbi db 0 ; Flag for keyboard input seen.
; Scrolling region - do not separate or change order of mar_top & mar_bot.
mar_top db ? ; Scrolling region top margin
mar_bot db ? ; Scrolling region bottom margin
led_col equ 65 ; column position for "LEDs" display
led_off equ '.' ; "Off" LED. [jrd]
ansleds db 'VT102 ....' ; "LEDs".Terminal ident (10 bytes)
v52leds db ' VT52 ' ; This is used in VT52 mode.
h19leds db ' Heath-19 ' ; For Heath-19 mode [jrd]
; message for mode line [jrd]
pntmsg db 'Printer not ready, printing request skipped.'
pntmsgl equ $-pntmsg ; length of pntmsg
nansarg db 0 ; Index for ANSI argument list
ansargs db 16 dup (0) ; Room for 16 ANSI arguments
lansarg equ $-ansargs ; Max number of ANSI arguments
; printer support data
anspflg db 0 ; printer flag bits and definitions
vtautop equ 1 ; autoprint enabled (1)
vtcntp equ 2 ; controller print enabled (1)
vtextp equ 4 ; printer extent set (1)
vtffp equ 8 ; form feed wanted at end of print (1)
trtbl db 0h,1h,2h,3h,1h,2h,3h,7h ; color translation table
db 7h,9h,0ah,0bh,9h,0ah,0bh,0fh
db 10h,14h,15h,16h,14h,15h,16h,18h
db 18h,19h,1ah,1bh,1ch,1dh,1eh,1fh
db 20h,24h,25h,26h,24h,25h,26h,28h
db 28h,29h,2ah,2bh,2ch,2dh,2eh,2fh
db 30h,34h,35h,36h,34h,35h,36h,38h
db 38h,39h,3ah,3bh,3ch,3dh,3eh,3fh
db 41h,41h,42h,43h,41h,42h,43h,47h
db 47h,49h,4ah,4bh,49h,4ah,4bh,4fh
db 51h,51h,52h,53h,51h,52h,53h,57h
db 57h,59h,5ah,5bh,59h,5ah,5bh,5fh
db 61h,61h,62h,63h,61h,62h,63h,67h
db 67h,69h,6ah,6bh,69h,6ah,6bh,6fh
db 70h,74h,75h,76h,74h,75h,76h,78h
db 78h,79h,7ah,7bh,7ch,7dh,7eh,7fh
datas ends
code segment public 'code'
extrn prtbout:near, prtnout:near, csrtype:near, trnmod:near
extrn scrmod:near, scrseg:near, scrsync:near, scroff:near
extrn scron:near, atsclr:near, vtscru:near, vtscrd:near
extrn modwrt:near, telmsy:near, scrloc:near, pcwait:near
extrn chgdsp:near, trnprs:near, cptchr:near, tekesc:near
; extrn procedures are all in module msyibm
extrn tekini:near, tekemu:near, tekend:near
assume cs:code, ds:datas, es:datas
; This routine initializes the VT100 setups at startup. It is called from
; procedure lclyini in module msyibm.
vsinit proc near
mov vtemu.vtflgst,vsdefaults ; Init to defaults in mssdef.h
mov vtemu.vtflgop,vsdefaults ; Init runtime state to setup items
mov insmod,0 ; turn off insert mode. [jrd]
mov deftabs,0 ; Column 1 has no tab stop.
mov cl,crt_cols ; physical screen width (80)
dec cl ; we count from column 0
mov ch,crt_lins ; physical screen length-1
dec ch ; we count from row 0
mov low_rgt,cx ; store active text area
mov cx,131
mov di,1 ; Starting index for column 2.
vsini1: mov al,0 ; Assume we will clear this one.
test di,0007H ; Index mod 8 equals 0?
jnz vsini2 ; No, clear it.
mov al,0FFH ; Yes, set it.
vsini2: mov deftabs[di],al ; Set or clear a tab stop.
inc di ; Advance to next.
loop vsini1 ; Loop for all.
mov cx,slen ; clear linetype array [jrd]
mov di,0
vsini3: mov linetype[di],0
inc di
loop vsini3
mov vtemu.vttbst,offset deftabs ; addrs of active tabs for STATUS
mov vtemu.vttbs,offset deftabs ; addrs of tabs for setup (SET)
mov vttabs,offset deftabs ; initial source of tabs. [jrd]
call cpytabs ; copy default to active [jrd]
mov vtemu.att_ptr,offset att_normal ; ptr to video attributes[jrd]
mov ah,8 ; read current attributes
xor bh,bh ; page 0
int screen
mov scbattr,ah ; save video attributes
mov att_normal,ah ; set att_normal to present colors
call brkatt ; separate colors from blink/bold
rol ah,1 ; reverse foreground & background
rol ah,1 ; RGB bits.
rol ah,1
rol ah,1
call addatt ; reinsert bold/blink bits
mov att_reverse,ah ; set att_reverse too.
mov ah,byte ptr low_rgt ; right most column (counted from 0)
sub ah,8 ; place marker 9 columns from margin
mov belcol,ah ; store column number to ring bell
ret ; And return.
vsinit endp
; Initialization routine.
;
; Call: al/ yflags byte that was passed to Term routine.
; dl/ index for baud rate table
; dh/ parity in bits 4-7, number of data bits in bits 0-3
;
ansini proc near
mov yflags,al ; Always save flags
mov ah,vtemu.vtflgst ; setup flags [jrd]
mov vtflags,ah
mov vttabs,offset deftabs ; tab stop pointer.
mov vtemu.vttbst,offset tabs; store here for STATUS [jrd]
mov al,flags.vtflg ; get current terminal type
mov oldterm,al ; remember it here for soft restarts
mov insmod,0 ; turn off insert mode. [jrd]
mov h19l25,0 ; clear Heath 25th line enable. [jrd]
mov h19ctyp,1 ; set Heath cursor to underline, on
mov anspflg,0 ; clear printer flag [jrd]
push ax
mov ah,byte ptr low_rgt ; right most column (counted from 0)
sub ah,8 ; place marker 9 columns from margin
mov belcol,ah ; store column number to ring bell
pop ax
cmp dl,lbaudtab ; Wierd index?
jb ansin1 ; No - OK - store it.
mov dl,lbaudtab-1 ; Yes - make it the maximum.
ansin1: mov baudidx,dl ; Save baud rate index
mov al,dh ; Get parity/number of databits
and al,0FH ; Isolate number of databits
mov datbits,al ; Save.
mov cl,4 ; Isolate parity code
shr dh,cl ; Isolate parity code
cmp dh,lpartab ; Weird code?
jb ansin2 ; No - OK - store it.
mov dh,lpartab-1 ; Yes - make it the maximum.
ansin2: mov parcode,dh ; Save.
call scrmod ; Get the screen mode, in MSYxxx
mov cl,crt_cols ; physical screen number columns (80)
dec cl ; we count from column 0 here
mov ch,crt_lins ; physical screen number rows-1 (24)
dec ch ; we count from row 0 here
mov low_rgt,cx ; save as active text screen size
ansin3: call atreset ; Reset everything
mov ttstate,offset atnrm ; Reset state to "normal".
ret ; And return.
ansini endp
; Re-initialization routine. Called when Term was called but screen was
; restored from a previously saved screen, etc.
;
; Call: al/ yflags byte that was passed from msyibm module.
;
ansrei proc near
mov yflags,al ; Always save flags
mov ah,vtemu.vtflgop ; get runtime flags [jrd]
mov tmpflags,ah
call scrmod ; Get the screen mode.
call atsctyp ; set cursor type [rbv]
mov ah,3 ; get cursor position from msy
mov bh,0 ; Page zero.
int screen
mov cursor,dx ; dh = row, dl = column
mov cl,crt_cols ; physical screen number columns (80)
dec cl ; we count from column 0 here
mov ch,crt_lins ; physical screen number rows-1 (24)
dec ch ; we count from row 0 here
mov low_rgt,cx ; save as active text screen size
cmp linelen,79 ; want 80 cols?
ja ansre2 ; a = no
cmp byte ptr low_rgt,79 ; want 80 cols. Is active screen wider?
jbe ansre2 ; be = no
mov byte ptr low_rgt,79 ; narrow down to 80 columns
ansre2: call stblmds ; Check settable modes, set flags.
ret
ansrei endp
; This routine copies the new tab stops when they have changed.
; Copies all 132 columns.
cpytabs proc near
mov cx,swidth ; number of screen columns
jcxz cpytab1 ; z = none to do
mov si,vttabs ; Source.
mov di,offset tabs ; Destination.
push es ; save es
push ds
pop es ; set es to datas segment
cld
rep movsb ; Do the copy.
pop es ; recover es
cpytab1:ret
cpytabs endp
; This routine checks to see whether any of the settable modes have changed
; (things that can be changed in both SETUP and by host commands), and
; changes those that need to be changed. TMPFLAGS has the new VT100 setup
; flags, VTFLAGS has the old. This routine also updates VTFLAGS.
; Revised by [jrd] to allow MSY to reset scbattr when not in connect mode,
; to do "soft reset" if terminal type has changed, and to do a screen clear
; reset if the actual screen colors have changed.
stblmds proc near
mov al,flags.vtflg ; get current terminal type [jrd]
cmp al,oldterm ; same as before?
je stblm10 ; e = yes, skip over soft reset.
mov oldterm,al ; remember current terminal type
mov insmod,0 ; reset insert mode flag
mov h19l25,0 ; reset heath-19 25th line enable
mov mar_top,0 ; reset top scrolling margin
mov al,byte ptr low_rgt+1 ; and scrolling margin
mov mar_bot,al ; to last normal line on screen
mov ah,byte ptr low_rgt ; right most column (counted from 0)
sub ah,8 ; place marker 9 columns from margin
mov belcol,ah ; store column number to ring bell
and ansflgs,decckm+deckpam+decom ; save some flags
push bx ; save this register around loop
mov bx,offset linetype ; setup to clear double width chars
mov cx,slen ; number of linetype slots to clear
cmp flags.vtflg,ttvt100 ; VT100 now?
jne stblm0 ; ne = no
or ansflgs,decanm ; set ansi flag bit
stblm0: mov byte ptr [bx],0 ; clear the linetype array to single
inc bx ; width characters.
loop stblm0 ; do each line (1 byte per line)
pop bx ; restore bx
stblm10:mov al,tmpflags ; Get the new flags.
and ansflgs,not anslnm ; assume we do not want newline
test al,vsnewline ; is newline mode desired?
jz stblm1 ; No - continue.
or ansflgs,anslnm ; Yes - set corresponding mode flag.
stblm1: and ansflgs,not decawm ; assume not want wrap
test al,vswrap ; Did wrap mode change?
jz stblm2 ; No - continue.
or ansflgs,decawm ; Yes - set corresponding mode flag.
stblm2: mov ah,vtflags ; old flags
xor ah,tmpflags ; new flags
test ah,vsshift3 ; pick out char set bit
jz stblm4 ; z = no change
mov ah,ascset ; assume US ASCII.
test tmpflags,vsshift3 ; Want UK?
jz stblm3 ; No - guessed right.
mov ah,ukset ; Yes - use UK set.
stblm3: mov chr_sg0,ah ; Set the sets.
mov chr_sg1,ah
stblm4: mov ah,oldbatr ; get old screen background scbattr
mov scbattr,ah ; and update working copy
mov ah,att_normal ; get new attributes (Set Term Color)
push bx
mov bh,ah ; get new intensity bit of att_normal
and bh,att_intensity
and curattr,not att_intensity ; char attrs. clear intensity bit
or curattr,bh ; set new intensity
and mlbattr,not att_intensity ; mode line attrs. clear intensity
and scbattr,not att_intensity ; screen background attribute
or scbattr,bh ; set its intensity also
mov bl,scbattr
mov oldbatr,bl ; and save it here as well
pop bx
call brkatt ; separate color and blink/bold
rol ah,1 ; reverse fore/back color fields
rol ah,1
rol ah,1
rol ah,1
call addatt ; put back blink/bold
push bx ; check on color change
mov bh,ah ; new att_reverse pattern
and bh,not(att_intensity+att_blink) ; look at just color bits
mov bl,att_reverse ; previous att_reverse pattern
and bl,not(att_intensity+att_blink) ; look at just color bits
mov att_reverse,ah ; save new reverse pattern
cmp bh,bl ; have any color bits changed?
pop bx ; does not affect flags
je stblm9 ; e = no
mov cursor,0 ; reset cursor position
jmp atres2 ; go to semi-reset
stblm9: ; check on screen normal/reversed.
mov al,tmpflags
xor al,vtflags ; Find which ones have changed.
test al,vsscreen ; How about screen background?
jz stblm8 ; No - don't touch it.
test tmpflags,vsscreen ; Flag to be set?
jnz stblm5 ; Yes - go to it.
and ansflgs,not decscnm ; No - cleared (normal video).
and savflgs,not decscnm
mov al,att_normal ; No - get new background.
jmp short stblm6 ; And reverse everything.
stblm5: or ansflgs,decscnm ; Set (reverse video).
or savflgs,decscnm
mov al,att_reverse ; No - set reverse video.
stblm6: call atrss2 ; Reverse screen and cursor attribute.
stblm7: mov al,scbattr ; Reset saved attribute also.
mov savecu+svattr_index,al
mov oldbatr,al ; and save our attribute
stblm8: mov al,tmpflags ; Get new flags.
mov vtflags,al ; Store them.
ret
stblmds endp
; Return screen offset - given rol, col in dx, returns offset of the word
; for that character from the screen origin in ax. Preserves all other acs.
; Use same routine in msy to more closely track screen width. [jrd]
;;scrloc proc near
;; push bx ; We will use bx.
;; mov al,dh ; Get row.
;; mov bl,swidth ; And length of a line
;; mul bl ; Offset for this row
;; mov dh,0 ; Clear row.
;; add ax,dx ; Word offset for this position
;; sal ax,1 ; Make it a byte offset
;; pop bx ; Restore bx.
;; ret ; And return.
;;scrloc endp
; Fetch status/attributes routine.
;
; Call: al/ "yflags" byte from MSYxxx.
;
; Return: ah/ mode line background attribute
; al/ screen background attribute
; bl/ current cursor attribute
; bh/ ANSI (VT100) mode flags
anstat proc near
mov yflags,al ; Mostly for disleds
mov ah,mlbattr ; Return them our attrs, flags, etc.
mov al,scbattr
mov bl,curattr
mov bh,ansflgs
ret
anstat endp
; Routine called when something is typed on the keyboard
;
; Call: No arguments
;
anskbi proc near
mov ttkbi,0FFH ; Just set a flag
ret
anskbi endp
; Routine to do keyclick if flag is set.
;
; Call: No arguments
;
vclick proc near
test vtflags,vskeyclick ; Is the flag on?
jz vclick1 ; No - just return
push bx ; Save some ACs
push di
mov di,8 ; 5000 Hertz [rwb]
mov bx,1 ; For 3 milliseconds. [rwb]
call vtsound ; Do it.
pop di ; Restore the ACs
pop bx
vclick1:ret
vclick endp
; Routine to do VT100-style bell.
;
; Call: No arguments
;
vtbell proc near
push di
push bx
mov di,45 ; 880 Hertz [rwb]
mov bx,22 ; For 70 ms. [rwb]
call vtsound ; Do it.
pop bx
pop di
ret
vtbell endp
; Routine to make noise of arbitrary frequency for arbitrary duration.
; Derived from a routine in December 1984 Soft Sector, page 28. [rwb]
; Frequency and duration parameters are different than in the IBM ver. [rwb]
; Sound is generated by toggling the break bit in the keyboard UART [rwb]
;
; Call: di/ frequency is 40KHz / di value [rwb]
; bx/ duration is 3.2 msec * bx value [rwb]
; These approximate values break down badly for di < 10 [rwb]
; or if an accelerator board is installed. [rwb]
vtsound proc near
push ax ; Save regs.
push bx
push cx
mov ax,35h ; UART cmd with break bit off
vtsou1: mov cx,di
xor al,8 ; toggle break bit
out 3ah,al ; send it to UART
vtsou2: dec ah
jnz vtsou3
dec bx ; count down duration
jz vtsou4
vtsou3: loop vtsou2 ; frequency count down
jmp vtsou1
vtsou4: mov al,35h
out 3ah,al ; turn off break bit on exit
pop cx ; Restore regs.
pop bx
pop ax
ret
vtsound endp
; Routine to toggle VT100/VT52/Heath-19 modes. No arguments.
; Use & update global byte flags.vtflg for terminal type and update local
; bit decanm. Note: shifting to Heath-19 here does Not reset the scrolling
; margins mar_top & mar_bot nor reset the double char linetype array.
; [jrd]
ans52t proc near
cmp tekflg,0 ; in Tek sub mode?
jne ans52c ; ne = yes, get out now
cmp flags.vtflg,ttvt100 ; in VT100 mode?
jne ans52a ; ne = no
and ansflgs,not decanm ; reset VT100 ansi mode
mov flags.vtflg,ttvt52 ; say VT52 now (clears vt100 bit)
mov oldterm,ttvt52 ; and remember it
jmp ans52e
ans52a: cmp flags.vtflg,ttvt52 ; in VT52 mode?
jne ans52b ; ne = no
mov flags.vtflg,ttheath ; say Heath-19 now
mov oldterm,ttheath
jmp ans52e
ans52b: cmp flags.vtflg,ttheath ; in Heath-19 mode?
jne ans52c ; ne = no
call atsc ; save cursor and associated data
mov flags.vtflg,tttek ; set Tek mode
call tekini ; init Tek to switch screens
jmp atnorm ; normal state and return
ans52c: cmp flags.vtflg,tttek ; in Tek mode now?
je ans52d ; e = yes
cmp tekflg,0 ; doing Tek sub mode?
jne ans52d ; ne = yes
jmp atnorm ; else ignore this call
ans52d: call tekend ; exit Tek graphics mode
mov tekflg,0 ; end Tek sub mode (do after tekend)
mov flags.vtflg,ttvt100 ; say VT100 now
mov oldterm,ttvt100
or ansflgs,decanm ; set, go to VT100 mode
call atrc ; restore cursor etc
cmp flags.modflg,0 ; is mode line disabled? [jrd]
je ans52e ; e = yes, disabled [jrd]
test yflags,modoff ; Mode line off?
jnz ans52e ; nz = yes - just return.
mov al,yflags ; get current flags
or al,modoff ; say mode line is off
call telmsy ; let msy hear the news
call trnmod ; turn it on
ans52e: call chrdef ; Set default character sets
call atsc ; Save cursor etc.
call disleds ; Remove or redisplay "LEDs".
jmp atnorm ; Say state is "normal" and return.
ans52t endp
; Display "LEDs" routine. Note that this routine
; is not used internally in this module (because it updates the flags from
; MSYIBM). Internally, disleds is used instead. The yflags from MSYIBM are
; needed because we have to know if the mode line is enabled.
;
; Call: al/ yflags from MSYIBM
;
; Return: Current state of "LEDs" displayed on line 25.
;
ansdsl proc near ; Update flags and display "LEDs"
mov yflags,al ; Update the flags.
call disleds ; Display LEDs
ret
ansdsl endp
; Internal routine to display LEDs.
disleds:test yflags,modoff ; Mode line off?
jnz disled2 ; Yes - just return.
;; mov al,0 ; Turn cursor off.
;; call csrtype
mov ah,2 ; Position cursor at (slen-1),70
mov bh,0 ; Page zero.
mov dh,byte ptr low_rgt+1 ; last screen line - 1
inc dh ; status line
mov dl,led_col ; column for led display
int screen
mov cx,10 ; Length of byte array is ten
mov si,offset ansleds ; The "LEDs"
cmp flags.vtflg,ttvt100 ; VT100 mode?
je disled1 ; e = yes
mov si,offset v52leds ; try VT52
cmp flags.vtflg,ttvt52 ; VT52?
je disled1 ; e = yes
mov si,offset h19leds ; use Heath-19
disled1:lodsb ; Get a character
mov ah,14 ; Write character function
mov bh,0 ; Page zero.
int screen ; ...
loop disled1 ; Loop for all chars
mov ah,2 ; Reposition cursor when finished
mov bh,0 ; Page zero
mov dx,cursor
int screen
call atsctyp ; Reset right type of cursor.
disled2:ret
; ANSI terminal output routine. Call with character in al.
anstty proc near ; ANSI terminal output.
mov dx,cursor ; Some routines need cursor in dx.
mov kbiflg,0 ; Clear old flag value
test yflags,trnctl ; Debug mode?
jz anstt1 ; z = no
jmp atdeb ; Yes - just translate control chars.
anstt1: cmp ttkbi,0 ; New keyboard input?
je anstt2 ; No - just continue
mov kbiflg,1 ; Yes - set flag
mov kbicsr,dx ; Save old cursor
mov ttkbi,0 ; Clear this flag.
anstt2: test anspflg,vtcntp ; print controller on?
jz anstt4 ; z = no
test yflags,capt ; capturing output?
jz anstt3 ; z = no, forget this part
push ax ; save char
call cptchr ; give it captured character
pop ax ; restore character
anstt3: jmp ansmc ; print transparently
; Set Display 7/8 bit filter
anstt4: test flags.remflg,d8bit ; keep 8 bits for displays?
jnz anstt5 ; nz = yes, 8 bits if possible
and al,7fh ; remove high bit
anstt5: cmp al,spc ; control char?
jb anstt6 ; b = yes
cmp ttstate,offset atnrm ; doing displayable text?
jne anstt7 ; ne = no, no translation
; Set Translation filter
anstt6: cmp rxtable+256,0 ; translation turned off?
je anstt7 ; e = yes, no translation
mov bx,offset rxtable ; address of translate table [jrd]
xlatb ; new char is in al
anstt7: cmp al,DEL ; ANSI Delete char?
je atdel ; e = yes, ignore it before logging
cmp al,0 ; NUL char?
je atign ; e = yes, ignore it before logging
test yflags,capt ; capturing output?
jz anstt8 ; z = no, forget this part
push ax ; save char
call cptchr ; give it captured character
pop ax ; restore character and keep going
; Direct char to processor module
anstt8: cmp al,20h ; Control character?
jb atctrl ; b = yes, handle it.
anstt9: jmp ttstate ; Nope, dispatch according to state.
atign: ret ; Something to be ignored.
atctrl: mov ah,0 ; Make sure this is zero..
cmp al,escape ; an escape sequence starting?
je atctrl1 ; e = yes, don't print it
test anspflg,vtautop+vtcntp ; printing desired?
jz atctrl1 ; z = no
call pntchr ; print char in al
atctrl1:mov di,ax ; Put it in an index register
shl di,1 ; Make it a word offset
jmp ansspc[di] ; Dispatch.
atdel: jmp short atign ; ignore DEL char
;; test yflags,lclecho ; doing local echoing?
;; jz atign ; z = no, ignore character
;; mov ansargs,0 ; Delete one char to left [jrd]
;; cmp dl,0 ; at column 0 already?
;; je atdel1 ; e = yes
;; dec dl ; move back one column
;;atdel1: call atscu5 ; move the cursor there and
;; jmp atdelc ; delete the char now under cursor
atdeb: test yflags,capt ; capturing output?
jz atdeb3 ; z = no, forget this part
push ax ; save char
call cptchr ; give it captured character
pop ax ; restore character and keep going
atdeb3: mov bh,ansflgs ; Save flags and attribute
mov bl,curattr
push bx
push word ptr mar_top ; Save limited scrolling region
push ax ; Save character for a second
mov ah,curattr ; Get attribute
call brkatt ; Break it up
and al,att_intensity ; clear attributes, except bold bit
call addatt ; Put it back together
mov curattr,ah ; Store
or ansflgs,decawm ; Set autowrap temporarily
mov mar_top,0 ; Set scrolling region to entire page
mov al,byte ptr low_rgt+1
mov mar_bot,al
pop ax ; Restore character
test al,80h ; high bit set? [jrd]
jz atdeb0 ; z = not set
push ax ; Save the character for a second
mov al,7eh ; Output a tilde [jrd]
call atnrm2
pop ax ; Restore character
and al,7fh ; and remove high bit
atdeb0: cmp al,del ; A DELETE?
je atdeb1 ; Yes - output "^?" [jrd]
cmp al,20h ; A control character?
jnb atdeb2 ; No - just output char in al.
atdeb1: push ax ; Save the character for a second
mov al,5eh ; Output a caret [jrd]
call atnrm2
pop ax ; Restore character
add al,40h ; Make ^letter (or ^? for DELETE)
and al,7fh ; Clear bit 7 (for DELETE)
atdeb2: call atnrm2 ; Output translated character
pop word ptr mar_top ; Restore scrolling region
pop bx ; And flags and cursor attribute
mov curattr,bl
mov ansflgs,bh
ret
atnorm: mov ttstate,offset atnrm ; Reset state to "normal".
ret
; Normal character processor
atnrm: mov bx,chr_set ; Get character set
cmp byte ptr [bx],sgrset ; "Special" set?
jne atnrm1 ; No - check UK.
cmp flags.vtflg,ttheath ; Heath-19?
je atnrm0a ; e = yes
cmp al,137Q ; Yes - is it in the "special" range?
jb atnrm2 ; No - just output the char in al.
mov bl,al ; Yes - compute index in bx.
mov bh,0
sub bx,137Q
mov al,sgrtab[bx] ; Fetch translation.
jmp short atnrm2 ; Output it.
atnrm0a:cmp al,94 ; H-19, in range for special graphics?
jb atnrm2 ; b = no
cmp al,126 ; too large?
ja atnrm2 ; a = too large
sub bx,94 ; H-19, offset from caret
mov bl,al
mov bh,0
sub bx,94
mov al,hgrtab[bx] ; fetch translation
jmp short atnrm2
atnrm1: cmp al,'#' ; This thing?
jne atnrm2 ; No - just output it
cmp byte ptr [bx],ukset ; Yes - UK set?
jne atnrm2 ; No - just output it.
mov al,156 ; Yeah, show them our pound sign.
atnrm2:
mov dx,cursor ; get cursor virtual position
push ax ; save character
call atscur ; set cursor physical position
pop ax
cmp insmod,0 ; insert mode off? [jrd]
je atnrm3 ; e = yes [jrd]
push ax ; save char
call inschr ; open a char space in this line [jrd]
push bx
mov bx,cursor ; get current row
mov bl,bh
mov bh,0
cmp linetype [bx],0 ; single width line?
je atnrm2a ; e = yes
call inschr ; open second space for double width
atnrm2a:pop bx
pop ax ; restore char
atnrm3: ; set cursor before writing char
mov bl,dh ; check for double characteristic
xor bh,bh ; bx = row, in bl
test anspflg,vtautop ; printing desired? [jrd]
jz atnrm4d ; e = no
call pntchr ; print char in al
cmp linetype [bx],0 ; normal characteristic?
je atnrm4d ; e = yes
push ax ; save current char
mov al,' ' ; add a space for double width
call pntchr
pop ax ; recover char to be processed
atnrm4d:
cmp linetype [bx],0 ; normal characteristic?
je atnrm4a ; e = yes
push ax ; save char
shl dl,1 ; double the column number
mov ah,2 ; set cursor (bh = 0 from above)
int screen
pop ax ; recover the char
mov ah,9 ; Output char in al to screen [jrd]
mov bh,0 ; Page zero
mov bl,curattr ; Current attribute
mov cx,1 ; Only one character
int screen
inc dl ; next column
mov ah,2 ; set cursor
int screen
mov al,' ' ; use a space for doubling
mov ah,9 ; Output to screen [jrd]
mov bh,0 ; Page zero
mov bl,curattr ; Current attribute
mov cx,1 ; Only one character
int screen
shr dl,1 ; keep "cursor" in single units
jmp atnrm4b ; check autowrap in double width mode
atnrm4a:mov ah,9 ; Output to screen [jrd]
mov bh,0 ; Page zero
mov bl,curattr ; Current attribute
mov cx,1 ; Only one character
int screen
; set physical cursor after this char
atnrm4b:test ansflgs,decawm ; Autowrap?
jz atnrm5 ; No, continue
mov cx,low_rgt ; copy logical cursor margins to cx
push bx
mov bl,dh ; get row
xor bh,bh
cmp linetype[bx],0 ; single width line?
pop bx ; pop preserves flags
je atnrm4c ; e = yes, single
shr cl,1 ; halve right column # for wide chars
atnrm4c:cmp dl,cl ; wrote in right-most column?
jb atnrm5 ; b = no
inc dl ; say want to use next column
cmp flags.vtflg,ttheath ; emulating a H-19? [uci]
je atscur ; e = yes, show wrap now. [uci]
mov cursor,dx ; virtual cursor position
ret ; exit without moving cursor from eol
atnrm5: mov dx,cursor ; Restore cursor position
inc dl ; Bump cursor
atscur: cmp dl,250 ; To left of column zero?(wide screen)
jb atscu1 ; b = no, continue
mov dl,0 ; Yes - set at column zero.
atscu1: mov cx,low_rgt ; copy logical margins; cl=right col
push bx
mov bl,dh ; get row
xor bh,bh
cmp linetype [bx],0 ; single width lines?
pop bx
je atscu1a ; e = yes, single width
shr cl,1 ; halve column # for double wides
atscu1a:cmp dl,cl ; To right of right margin?
jbe atscu3 ; be = no, continue
mov dl,cl ; Yes - assume no autowrap.
test ansflgs,decawm ; Autowrap?
jz atscu3 ; No, continue
mov dl,0 ; Yes - set to column zero
cmp dh,byte ptr low_rgt+1 ; at bottom of screen?
je atscu1b ; e = yes
cmp dh,mar_bot ; At bottom of scrolling region?
jl atscu2 ; l = No - bump cursor and continue
atscu1b:call atscru ; Scroll up.
dec dh ; offset inc dh below
atscu2: inc dh ; Just bump it.
atscu3: cmp dh,0 ; Constrain row to valid range.
jge atscu4 ; ge = non-negative row, ok
mov dh,0
atscu4: cmp dh,byte ptr low_rgt+1 ; 25th line?
jle atscu5 ; le = no
mov dh,byte ptr low_rgt+1 ; set to 24th line
cmp flags.vtflg,ttheath ; emulating a Heath-19?
jne atscu4a ; ne = no [hlk]
cmp h19l25,0 ; Heath 25th line enabled?
je atscu5 ; e = no
jmp short atscu4b ; do 25th line
atscu4a:test ansflgs,decom ; Origin mode active?
;;;## jz atscu5 ; z = no, no 25th line allowed
atscu4b:inc dh ; yes, go to line 25 [hlk]
test yflags,modoff ; is mode line off?
jnz atscu8 ; nz = yes
push dx ; save cursor position
call trnmod ; no, turn it off now.
pop dx
atscu8: mov flags.modflg,0 ; and disable mode line. [jrd]
mov al,yflags ; place to communicate [jrd]
call telmsy ; tell msy the news. [jrd]
atscu5: push cx ; save cx around screen call
mov cursor,dx ; Set cursor and return.
mov ah,2 ; setup for position cursor call.
mov bl,dh ; get row
mov bh,0
cmp linetype [bx],0 ; single width line?
je atscu5a ; e = yes
shl dl,1 ; double the column number
int screen ; set the physical cursor
shr dl,1 ; restore dl (logical column)
jmp short atscu5b
atscu5a:int screen
atscu5b:pop cx
cmp kbiflg,0 ; Is keyboard input flag set?
je atscu6 ; No - just return
test vtflags,vsmarginbell ; Yes - do we care?
jz atscu6 ; Return if no margin bell.
mov dx,cursor ; Get new and old cursors
mov bx,kbicsr
cmp bh,dh ; Same row?
jne atscu6 ; No - just return
cmp bl,belcol ; Old cursor at or left of bell column?
ja atscu6 ; a = no, just return
cmp dl,belcol ; Yes - new cursor past bell column?
jbe atscu6 ; be = no, just return
call vtbell ; Yes - ring the bell
atscu6: ret
; This routine is called to check the cursor position after any kind of cursor
; positioning command. Note that cursor positioning does NOT cause scrolling
; on a VT100 (hence the need for a routine separate from this for "indexing".
;
; Call: dx/ "new" cursor position (modified cursor)
;
; Return: dx/ "new" cursor position adjusted for screen limits (if
; decom is reset), or scrolling region (if decom is set).
;
; Preserves ax, bx, and cx.
;
atccpc: push bx ; save bx and cx
push cx
atccp7: mov cx,low_rgt ; margins, cl = right margin
mov bl,dh ; get row
xor bh,bh
cmp linetype [bx],0 ; single width line?
je atccp0 ; e = yes, single width
shr cl,1 ; halve right margin for double wides
atccp0: cmp dl,250 ; To left of left margin?(wide screen)
jb atccp1 ; b = no, go check right
mov dl,0 ; No, set to left margin
atccp1: cmp dl,cl ; To right of right margin
jbe atccp2 ; be = yes, go check top
mov dl,cl ; No, set to right margin
atccp2: test ansflgs,decom ; Origin mode set?
jnz atccp5 ; Yes, can't go out of scrolling region
cmp dh,0 ; Above top of screen?
jge atccp3 ; ge = no, check bottom
mov dh,0 ; Yes, stop here
atccp3: cmp dh,byte ptr low_rgt+1 ; Below bottom of screen?
jle atccp4 ; le = no, return
mov dh,byte ptr low_rgt+1 ; Yes, stop at bottom margin
cmp flags.vtflg,ttheath ; Heath-19 mode?
jne atccp4 ; ne = no
cmp h19l25,0 ; 25th line enabled?
je atccp4 ; e = no
inc dh ; allow 25th line
atccp4: pop cx
pop bx
ret
atccp5: cmp dh,mar_top ; Above top of scrolling region?
jge atccp6 ; ge = no, check bottom
mov dh,mar_top ; Yes, stop there.
atccp6: cmp dh,mar_bot ; Below bottom perhaps?
jle atccp4 ; le = no, return
mov dh,mar_bot ; Yes, stop at the bottom margin
pop cx
pop bx
ret
; This routine is called to adjust the cursor for the "indexing" like commands
; (e.g., index, reverse index, newline, etc.). It contrains the cursor, and
; indicates if scrolling is necessary, and if so, in which direction.
;
; Call: cursor/ "old" cursor position
; dx/ "new" cursor position
;
; Return: ax/ pointer to scrolling routine to call (or to a ret)
; bx/ "old" cursor position
; dx/ "new" cursor position adjusted for screen limits or
; scrolling region, depending on whether the original
; cursor position was inside or outside the scrolling
; region.
;
; On the VT100, a scroll does not occur unless the original cursor position
; was on the top or bottom margin. This routine assumes that when decom is
; set the cursor position is set to the new origin, and that no other routine
; allows the cursor to be positioned outside the scrolling region as long
; as decom is set (which is the way a real VT100 works). Note that for the
; normal case (no limited scrolling region defined) the margins are the same
; as the screen limits and scrolling occurs (as on a "normal" terminal) when
; an attempt is made to index off the screen. Preserves cx.
; Revised 16 June 1987 [jrd]
atccic: push cx
mov cx,low_rgt ; get margins, cl = right margin
mov bl,dh ; get row
xor bh,bh
cmp bl,ch ; Below screen? [jrd]
jg atcci0 ; g = yes, use single width line
cmp linetype[bx],0 ; single width chars?
je atcci0 ; e = yes, single width
shr cl,1 ; halve margin for double wides
atcci0: mov ax,offset atign ; Assume no scrolling necessary
mov bx,cursor ; Get old cursor.
cmp dl,250 ; To left of left margin?(wide screen)
jb atcci1 ; b = no, go check right
mov dl,0 ; No, set to left margin
atcci1: cmp dl,cl ; To right of right margin
jbe atcci2 ; be = yes, go check top
mov dl,cl ; No, set to right margin
atcci2: cmp bh,mar_top ; was old pos at scrolling top margin?
jne atcci5 ; ne = no, check other end
cmp dh,mar_top ; want to go above top margin?
jge atcci7 ; ge = no
mov ax,offset atscrd ; Yes, indicate scroll down required.
mov dh,mar_top ; Set to top margin
jmp atcci7
atcci5: cmp bh,mar_bot ; Was old position at bottom margin?
jne atcci7 ; ne = no, so don't trap cursor
cmp dh,mar_bot ; want to go below?
jb atcci7 ; b = no, nothing to worry about
mov ax,offset atscru ; Yes, indicate scroll up required.
atcci6: mov dh,mar_bot ; Set to bottom margin
pop cx
ret
atcci7: pop cx ; old pos was outside scrolling region
jmp atccpc ; do full screen check and return
; This routine picks an attribute apart into its component "parts" - the
; base attribute for the screen and the "extras" - i.e., blink, intensity
; and underline.
;
; Call: ah/ a cursor attribute
;
; Return: ah/ base attribute for screen (07H normal, 70H reverse).
; al/ "extra" attributes
;
; Note that there is a complementary routine, addatt, for putting attributes
; back together...
;
brkatt: mov al,0 ; Clear returned "extra" attributes
cmp crt_mode,2 ; monochrome display adapter mode?
jnz brkat1 ; Yes, can't be underline
test ah,att_underline ; Underline?
jz brkat2 ; No, some kind of reverse video
or al,att_underline ; Yes, say underline
test ah,70h ;;att_reverse ; Reverse video + underline?
jz brkat1 ; No, fix up low nibble
and ah,not att_underline ; Yes, clear the underline bit in ah
jmp short brkat2 ; And forge on.
brkat1: or ah,att_normal ; Normal - turn on all normal bits
brkat2: test ah,att_intensity ; Intensity attribute on?
jz brkat3 ; No - check blink
or al,att_intensity ; Yes - turn on the bit
brkat3: test ah,att_blink ; Blink on?
jz brkat4 ; No - forge on
or al,att_blink ; Yes - turn on the bit
brkat4: and ah,not(att_intensity+att_blink) ;strip blink/bold, leave color
ret
; This routine builds a cursor attribute given the base attribute for the
; screen background and the "extra" attributes we want (blink, etc.).
;
; Call: ah/ base attribute for background (07H or 70H)
; al/ "extra" attributes (89H for all three)
;
; Return: ah/ base combined with "extras".
;
addatt: test al,att_underline ; Want underline?
jz addat1 ; No - no need for hack
and ah,not att_low_mask ; Yes - clear these bits
addat1: or ah,al ; Or in the attributes.
; When a monochrome monitor is used on a Sanyo with a video board, some [rwb]
; "colors" are completely invisible. Following code guarantees all text
; is visible.
test usevb,1 ; video board in use?
jz addat2 ; z = no
cmp crt_mode,2 ; monochrome?
jne addat2 ; ne = no
push bx
mov bx,offset trtbl ; point at translate table
xchg al,ah ; get original attribute in al
and al,7fH ; translate table only half length
xlat ; translate attribute
xchg al,ah ; return in ah
pop bx
addat2:
ret
; This routine is called when we want to reverse everything on the screen
; from normal to reverse video, or vice versa. It is called only when
; the decscnm attribute is changed.
;
; Call: no arguments.
;
; This routine may destroy ax-dx
; [begin jhw]
; Modified to use bios calls for Sanyo without video board
;
revscn: test usevb,1 ; video board in use?
jz revscnv ; z = no
mov dh,byte ptr low_rgt+1 ; Compute last screen offset in ax
inc dh ; One more row to catch mode line
mov dl,crt_cols ; physical width
dec dl ; and we count from 0
call scrloc
mov cx,ax ; Save it in cx for a minute
mov dx,0 ; Compute first screen offset in ax
call scrloc
sub cx,ax ; Compute number of locs to change..
add cx,2
sar cx,1 ; In 16-bit words please...
push di ; Save some more acs
push es
push cx ; save word count for Topview [jrd]
push ax ; save screen displacement
call scrseg ; Get address of screen in ax, es:di
pop ax ; recover displacement
add di,ax ; displacement addr of start of change
call scroff ; Turn screen off if color card.
revsc1: mov ax,es:[di] ; Fetch a word
mov bl,al ; Save the character
call brkatt ; Break up the attributes
rol ah,1 ; Reverse the video
rol ah,1 ; Reverse the video
rol ah,1 ; Reverse the video
rol ah,1 ; Reverse the video
call addatt ; Put attributes back together
mov al,bl ; Restore character
mov es:[di],ax ; Stuff into screen memory.
add di,2 ; Point di to next word of screen mem.
loop revsc1 ; Loop for entire screen.
pop cx ; recover word count for Topview [jrd]
call scrsync ; synch with Topview
call scron ; Turn screen back on if color card.
pop es ; Restore segment register
pop di ; And destination index
ret
revscnv:mov ax,0300h ; save cursor position on stack
int screen
push dx
mov dx,0
revs1: mov ax,0200h
int screen
mov ax,0800h ; read character at cursor
int screen
mov bh,al ; char/attrib in al/ah
call brkatt ; redo the attribute
rol ah,1
rol ah,1
rol ah,1
rol ah,1
call addatt ; reassemble attributes
mov bl,ah ; set up char/attrib in al/bl
mov al,bh ;
mov cx,1
mov ah,09h ; write char/attrib to screen
int screen
cmp dl,79 ; end of line?
jae revs7 ; yes, go to next line
inc dl ; else, go to next char
jmp revs1
revs7: mov dl,0
cmp dh,24 ; bottom of screen? (done?)
jae revs8 ; yes, finish up
inc dh ; no, go to next line
jmp revs1
revs8: pop dx ; restore cursor to where it was
mov ax,0200h
int screen ; end jhw [end jhw]
ret
; Reset-everything routine.
atreset:mov al,0 ; Make cursor disappear for a while.
;; call csrtype
mov cursor,0 ; Cursor is at 0,0
mov ansflgs,0 ; reset these flags[jrd]
cmp flags.vtflg,ttvt100 ; VT100? [jrd]
jne atres7 ; ne = no. [jrd]
mov ansflgs,decanm ; turn on ANSI mode flag. [jrd]
atres7: mov mar_top,0 ; Reset scrolling region
mov al,byte ptr low_rgt+1
mov mar_bot,al
mov ah,vtemu.vtflgst
mov vtemu.vtflgop,ah
mov vtflags,ah
mov insmod,0 ; reset insert mode. [jrd]
mov h19l25,0 ; clear heath 25th line enable
mov h19ctyp,1 ; Heath-19 cursor to underline [jrd]
mov anspflg,0 ; clear printer flag [jrd]
mov cx,4 ; Initialize the "LEDs". [jrd]
mov al,led_off ; Turn them all off.
mov di,offset ansleds+6 ; Point to the "LEDs".
push es ; save es
push ds
pop es ; use datas segment for es:di below
cld ; set forward direction
rep stosb ; Do it. [jrd]
pop es
call disleds ; update mode line. [jrd]
mov vttabs,offset deftabs ; [jrd]
call cpytabs ; Initialize tab stops.
call chrdef ; Set default character set.
call vtbell ; Ding bell like VT100
test vtflags,vsnewline ; Want ANSI newline mode?
jz atres1 ; No.
or ansflgs,anslnm ; Yes - set it in the mode flags.
atres1: test vtflags,vswrap ; How about autowrap?
jz atres2 ; No.
or ansflgs,decawm ; Yes - set it in the mode flags.
atres2: mov ah,att_normal ; get present normal coloring
call brkatt ; separate color and blink/bold
rol ah,1 ; reverse fore/back color fields
rol ah,1
rol ah,1
rol ah,1
call addatt ; put back blink/bold
mov att_reverse,ah ; this is the reverse video code
mov al,att_normal ; Assume normal video.
test vtflags,vsscreen ; Want reverse video?
jz atres3 ; No.
or ansflgs,decscnm ; Yes - turn on the mode flag...
xchg al,ah ; And reverse the video.
atres3: mov cx,slen ; typically 24 but do max lines [jrd]
mov di,0
atres8: mov linetype[di],0 ; clear the linetype array to single
inc di ; width/height characters.
loop atres8
mov curattr,al ; Give cursor and screen nice
mov scbattr,al ; attributes..
mov oldbatr,al ; place to remember long term
mov mlbattr,ah ; Give the other to the mode line.
and mlbattr,not att_intensity ; turn off intensity bit
mov video_state,0 ; say normal video. [jrd]
mov ax,0 ; Clear entire screen.
mov bx,low_rgt
mov bl,crt_cols
dec bl ; do physical screen
call atsclr
mov dx,cursor ; Set cursor to 0,0.
call atscu5
call atsc ; Give saved cursor reasonable values.
call atsctyp ; Set right cursor type.
mov al,yflags
call telmsy ; update msy about ansflgs state
test yflags,modoff ; is mode line off?
jnz atres9 ; nz = yes
push dx ; save cursor position
call trnmod ; toggle off then on again so we
call trnmod ; use it with current coloring
pop dx
atres9: ret
; Routine to set cursor type (block, underline).
atsctyp:cmp flags.vtflg,ttheath ; Heath-19?
jne atsct0 ; ne = no
mov al,h19ctyp ; get cursor kind and on/off bit
test al,4 ; is cursor to be off?
jz atsct1 ; z = no, al has kind
mov al,0 ; turn off cursor
jmp short atsct1 ; do it
atsct0: mov al,1 ; Assume underline.
test vtflags,vscursor ; Want block?
jnz atsct1 ; nz = no, underline
mov al,2 ; Yes.
atsct1: call csrtype ; Do it.
ret
; Routine to set default character set.
chrdef: mov al,ascset ; Assume US ASCII.
test vtflags,vsshift3 ; Want UK for default?
jz chrde1 ; No.
mov al,ukset ; Yes - use the UK set.
chrde1: mov chr_sg0,al ; Reset character sets.
mov chr_sg1,al
mov ax,offset chr_sg0 ; Select character set zero.
mov chr_set,ax
ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;; end of part one ;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;; start of part two ;;;;;;;;;;;;;;;;;;;;;;;;;;
; Routine to set special graphics character set (used in VT52 mode).
chrsgs: mov al,sgrset ; Select "graphics" set.
jmp chrde1 ; Do it and return.
; Control-character handling routines
atbel: call vtbell ; Just ring bell and return.
ret
atbs: cmp dl,0 ; Backspace. too far?
je atbs1 ; e = at column 0 already.
dec dl ; Backup cursor
atbs1: call atccpc ; Check range
jmp atscu5 ; Set cursor and return
atht: cmp flags.vtflg,ttheath ; Heath-19 mode? [jrd]
je atht2 ; e = yes. handle specially. [jrd]
cmp dl,byte ptr low_rgt ; At or beyond last column?
jae atbs1 ; Yes, check range, set cursor and ret
mov al,0 ; For ORing.
mov bh,0 ; Make an index
mov bl,dl ; For column.
atht1: inc bx ; Tab always moves at least one space.
or al,tabs[bx] ; Look for non-zero.
jz atht1 ; ...
mov dl,bl ; Get the new row index
jmp atbs1 ; Check range, set cursor, and return
atht2: mov dx,cursor ; Heath-19. get cursor position
add dl,8 ; tabs are every 8 columns
and dl,not 7 ; do modulo 8
cmp dl,byte ptr low_rgt ; check against right edge
jae atht3 ; ae = out of range
jmp atscu5 ; set cursor and return
atht3: test ansflgs,decawm ; doing line wrapping?
jnz atht4 ; nz = yes. wrap to next line
mov dl,byte ptr low_rgt ; else go to right margin
jmp atscu5 ; set cursor and return
atht4: inc dh ; say want next line down
xor dl,dl ; and left margin
call atccic ; index check
call ax ; do any needed scrolling
atht4a: jmp atscu5 ; reset cursor
atlf: cmp flags.vtflg,ttheath ; Heath-19 mode? [jrd]
je atlf2 ; e = yes [jrd]
test ansflgs,anslnm ; New-line mode?
jz atlf2 ; No - just move to next line down
mov dl,0 ; Yes - move to left margin also.
atlf2: inc dh ; Index line down
call atccic ; Check indexing
call ax ; Call scrolling routine
jmp atscu5 ; Set cursor
atcr: mov dl,0 ; Go to left margin
jmp atscu5 ; Set cursor and return.
atff: cmp ttstate,offset atescf ; parsing escape sequence?
jne atlf ; ne = no, do as line feed
test denyflg,200h ; is auto Tek mode disabled?
jnz atlf ; nz = yes, treat as line feed.
call atsc ; save cursor and associated data
JMP TEKESC ; Jump to Tektronix Emulator, al=FF
atso: mov ax,offset chr_sg1 ; Select set G1 and return
mov chr_set,ax
ret
atsi: mov ax,offset chr_sg0 ; Select set G0 and return
mov chr_set,ax
ret
atcan: cmp ttstate,offset atnrm ; doing normal chars (vs esc seq)?
jne atcan1 ; ne = no, assume esc seq
jmp atign ; ignore ^X, ^Z in normal mode
atcan1: mov ttstate,offset atnrm ; Reset state to "normal".
mov al,sgrtab+2 ; replace CAN (^X) by checkerboard
jmp atnrm ; Process char as a normal one
atesc: mov nansarg,0 ; Clear ANSI arguments
mov al,0
mov cx,lansarg
mov di,offset ansargs
push es
push ds
pop es ; use datas segment for es:di below
cld ; set direction forward
rep stosb
pop es
and ansflgs,not decmode ; Clear "DEC modes" flag.
mov h19mod,0 ; clear Heath-19 mode flag
mov ttstate,offset atescf ; Next state is escape follower
ret
atescf: cmp flags.vtflg,ttvt100 ; VT100? [jrd]
jne atv52f ; ne = not VT100, try others. [jrd]
atescf0:mov cx,lansesc ; Escape follower - get table length
mov di,offset ansesc ; Point di at table
push es
push ds
pop es ; use datas segment for es:di below
cld ; set direction forward
repne scasb ; Find it.
pop es
je atescf1 ; Found - now go do something with it
jmp atnorm ; Not there - just ignore it.
atescf1:mov di,lansesc - 1 ; Compute word index into jump table.
sub di,cx
shl di,1
jmp ansejt[di] ; Dispatch to the routine.
atv52f: cmp flags.vtflg,ttheath ; Heath-19? [jrd]
je ath19f ; e = yes. Use Heath esc seqs. [jrd]
mov ttstate,offset atnrm ; Assume state "normal" on return.
mov cx,lv52esc ; Get table length
mov di,offset v52esc ; Point di at table.
push es
push ds
pop es ; use datas segment for es:di below
cld ; set direction forward
repne scasb ; Find it.
pop es
je atv52f1 ; Found - do something with it.
ret ; Not there - just ignore it.
atv52f1:mov di,lv52esc - 1 ; Compute word index into jump table.
sub di,cx
shl di,1
jmp v52ejt[di] ; Dispatch to the routine.
ath19f: mov ttstate,offset atnrm ; Assume state "normal" on return.
test ansflgs,decanm ; ansi mode?
jnz atescf0 ; nz = yes, use ansi table
mov cx,lh19esc ; Get table length
mov di,offset h19esc ; Point di at table.
push es
push ds
pop es ; use datas segment for es:di below
cld ; set direction forward
repne scasb ; Find it.
pop es
je ath19f1 ; Found - do something with it.
ret ; Not there - just ignore it.
ath19f1:mov di,lh19esc - 1 ; Compute word index into jump table.
sub di,cx
shl di,1
jmp h19ejt[di] ; Dispatch to the routine.
; Escape follower routines.
atcsi: mov ttstate,offset atpaa ; Next state is parse ansi args.
ret
atpaa: test al,80h ; high bit set?
jz atpaa6 ; z = no
and al,7fh ; strip high bit
cmp al,' ' ; control code remainder?
jae atpaa6 ; ae = no, use 7 bit result
mov ttstate,offset atnrm ; reset state to normal text
jmp atctrl ; execute 7 bit control code
atpaa6: cmp al,'0' ; A digit?
jb atpaa1 ; No - just ignore it.
cmp al,'9' ; Maybe - A separator or final char?
ja atpaa2 ; Perhaps - go check it out
mov cl,al ; A digit - convert ASCII to binary
sub cl,'0'
mov bl,nansarg ; put index in bx [dlk]
xor bh,bh
mov al,ansargs[bx] ; Pick up what we've done so far [dlk]
shl al,1 ; multiply by 10. 2 * al
mov ah,al ; save
shl al,1 ; 4 * al
shl al,1 ; 8 * al
add al,ah ; 10 * al
mov ah,0 ; clear high field
add ax,cx ; add in this digit [dlk]
cmp ax,0feh ; max value is 0ffh [dlk]
jbe atpaa0 ; be = ok [dlk]
mov al,0ffh ; set to max value [dlk]
atpaa0: mov ansargs[bx],al ; Put result back for next time [dlk]
atpaa1: ret ; And return
atpaa2: cmp al,'?' ; The deadly question mark?
jne atpaa2a ; No - check further.
or ansflgs,decmode ; Yes - say DEC modes are coming.
ret ; And return.
atpaa2a:cmp al,'>' ; Heath private mode? [jrd]
jne atpaa3 ; ne = no
cmp flags.vtflg,ttheath ; emulating a Heath-19?
jne atpaa3 ; ne = no, ignore this sequence
mov h19mod,1 ; say Heath mode sequence follows.
ret
atpaa3: cmp al,';' ; Argument separator?
jne atpaa4 ; No - check for final char.
mov al,nansarg ; Get argument index
inc al ; Bump it.
cmp al,lansarg ; Too many?
jl atpa3a ; l = no, continue
mov ttstate,offset atnrm ; Reset state to "normal".
ret ; and pretend all is well [jrd]
; [jrd] jmp atcan ; Yes - abandon sequence on error.
atpa3a: mov nansarg,al ; Save it.
ret
atpaa4: mov cx,lanstab
mov di,offset anstab ; Look for it in the table
push es
push ds
pop es ; use datas segment for es:di below
cld ; set direction forward
repne scasb
pop es
je atpaa5 ; Found it - go dispatch
cmp al,40h ; in range for a legal terminator?
jb atpaa4a ; b = not in range, ignore
cmp al,7eh ; other end of the range
ja atpaa4a ; a = out of range, ignore
; in range, absorb and become normal
mov ttstate,offset atnrm ; Put state back to normal
atpaa4a:ret ; Just return if it is unknown.
atpaa5: mov ttstate,offset atnrm ; Put state back to normal
mov di,lanstab - 1 ; Compute word index into jump table.
sub di,cx
shl di,1
jmp ansjmp[di] ; Off into the wild blue...
atind: inc dh ; Index - move cursor down one.
atind1: call atccic ; Check cursor position.
call ax ; Scroll if necessary.
mov ttstate,offset atnrm ; Reset state.
jmp atscu5 ; Set cursor, etc. and return.
atnel: mov dl,0 ; Next line - sort of like CRLF...
inc dh ; ... all in one command
jmp atind1 ; Check cursor, etc., and return.
atri: dec dh ; Reverse index...
jmp atind1 ; Check cursor, etc., and return.
athts: call atccpc ; Make sure we have valid column number.
mov dh,0 ; Zap row
mov al,0FFH ; Indicates a tab stop
mov di,dx ; Dumb specialized registers.
mov tabs[di],al ; Store it.
jmp atnorm ; Reset state and return.
atsc: mov si,offset curattr ; Save cursor, attribute, char set etc.
mov di,offset savecu ; Place to save the stuff.
mov cx,lsavecu ; Length of save area
push es ; save es
push ds
pop es ; set es to datas segment
cld
rep movsb ; Save it.
pop es
mov cl,ansflgs ; Save a copy of the flags.
mov savflgs,cl ; ...
jmp atnorm ; Reset state and return.
atrc: mov si,offset savecu ; Restore cursor, attributes, etc..
mov di,offset curattr ; Where stuff goes
mov cx,lsavecu ; Length of save area
push es ; save es
push ds
pop es ; set es to datas segment
cld
rep movsb ; Put the stuff back.
pop es
mov al,savflgs ; Get saved flags
xor al,ansflgs ; Exclusive-or with current flags
test al,decscnm ; Did screen mode change?
jz atrc1 ; No, just reset saved flags and leave
mov ah,curattr ; Get cursor attribute that was saved
call brkatt ; Break into background & extra stuff
rol ah,1 ; Reverse the background
rol ah,1 ; Reverse the background
rol ah,1 ; Reverse the background
rol ah,1 ; Reverse the background
call addatt ; Put it all back together
mov curattr,ah ; Store
atrc1: mov al,ansflgs ; Reset flags in case called again
and al, not(decckm+deckpam+decom) ; remove old bits [dlk]
and savflgs,(decckm+deckpam+decom) ; remove all but new bits [dlk]
or al,savflgs ; restore saved bits [dlk]
mov ansflgs,al ; update these flags [dlk]
mov savflgs,al
mov dx,cursor ; Get cursor
mov kbiflg,0 ; Don't bother them with beeps here
call atscu5 ; Set cursor.
jmp atnorm ; Reset state and return.
atkpam: or ansflgs,deckpam ; Turn on the bit
mov al,yflags
call telmsy ; inform msy of new state
jmp atnorm ; Reset state and return.
atkpnm: and ansflgs,not deckpam ; Turn off the bit
mov al,yflags
call telmsy ; inform msy of new state
jmp atnorm ; Reset state and return.
atris: call atreset ; Reset everything
jmp atnorm ; And state too, return, etc.
atsg0: mov ttstate,offset atsg01 ; Setup to get last character
ret
atsg01: call atscs ; Get code for character set
mov chr_sg0,al ; Store it.
jmp atnorm ; Reset state etc. and return
atsg1: mov ttstate,offset atsg11 ; Setup to get last character
ret
atsg11: call atscs ; Get code for character set
mov chr_sg1,al ; Store it.
jmp atnorm ; Reset state etc. and return
atscs: cmp al,'A' ; UK ASCII set?
jne atscs1 ; No.
mov al,ukset ; Yes - give them that and return
ret
atscs1: cmp al,'B' ; US ASCII set?
jne atscs3 ; No.
atscs2: mov al,ascset ; Yes - give them that and return
ret
atscs3: cmp al,'0' ; Special graphics set?
jne atscs4 ; ne = no
mov al,sgrset ; Yes - say that's what it is
ret
atscs4: cmp al,'1' ; alt char ROM, std char set? [jrd]
jne atscs5 ; ne = no
mov al,ascset ; use US ASCII set
ret
atscs5: cmp al,'2' ; alt char ROM, special graphics?[jrd]
jne atscs2 ; ne = no, use US ASCII
mov al,sgrset ; set graphics
ret
; ESC # Pn series. [jrd]
atsdhl: mov ttstate,offset atsdbl ; set up to parse argument
ret
atsdbl: cmp al,'3' ; Double high lines. Top half? [jrd]
je atsdh2 ; e = yes
cmp al,'4' ; bottom half?
je atsdh2 ; e = yes
cmp al,'5' ; restore line to single width?
je atsdh1 ; e = yes
cmp al,'6' ; double width single height?
je atsdh2 ; e = yes
cmp al,'8' ; screen alignment?
je atsdh8 ; e = yes
jmp atnorm ; else ignore
atsdh1: call linesgl ; set line to single width
jmp atnorm
atsdh2: call linedbl ; expand the line to double width
jmp atnorm ; set state to normal and ret
atsdh8: call atalign ; do screen alignment
jmp atnorm
atpriv: mov ttstate,offset atnorm ; ignore next char.
ret ; and return to normal afterward.
atalign proc near ; Fill screen with 'E'
call atreset ; clear system
or ansflgs,decawm ; set wrap
mov cl,byte ptr low_rgt ; number of columns-1
inc cl
mov al,byte ptr low_rgt+1 ; number of rows-1
inc al
mul cl ; ax = number of chars on screen
mov cx,ax
atalig1:push cx
mov al,'E' ; write screen full of E's
call atnrm ; write the 'E'
pop cx
loop atalig1 ; cx times
ret
atalign endp
; This routine may be used to repeat a call to a selected action routine
; for all of the ANSI parameters given in a call. When the action routine
; is called, si will contain the index for the current ANSI parameter (i.e.,
; the current ANSI parameter may be gotten using ansargs[si] for an effective
; address). The action routine may modify any ACs it wants, but cx, si,
; and di are preserved over the call to the action routine, so these may
; not be used for building return values for the original caller. Note that
; if there are no ANSI parameters, the effect is the same as if one ANSI
; parameter with a value of zero was given.
;
; Call: di/ offset of action routine in code seqment
;
atreps: mov cl,nansarg ; Pick up number of parameters
inc cl ; Zero parms is same as 1 zero parm.
mov ch,0
mov si,0 ; Init parm index
atrep1: push cx ; Save important acs
push si
push di
call di ; Call indicated routine
pop di ; Restore acs
pop si
pop cx
inc si ; Advance to next parameter
loop atrep1 ; Loop for all
ret ; And return.
; Final char (ANSI) routines.
atcup: mov dh,ansargs ; Get the two arguments
mov dl,ansargs+1
cmp dh,0 ; Zero line number?
jne atcup1 ; No - continue
mov dh,1 ; Yes - default to one.
atcup1: cmp dl,0 ; Ditto for row
jne atcup2
mov dl,1
atcup2: dec dh ; Now normalize
dec dl
test ansflgs,decom ; Origin mode?
jz atcup4 ; No - skip this stuff
add dh,mar_top ; Yes - it was relative to top margin
jno atcup4 ; If no overflow, continue
mov dh,byte ptr low_rgt+1 ; Otherwise just set to screen bottom
atcup4: cmp dh,byte ptr low_rgt+1 ; going to 25th line? [hlk]
jbe atcup5 ; be = no [dlk]
cmp flags.vtflg,ttheath ; emulating a Heath-19? [jrd]
jne atcup6 ; ne = no [hlk]
cmp h19l25,0 ; Heath 25th line enabled?
je atcup5 ; e = no
mov dh,byte ptr low_rgt+1 ; [hlk]
inc dh ; go there
jmp atscu4 ; set cursor position & mode line
atcup6: test ansflgs,decom ; origin mode? [jrd]
;;;## jz atcup5 ; z = no, no 25th line stuff allowed
mov dh,byte ptr low_rgt+1 ; bottom normal line
inc dh ; the 25th line
jmp atscu4 ; set cursor position and return
atcup5: call atccpc ; Check position
jmp atscu5 ; Set cursor position and return.
atcuarg:mov al,ansargs ; Get a cursor move argument
cmp al,0 ; Zero?
jne atcua1 ; No - return
mov al,1 ; Yes - default to one.
atcua1: ret ; Return.
; Disallow movement to 25th line.
atcuu: call atcuarg ; Get cursor move argument in al
sub dh,al ; Compute new cursor position
jnc atcuu1 ; nc = ok [dlk]
xor dh,dh ; overflow, restrict range. [dlk]
atcuu1: call atccic ; check indexing, ignore action in ax
jmp atscu5 ; set the cursor at its new position
atcud: call atcuarg ; Get the argument
add dh,al ; Compute new cursor position
jnc atcud1 ; nc = ok [dlk]
mov dh,byte ptr low_rgt+1 ; default bottom [dlk]
atcud1: call atccic ; check indexing, ignore action in ax
jmp atscu5 ; set the cursor at its new position
; Allow horiz movement on 25th line.
atcuf: call atcuarg ; Get the argument
add dl,al ; Compute new cursor position
jnc atcup4 ; If no carry, continue [dlk]
mov dl,byte ptr low_rgt ; Else set to right margin
jmp atcup4 ; Check/set cursor, return.
atcub: call atcuarg ; Get the argument
sub dl,al ; Compute new cursor position
jnc atcup4 ; If no carry, continue [dlk]
mov dl,0 ; Else set to left margin
jmp atcup4 ; Check/set cursor, return.
ated: mov di,offset ated0 ; Routine to process parm.
call atreps ; Do all selected parms.
ret
ated0: cmp ansargs[si],0 ; Was arg zero?
jne ated2 ; No - continue
mov ax,dx ; Yes - erase from cursor to end of screen
push dx ; save dx
mov bl,dh ; get row number
xor bh,bh
cmp linetype [bx],0 ; single width line?
je ated0a ; e = yes
shl dl,1 ; physical column is twice logical
ated0a: or dl,dl ; starting at left margin?
je ated0b ; e = yes, this goes to single width
inc bl ; else start on next line
ated0b: cmp bl,byte ptr low_rgt+1 ; at the end of the screen?
ja ated0c ; a = yes, stop singling-up
mov byte ptr linetype [bx],0 ; set to single width
inc bx
jmp short ated0b ; loop, reset lines to end of screen
ated0c: mov bx,low_rgt ; erase from cursor to end of screen
mov bl,crt_cols
;;;##
test yflags,modoff ; is mode line disabled?
jz ated0d ; z = yes, don't extend erase
inc bh ; yes, extend erase to 25th line
ated0d:
;;;##
dec bl ; do physical screen width
call atsclr ; Clear it.
pop dx ; restore dx
ated1: ret
ated2: cmp ansargs[si],1 ; Was arg one?
jne ated3 ; No - continue
mov ax,0 ; Yes - erase from start of screen...
; ...to cursor, inclusive
xor bx,bx ; start at top row (0)
ated2b: cmp bl,dh ; check rows from the top down
jae ated2c ; ae = at or below current line
mov byte ptr linetype [bx],0; set line to single width
inc bx ; inc row
jmp short ated2b ; look at next line
ated2c: or dl,dl ; at left margin of current line?
jne ated2d ; ne = no, leave line width intact
mov byte ptr linetype [bx],0 ; convert to single width
ated2d: mov bl,dh ; get row number
xor bh,bh
cmp linetype [bx],0 ; single width line?
je ated2a ; e = yes
shl dl,1 ; physical column is twice logical
ated2a: mov bx,dx ; cursor position to bx
call atsclr ; Clear it.
ret
ated3: cmp ansargs[si],2 ; Was arg two?
jne ated1 ; No - ignore it.
mov ax,0 ; Yes - erase entire screen.
mov bx,low_rgt
mov bl,crt_cols
;;;##
test yflags,modoff ; is mode line disabled?
jz ated3b ; z = yes, don't extend erase
inc bh ; yes, extend erase to 25th line
ated3b:
;;;##
dec bl ; physical width
call atsclr ; Clear it.
push bx
push cx ; set all 24 lines to single width
mov cl,byte ptr low_rgt+1 ; number of last line
xor ch,ch
inc cx ; count from one
xor bx,bx
ated3a: mov linetype [bx],0
inc bx
loop ated3a
pop cx
pop bx
ret
atel: mov di,offset atel0 ; Get routine to call
call atreps ; Repeat for all parameters.
ret
atel0: cmp ansargs[si],0 ; Was arg zero?
jne atel2 ; No - continue
mov ax,dx ; Yes - erase from cursor...
mov bh,dh ; ...to end of line, inclusive
push bx
mov bl,bh ; get row
mov bh,0
cmp linetype [bx],0 ; single width line?
je atel0a ; e = yes
shl al,1 ; physical column is twice logical
atel0a: pop bx
mov bl,byte ptr low_rgt
call atsclr ; Clear it.
atel1: ret
atel2: cmp ansargs[si],1 ; Was arg one?
jne atel3 ; No - continue
mov ah,dh ; Yes - erase from start of line...
mov al,0
mov bx,dx ; ...to cursor, inclusive
push bx
mov bl,dh ; get row
mov bh,0
cmp linetype [bx],0 ; single width line?
pop bx ; pop does not affect flags
je atel2a ; e = yes
shl bl,1 ; physical column is twice logical
atel2a: call atsclr ; Clear it.
ret
atel3: cmp ansargs[si],2 ; Was arg two?
jne atel1 ; No - ignore it.
mov ah,dh ; Yes - erase entire line.
mov al,0
mov bh,dh
mov bl,byte ptr low_rgt
mov bl,crt_cols
dec bl ; physical line
call atsclr ; Clear it.
ret
atsgr: mov ah,curattr ; Get current cursor attribute
call brkatt ; Break it apart.
mov di,offset atsgr1 ; Routine to call.
call atreps ; Repeat for all parms.
call addatt ; Put the attributes back together
mov curattr,ah ; Store.
ret
atsgr1: mov bl,ansargs[si] ; Fetch an argument
cmp bl,0 ; Zero?
jne atsgr2 ; No.
mov al,0 ; Yes - clear the "extras"
mov ah,scbattr ; And reset background.
and ah,77h ; clear blink/bold here
mov video_state,0 ; say normal video now. [jrd]
ret
atsgr2: cmp bl,1 ; One?
jne atsgr3 ; No.
or al,att_intensity ; Yes - set bold
ret
atsgr3: cmp bl,4 ; Four? Underline. Mods by [jrd]
jne atsgr4 ; No.
or al,att_underline ; Yes, set underscore.
cmp crt_mode,2 ; monochrome display adapter mode?
je atsgr3a ; e = yes. Otherwise reverse video
; use reversed video rather than blue on black
and al,not att_underline ; clear underline and [jrd]
rol ah,1 ; reverse the colors [jrd]
rol ah,1 ; [jrd]
rol ah,1 ; [jrd]
rol ah,1
atsgr3a:ret
atsgr4: cmp bl,5 ; Five?
jne atsgr5 ; No.
or al,att_blink ; Yes - set blink
ret
atsgr5: cmp bl,7 ; Seven?
jne atsgr6 ; No - just ignore it.
cmp video_state,0 ; is video normal? [jrd]
jne atsgr6 ; ne = no, reversed already, ignore
rol ah,1 ; reverse the colors
rol ah,1
rol ah,1
rol ah,1
mov video_state,1 ; say reversed now.
ret
atsgr6: cmp bl,30 ; ANSI color series? [jrd]
jb atsgrx ; b = no.
cmp bl,37 ; foreground set (30-37)?
ja atsgr7 ; a = no, try background set.
sub bl,30 ; take away the bias
and ah,not 07H ; clear foreground bits
test bl,1 ; ANSI red?
jz atsgr6a ; z = no
or ah,4 ; IBM red foreground bit
atsgr6a:test bl,2 ; ANSI & IBM green?
jz atsgr6b ; z = no
or ah,2 ; IBM green foreground bit
atsgr6b:test bl,4 ; ANSI blue?
jz atsgr6c ; z = no
or ah,1 ; IBM blue foreground bit
atsgr6c:ret
atsgr7: cmp bl,40 ; background color set?
jb atsgrx ; b = no
cmp bl,47 ; background set is 40-47
ja atsgrx ; nb = no, not a color command.
sub bl,40 ; take away the bias
and ah,not 70H ; clear background bits
test bl,1 ; ANSI red?
jz atsgr7a ; z = no
or ah,40h ; IBM red background bit
atsgr7a:test bl,2 ; ANSI & IBM green?
jz atsgr7b ; z = no
or ah,20h ; IBM green background bit
atsgr7b:test bl,4 ; ANSI blue?
jz atsgrx ; z = no
or ah,10h ; IBM blue background bit
atsgrx: ret
attbc: call atccpc ; Make sure cursor is kosher
mov di,offset attbc0 ; Routine to call
call atreps ; Do for all parms
ret
attbc0: cmp ansargs[si],0 ; Was argument zero?
jne attbc2 ; No - check further
mov dh,0 ; Zap row for indexing
mov di,dx
mov tabs[di],0 ; clear tab stop
attbc1: ret
attbc2: cmp ansargs[si],3 ; Was arg 3 (clear all tab stops)?
jne attbc1 ; No - just ignore it.
mov cx,swidth ; Get ready to zap swidth columns
mov di,offset tabs ; Point to the tab stop table.
mov al,0 ; zero indicates no tab stop.
push es ; save es
push ds
pop es ; use datas segment for es:di below
cld ; set direction forward
rep stosb ; Blit full of zeros.
pop es
ret
atstbm: mov al,ansargs ; Get the two line number args
mov ah,ansargs+1
cmp al,0 ; Was first zero?
jne atstb1 ; No - continue
mov al,1 ; Yes - default is one
atstb1: cmp ah,0 ; Was second zero?
jne atstb2 ; No - continue
mov ah,byte ptr low_rgt+1 ; Yes - default is last line on screen
inc ah
atstb2: dec al ; Normalize to our coord. system
dec ah
cmp ah,al ; Is size of region at least two lines?
jbe atstb3 ; be = if not, indicate an error.
cmp al,0 ; Check against screen limits.
jl atstb3
cmp ah,byte ptr low_rgt+1
ja atstb3
mov mar_top,al ; Set the limits
mov mar_bot,ah
mov dx,0 ; Home cursor
call atccpc ; Check cursor (get it inside window)
jmp atscu5 ; Set cursor position and return.
atstb3: ret ; ignore bad requests
;;; jmp atcan ; Indicate error and return.
atda: cmp ansargs,0 ; Was argument zero?
je decid ; Yes - send the i.d. string.
ret ; No - only an echo...
at52id: mov ttstate,offset atnrm ; ensure state is correct
decid: mov cx,ldastr ; Length of the string
mov si,offset dastr ; Point to the string
cmp flags.vtflg,ttvt100 ; VT100? [jrd]
je decid1 ; e = yes [jrd]
mov cx,lv52str ; No - try VT52 i.d. [jrd]
mov si,offset v52str
cmp flags.vtflg,ttvt52 ; Heath-19 mode? [jrd]
je decid1 ; e = yes. [jrd]
mov cx,lh19str ; length of Heath-19 ident string
mov si,offset h19str ; say Heath-19. [jrd]
decid1: cld
lodsb ; Get a byte
push cx ; Save the important registers
push si
call prtbout ; Send it to port with no local echo
pop si
pop cx
loop decid1 ; Loop for all characters
ret
atll: mov di,offset atleds ; Get pointer to routine to call
call atreps ; Repeat for selective parameters.
ret
atleds: cmp ansargs[si],0 ; Zero argument?
jne atled3 ; No - check further.
mov cx,4 ; Reset the "LEDs". [jrd]
mov al,led_off ; to all off.
mov di,offset ansleds+6 ; Point to the "LEDs".
push es ; save es
push ds
pop es ; make es:di point to datas seg
cld ; move forward
rep stosb ; [jrd]
pop es
atled1: call disleds ; Update "LEDs" display and return.
atled2: ret
atled3: mov al,ansargs[si] ; Get the argument
cmp al,1 ; Must be .GE. 1
jb atled2 ; If not just ignore it. [dlk]
cmp al,4 ; Must be .LE. 4
ja atled2 ; Ignore if not so. [dlk]
dec al ; Zero base it.
cbw ; Convert to index in ax.
mov di,ax ; Dumb specialized registers.
add al,'1' ; add ascii offset for digit
mov ansleds[di+6],al ; Turn the "LED" on by storing digit
jmp atled1 ; Update display and return.
atreqt: cmp ansargs,0 ; Want report?
je atreq1 ; Yes - give report
cmp ansargs,1 ; Want report?
je atreq1 ; Yes - give the report.
ret ; Gee, must have been an echo...
atreq1: mov al,escape ; Send an escape to start off...
call prtbout
mov al,'[' ; Then one of these...
call prtbout
mov al,'3' ; We only report on request...
cmp ansargs,0 ; was argument a zero?
jne atreq1a ; ne = no
mov al,'2' ; yes
atreq1a:call prtbout
mov al,';' ; Separate
call prtbout
mov bl,parcode ; Get the parity code
mov bh,0
mov al,partab[bx] ; Get VT100 parity code
push ax ; save parity code
call prtnout ; Send number to the port..
mov al,';' ; Separate
call prtbout
mov al,'2' ; Assume 7 data bits
pop bx ; get parity code into bl
cmp bl,1 ; is parity none?
jne atreq2 ; ne = no, so 7 data bits
test flags.remflg,d8bit ; 8 bit display?
jz atreq2 ; z = no
mov al,'1' ; must be eight.
atreq2: call prtbout ; Send it to the port
mov al,';' ; Separate
call prtbout
mov bl,baudidx ; Baud rate index
mov bh,0
mov al,baudtab[bx] ; Get DEC baud rate code
push ax
call prtnout ; Send it to the port
mov al,';' ; Separate
call prtbout ; Send it to the port
pop ax
call prtnout ; Send it to the port
mov al,';' ; Separate
call prtbout
mov al,'1' ; Clock rate multiplier is always 1
call prtbout
mov al,';' ; Separate (gasp - for the last time)
call prtbout
mov al,'0' ; Flags are always zero (no STP)
call prtbout
mov al,'x' ; Finally, say what this all was.
call prtbout
ret
atdsr: mov di,offset atdsr1 ; Routine to call
call atreps ; Do for all parms.
ret
atdsr1: cmp ansargs[si],5 ; Want status?
je rpstat ; Yes - report status
cmp ansargs[si],6 ; Want cursor position?
je rpcup ; Yes - do it.
cmp ansargs[si],15 ; Printer status? [jrd]
je rpstap ; e = yes, do so.
ret ; No - must have been an echo
rpstat: mov al,escape ; Tell them we think we are OK
call prtbout
mov al,'['
call prtbout
mov al,'0'
call prtbout
mov al,'n'
call prtbout
ret
rpstap: test ansflgs,decmode ; Printer status report from [jrd]
jz rpstap3 ; ESC [ ? 15 n request
mov al,escape
call prtbout
mov al,'['
call prtbout
mov al,'?'
call prtbout
mov al,'1'
call prtbout
mov ah,ioctl ; get printer status, via DOS
mov al,7 ; status for output
push bx
mov bx,4 ; std handle for system printer
int dos
pop bx
jc rpstap1 ; c = call failed
cmp al,0ffh ; code for Ready
jne rpstap1 ; ne = not ready
mov al,'0' ; ready, send final digit
jmp rpstap2
rpstap1:mov al,'3' ; not ready, say printer disconnected
rpstap2:call prtbout
mov al,'n' ; final char of response
call prtbout
rpstap3:ret
rpcup: mov al,escape ; Cursor position - send an escape
call prtbout
mov al,'[' ; And one of these
call prtbout
mov al,byte ptr cursor+1 ; Get row
inc al ; They use coords that start at 1.
test ansflgs,decom ; Origin mode set?
jz rpcup1 ; No - continue
sub al,mar_top ; Yes - subtract off top margin
rpcup1: call prtnout ; Output the number.
mov al,';' ; Separate
call prtbout
mov al,byte ptr cursor ; Now get the column number.
inc al ; Their coords start at 1.
call prtnout ; Send it off to the port.
mov al,'R' ; Finally end it with this
call prtbout
ret
; ESC [ ? xxx h/l series
atrm: mov modeset,0 ; Say we are resetting modes
mov di,offset atrsm ; Reset/set modes.
call atreps ; Repeat for all parms.
test ansflgs,decanm ; Did this get reset?
jnz atrm1 ; No - return.
cmp flags.vtflg,ttheath ; were we a Heath-19?
je atrm0 ; e = yes, don't change terminal types
mov flags.vtflg,ttvt52 ; Yes. Say VT52 now. [jrd]
atrm0: call chrdef ; Yes - set default char sets.
call atsc ; Save cursor status.
call disleds ; update terminal type
atrm1: ret
atsm: mov modeset,1 ; Say we are setting modes
mov di,offset atrsm ; Reset/set modes.
call atreps ; Repeat for all parms.
ret
atrsm: mov al,ansargs[si] ; Pick up the argument.
test ansflgs,decmode ; Is this DEC private mode ([ ?)stuff?
jnz atrsm1 ; nz = yes - go check it out.
cmp h19mod,0 ; Heath-19 private mode ([ >)?
je atrsma ; e = no
jmp htrsm1 ; yes, do Heath specific things.
atrsma: cmp al,20 ; No - ANSI new-line mode?
jne atrsm0 ; but try insert mode. [jrd]
and vtemu.vtflgop,not vsnewline ; assume resetting
cmp modeset,0 ; resetting?
je atrsmb ; e = yes
or vtemu.vtflgop,vsnewline ; setting
atrsmb: mov al,anslnm ; Yes - get the bit
call atrsflg ; Set or reset it
ret
atrsm0: cmp al,4 ; toggle insert mode? [jrd]
jne atrsmx ; ne = no [jrd]
mov al,modeset ; set/reset insert mode [jrd]
mov insmod,al ; store it. [jrd]
atrsmx: ret
atrsm1: cmp al,1 ; Cursor keys mode?
jne atrsm2 ; No - check some more
mov al,decckm ; Yes - get the bit.
jmp atrsflg ; Set or reset it and return.
atrsm2: cmp al,7 ; Auto-wrap?
jne atrsm3 ; No - check some more
and vtemu.vtflgop,not vswrap ; assume resetting line wrap
cmp modeset,0 ; resetting?
je atrsm2a ; e = yes
or vtemu.vtflgop,vswrap ; set the bit
atrsm2a:mov al,decawm ; Yes - get the bit
jmp atrsflg ; Set or reset it and return.
atrsm3: cmp al,6 ; Origin mode?
jne atrsm4 ; No - check for video change
jmp atrsom ; Yes - change decom and return.
atrsm4: cmp al,5 ; Change the video?
jne atrsm5 ; No - check for VT52 mode set/reset.
jmp atrsscnm ; Yes - change it if we have to and ret.
atrsm5: cmp al,2 ; Change VT52 compatibility mode?
jne atrsm6 ; No - ignore unknown DEC private modes
cmp flags.vtflg,ttheath ; Heath-19 mode? [jrd]
je atrsm5a ; e = yes, handle specially. [jrd]
mov al,ascset ; return to US ascii graphics sets
mov chr_sg0,al ; Store it.
mov chr_sg1,al ; Store it.
mov al,decanm ; Yes - get the flag.
jmp atrsflg ; Set or reset it and return.
atrsm5a:mov modeset,0 ; Heath-19 ESC [ ? 2 h, reset ansi
mov al,decanm ; the flag needing adjustment
jmp atrsflg ; reset the flag and return
atrsm6: cmp al,3 ; 132/80 column mode change? [jrd]
jne atrsm7 ; ne = no
mov al,modeset ; pass set/reset request to chgdsp[dlk]
call chgdsp ; call Change Display proc in msy [dlk]
call scrmod ; get current screen mode
cmp modeset,1 ; want 132 cols?
jne atrsm6n ; ne = no, so use 80 columns
push ax
mov al,crt_cols ; get current physical screen width
dec al ; we count from column 0 here
mov byte ptr low_rgt,al ; screen capability
pop ax
mov linelen,131 ; say using wide screen, if possible
jmp short atrsm6e
atrsm6n:mov linelen,79 ; say using 80 columns
cmp byte ptr low_rgt,79 ; want 80 cols, is it wider?
jbe atrsm6e ; be = no
mov byte ptr low_rgt,79 ; narrow down to 80 columns
atrsm6e:
CALL ATRES2 ; do partial reset of emulator
xor ax,ax ; clear screen from 0,0
mov bh,byte ptr low_rgt+1 ; to end of text lines (typ. line 24)
mov bl,crt_cols ; physical width
dec bl ; we count from 0
call atsclr ; do the clear
push bx ; save regs. [jrd]
push cx
mov cl,byte ptr low_rgt+1 ; text lines (leave status line intact)
mov mar_top,0
mov mar_bot,cl ; reset scrolling region
xor ch,ch
xor bx,bx
atrsm6a:mov linetype [bx],0 ; reset linetype to single chars
inc bx
loop atrsm6a
pop cx
pop bx
xor dx,dx ; new cursor position is 0,0
mov cursor,dx
jmp atscu5 ; place it there and return
atrsm7: cmp al,18 ; 18? 18 & 19 = printer support [jrd]
jne atrsm8 ; ne = no
cmp modeset,0 ; resetting?
jne atrsm7a ; ne = no, setting
and anspflg,not vtffp ; no form feed after printing
ret
atrsm7a:or anspflg,vtffp ; use form feed after printing
ret
atrsm8: cmp al,19 ; 19? [jrd]
jne atrsm9 ; ne = no
cmp modeset,0 ; resetting?
jne atrsm8a ; ne = no, setting
and anspflg,not vtextp ; reset print region to scrolling reg.
ret
atrsm8a:or anspflg,vtextp ; set print region to whole screen
ret
atrsm9: cmp al,38 ; 38? Enter Tek sub-mode. VT340 seq
jne atrsm10 ; ne = no
cmp modeset,1 ; setting mode (ESC [ ? 38 h)?
jne atrsm10 ; ne = no, ignore sequence
test denyflg,200h ; is auto Tek mode disabled?
jnz atrsm10 ; nz = yes, just ignore command
call atsc ; save cursor and associated data
mov al,0 ; enter with this received character
JMP TEKEMU ; Jump to Tektronix Emulator, al=null
atrsm10:ret
; Heath-19 ESC [ > Ps h or l where Ps = 1, 4, 7, or 9. [jrd]
htrsm1: cmp al,1 ; 25th line?
jne htrsm4 ; ne = no
mov al,modeset ; set/reset flag
mov h19l25,al
cmp al,0 ; resetting? Mods from Dave Tweten
jne htrsmx ; ne = no, enabling. we are done
mov ah,byte ptr low_rgt+1 ; point to status (25th) line
inc ah ; which is here
xor al,al ; from column 0
mov bh,ah ; to same line
mov bl,crt_cols ; physical width
dec bl ; we count from 0
jmp atsclr ; disabling status line clears it
htrsm4: cmp al,4 ; block/line cursor?
jne htrsm5 ; ne = no
and h19ctyp,4 ; save on/off bit (4)
cmp modeset,0 ; reset?
je htrsm4a ; e = yes
or h19ctyp,2 ; remember block kind here
jmp atsctyp
htrsm4a:or h19ctyp,1 ; remember underline kind here
jmp atsctyp
htrsm5: cmp al,5 ; on/off cursor?
jne htrsm7 ; ne = no
cmp modeset,0 ; on?
je htrsm5a ; e = yes
or h19ctyp,4 ; remember off state in this bit
jmp atsctyp
htrsm5a:and h19ctyp,not 4 ; set cursor on
jmp atsctyp
htrsm7: cmp al,7 ; alternate application keypad?
jne htrsm9 ; ne = no
mov al,deckpam ; get keypad application mode bit
jmp atrsflg ; set or reset appl keypad mode
htrsm9: cmp al,9 ; auto newline mode? (add cr to lf)
jne htrsmx ; ne = no
mov al,anslnm ; get the bit
jmp atrsflg ; set or reset newline mode
htrsmx: ret ; ignore the code
atrsflg:cmp modeset,0 ; Want to reset
je atrsf1 ; Yes - reset it.
or ansflgs,al ; No, set. OR in the flag
test al,decanm ; Changing terminal type? [jrd]
jz atrsfx ; z = no [jrd]
cmp flags.vtflg,ttheath ; in Heath-19 mode? [jrd]
je atrsfx ; e = yes, don't flip terminal kinds.
mov flags.vtflg,ttvt100 ; say VT100 now. [jrd]
jmp short atrsfx
atrsf1: not al ; Complement
and ansflgs,al ; Clear the bit
not al ; recover the bit. [jrd]
test al,decanm ; Changing terminal type? [jrd]
jz atrsfx ; z = no
cmp flags.vtflg,ttheath ; in Heath-19 mode? [jrd]
je atrsfx ; e = yes, don't flip terminal kinds.
mov flags.vtflg,ttvt52 ; say VT52 now. [jrd]
atrsfx: push ax
mov al,yflags
call telmsy ; tell msy file about new state
pop ax
ret
atrsom: cmp modeset,0 ; Clearing DEC origin mode?
jne atrsom1 ; ne = no, setting
and ansflgs,not (decom) ; clear the bit
mov dx,0 ; go to the home position
jmp atscu5 ; set cursor and return
atrsom1:or ansflgs,decom ; Set Origin mode
mov dx,cursor ; Get the cursor
mov dl,0 ; go to right margin
mov dh,mar_top ; go to home of scrolling region
jmp atscu5 ; Set the cursor and return
atrsscnm:
cmp modeset,0 ; Setting or resetting?
je atrss1 ; Do reset.
test ansflgs,decscnm ; Setting. Is it set already?
jnz atrss3 ; Yes. Don't do it again.
or ansflgs,decscnm ; No. Set it.
or vtemu.vtflgop,vsscreen ; tell Status display
or vtflags,vsscreen ; and our local flags
mov al,att_reverse ; Want reverse video.
jmp short atrss2 ; Do it.
atrss1: test ansflgs,decscnm ; Resetting. Is it reset already?
jz atrss3 ; Yes. Don't do it again.
and ansflgs,not decscnm ; No. Clear it.
and vtemu.vtflgop,not vsscreen ; tell Status display
and vtflags,not vsscreen ; and our local flags
mov al,att_normal ; Want normal video.
; Fall through to atrss2...
; Note: This is also called from the stblmds initialization routine.
atrss2: push ax
mov scbattr,al ; Set screen background attribute
mov oldbatr,al ; update long term memory too.
mov ah,al ; place where brkatt works
call brkatt ; separate color and specials
rol ah,1 ; Reverse the reversal (sic.)
rol ah,1 ; Reverse the reversal (sic.)
rol ah,1 ; Reverse the reversal (sic.)
rol ah,1 ; Reverse the reversal (sic.)
call addatt ; put blink/bold bits back in
mov mlbattr,ah ; For mode line background
mov ah,curattr ; Get current cursor attribute
call brkatt ; Break it up
rol ah,1 ; Reverse its background
rol ah,1 ; Reverse its background
rol ah,1 ; Reverse its background
rol ah,1 ; Reverse its background
call addatt ; Put it back together.
mov curattr,ah ; And store it.
pop ax
call revscn ; Reverse everything on the screen.
atrss3: ret
atctst: mov al,0 ; Init test weight
mov di,offset atcts2 ; Routine to call
call atreps ; Repeat for all parms
test al,80H ; Want to reset?
jz atcts1 ; No - return.
call atreset ; Yes - reset everything.
atcts1: ret
atcts2: mov ah,ansargs[si] ; Pick up an argument.
cmp ah,0 ; Zero?
jne atcts3 ; No - ignore others.
or al,80H ; Yes - say we want reset
atcts3: ret
; VT52 compatibility mode routines.
; Return to ANSI mode.
v52ans: or ansflgs,decanm ; Turn ANSI flag back on.
mov flags.vtflg,ttvt100 ; Say VT100 now. [jrd]
call chrdef ; Set default char sets.
call atsc ; Save cursor status.
call disleds ; Put "LEDs" back.
jmp atnorm ; Reset state to normal and return.
; Reset VT52 (does NOT cause return to VT100 mode). [jrd]
v52ris: call atreset ; Reset everything.
call disleds ; Put "LEDs" back.
ret
; Enter VT52 "graphics" mode.
v52egm: call chrsgs ; Set "graphics" char set.
jmp atnorm ; Reset state to normal and return.
; Exit VT52 "graphics" mode.
v52xgm: call chrdef ; Set default character set.
jmp atnorm ; Reset state to normal and return.
; VT52 cursor positioning.
v52pos: mov ttstate,offset v52pc1 ; Next state.
ret
v52pc1: sub al,' '-1 ; Minus offset.
mov ansargs,al ; Stash it here.
mov ttstate,offset v52pc2 ; Next state.
ret
v52pc2: sub al,' '-1 ; Minus offset.
mov ansargs+1,al ; Stash here.
call atnorm ; Reset state to "normal".
jmp atcup ; Position and return.
; VT52 print controls
v52apb: mov ansargs,5 ; Enter auto print mode
or ansflgs,decmode ; simulate ESC [ ? 5 i
jmp ansprt ; process command
v52ape: mov ansargs,4 ; Exit auto print mode
or ansflgs,decmode ; simulate ESC [ ? 4 i
jmp ansprt ; process command
v52pcb: mov ansargs,5 ; Enter printer controller on
and ansflgs,not decmode ; simulate ESC [ 5 i
jmp ansprt ; process command
v52pce: mov ansargs,4 ; Exit printer controller on
and ansflgs,not decmode ; simulate ESC [ 4 i
jmp ansprt ; process command
v52ps: mov ansargs,0 ; print screen
and ansflgs,not decmode ; simulate ESC [ 0 i
jmp ansprt ; process command
v52pl: mov ansargs,1 ; print line
or ansflgs,decmode ; simulate ESC [ ? 1 i
jmp ansprt ; process command
; Heath-19 special functions [jrd]
h19ans: or ansflgs,decanm ; Turn on ANSI flag. ESC <
call chrdef ; Set default char sets.
jmp atnorm ; Reset state to normal and return.
; do several "ESC [" ANSI commands
; but don't change terminal types
h19ansa:jmp atcsi ; parse ansi arguments.
; clear screen and go home
h19clrs:mov dx,0 ; go to upper left corner
call atscu5 ; do it
mov ax,0 ; clear screen from (0,0)
mov bh,byte ptr low_rgt+1 ; to lower right corner
mov bl,crt_cols ; physical width
dec bl ; we count from 0
jmp atsclr
; cursor down (scrolls)
h19cud: mov dx,cursor ; get cursor position
inc dh ; say next row down
call atccic ; check position cursor (scrolls)
mov cursor,dx
call ax ; do scrolling
jmp atscu5
; cursor forward (right). ESC C
h19cuf: mov dx,cursor ; get cursor position
inc dl ; move cursor right
cmp dl,byte ptr low_rgt ; beyond right margin
jb h19cuf1 ; b = no. do it
test ansflgs,decawm ; wrap mode on?
jz h19cuf2 ; z = no. just ignore movement
xor dl,dl ; set to left margin
inc dh ; and down a row
call atccic ; adjust position
call ax ; call scrolling routine
h19cuf1:jmp atscu5 ; do positioning and return
h19cuf2:ret ; just return
; set line wrap on
h19wrap:or ansflgs,decawm ; turn on the flag
jmp atnorm
; turn off line wrap
h19nowrp:and ansflgs,not decawm ; turn off the flag
jmp atnorm
h19erb: mov bx,cursor ; erase home to cursor, incl.
xor ax,ax ; home
jmp atsclr ; clear the area, cursor stays put???
h19erl: mov bx,cursor ; erase whole line
mov ax,bx ; get row
xor al,al ; column 0
mov bl,crt_cols ; physical width
dec bl ; we count from 0
jmp atsclr ; erase whole line, cursor stays put
h19ero: mov bx,cursor ; erase start of line to cursor
mov ax,bx
xor al,al ; start in column 0
jmp atsclr ; clear that part of line
h19herv:cmp video_state,0 ; is video normal? ESC p
jne h19hrv1 ; ne = no, reversed already, ignore
mov ah,curattr ; current cursor attributes
call brkatt ; breakup attributes byte
rol ah,1 ; reverse foreground to background
rol ah,1
rol ah,1
rol ah,1
call addatt ; put things together again
mov curattr,ah ; and store it
mov video_state,1 ; say we are reversed
h19hrv1:ret
h19hxrv:cmp video_state,0 ; is video normal? ESC q
je h19hxr1 ; e = yes, so just ignore
mov ah,curattr ; current cursor attributes
call brkatt ; breakup attributes byte
rol ah,1 ; reverse foreground to background
rol ah,1
rol ah,1
rol ah,1
call addatt ; put things together again
mov curattr,ah ; and store it
mov video_state,0 ; say we are normal
h19hxr1:ret
h19mbr: mov ttstate,offset hmbr ; Modify baud rate ESC r char
ret ; setup to parse next char
hmbr: jmp atnorm ; discard char (in al)
htsc: cmp flags.vtflg,ttheath ; Heath-19? ESC [ s
jne htscx ; ne = no, ignore
call atsc ; store cursor position and attr.
htscx: jmp atnorm ; reset state & return
htrc: cmp flags.vtflg,ttheath ; Heath-19? ESC [ u
jne htrcx ; ne = no, ignore
call atrc ; restore cursor pos and attr.
htrcx: jmp atnorm ; reset state & return
; Heath-19 set mode "ESC x "
h19smod:mov ttstate,offset hsmod ; setup to parse rest of seq
ret
hsmod: mov modeset,1 ; say set mode
mov ttstate,offset atnrm
sub al,'0' ; remove ascii bias
jmp htrsm1 ; perform mode set
h19cmod:mov ttstate,offset hcmod ; setup to parse rest of seq
ret
hcmod: mov modeset,0 ; say reset mode
mov ttstate,offset atnrm
sub al,'0' ; remove ascii bias
jmp htrsm1 ; perform mode reset
htrest: cmp flags.vtflg,ttheath ; Heath-19? ESC [ z
jne htrestx ; ne = no, ignore
call atreset ; do a hard reset
htrestx:jmp atnorm ; reset state and return
hrcup: mov al,escape ; send "ESC Y row col" cursor report
call prtbout ; send with no local echo
mov al,'Y'
call prtbout
mov al,byte ptr cursor+1 ; get row
add al,' ' ; add ascii bias
call prtbout ; send it
mov al,byte ptr cursor ; get column
add al,' ' ; add ascii bias
call prtbout ; and send it too
jmp atnorm ; return to terminal mode
; Heath-19 and VT102 additions [jrd]
inslin: cmp ansargs,0 ; insert line(s). Any args? [jrd]
jne insli1 ; ne = yes. If no arg use 1
mov ansargs,1 ; insert one line.
insli1: mov dx,cursor ; current position
cmp dh,mar_bot ; below bottom margin?
jae insli3 ; ae = at or below bottom margin
push word ptr mar_top
mov mar_top,dh ; call present position the top
push cx ; save a reg
mov cl,ansargs ; get repeat count
xor ch,ch ; clear high byte
insli2: call atscrd ; scroll down
loop insli2 ; repeat until done (cx times)
pop cx ; restore reg
pop word ptr mar_top ; restore margins
xor dl,dl ; go to left margin
jmp atscu5 ; reposition cursor and return
insli3: ret
dellin: cmp ansargs,0 ; delete line(s). Any args? [jrd]
jne delli1 ; no arg; use 1
mov ansargs,1 ; insert one line.
delli1: mov dx,cursor ; where we are presently
cmp dh,mar_bot ; at or below bottom margin?
jae delli3 ; ae = yes.
push word ptr mar_top ; save current scrolling margins
mov mar_top,dh ; temp top margin is here
push cx ; save a reg
mov cl,ansargs ; get repeat count
xor ch,ch ; clear high byte
delli2: call atscru ; scroll up
loop delli2 ; repeat until done (cx times)
pop cx ; restore reg
pop word ptr mar_top ; restore scrolling margins.
jmp atscu5 ; restore cursor and return
delli3: ret
; Delete character(s)
atdelc: cmp ansargs,0 ; zero becomes one operation
jne atdelc1
mov ansargs,1 ; delete one char. Heath ESC N
atdelc1:mov cl,byte ptr low_rgt ; number of columns on screen.
mov dx,cursor ; get present cursor position
push bx
mov bl,dh ; get row
mov bh,0
cmp linetype [bx],0 ; single width line?
je atdelc5 ; e = yes
shl dl,1 ; double the column number
mov bl,ansargs
shl bl,1 ; double # chars to delete
mov ansargs,bl
atdelc5:pop bx
test usevb,1 ; video board in use?
jz atdelv1 ; z = no
sub cl,dl ; end of screen - current column #
xor ch,ch ; cx = number of chars to move
cmp cx,0 ; zero means just this char
ja atdelc4
inc cx ; say one, this one
atdelc4:push es
push cx ; save word count for Topview
cld
call scrloc ; compute current cursor location
mov di,ax ; temporary storage places
mov si,ax
mov al,ansargs ; get delete count
xor ah,ah ; clear high byte of delete count
cmp al,cl ; clear more than rest of line?
jb atdelc2 ; b = no. some chars left at end
mov al,cl ; say delete all to right, inclusive
atdelc2:cmp al,0 ; zero?
jne atdelc3
inc al ; none or 0 impiles one.
atdelc3:shl ax,1 ; double: char and its attribute byte
push di ; destination offset
add ax,si ; src offset = dest + # deleted words
push ax ; save it
call scroff
call scrseg ; pick up screen segment
mov si,di ; align memory addresses
pop ax ; recover source offset
add si,ax ; add to starting memory address
pop ax ; recover destination offset
add di,ax ; add to destination memory address
push ds ; save ds around the move
push es ; move es into ds to
pop ds ; make ds point to screen memory too
rep movsw
pop ds ; recover normal ds
pop cx ; count for Topview
call scrsync ; synch Topview
pop es
call scron
jmp short atdelv2
; modify to use Sanyo bios sideways shift [begin jhw]
; (can't write to video RAM)
atdelv1:mov al,ansargs ; no. of positions to shift
mov ah,73h ; Sanyo bios sideways scroll
mov cx,dx ; cursor position -- now
mov dl,79 ; end of line coord. in dx
mov bh,scbattr ; attribute for cleared position
int screen ; [end jhw]
atdelv2:
mov ax,cursor ; get current row
mov bx,cursor
mov bl,byte ptr low_rgt ; last col on screen
mov al,bl
sub al,ansargs ; minus number of locations cleared
inc al
call atsclr ; clear end of line
atdelcx:mov dx,cursor
jmp atscu5 ; reposition cursor
inschr: mov dx,cursor ; open one char space in current line
test usevb,1 ; video board in use?
jnz insv1 ; nz = yes
push ax ;
mov al,1 ; shift one space (for use later)
insv1:
push bx
mov bl,dh ; get row
mov bh,0
cmp linetype [bx],0 ; single width line?
je insch2 ; e = yes
shl dl,1 ; double the column number
test usevb,1 ; video board in use?
jnz insv2 ; nz= yes
mov al,2 ; and the number of cols to shift
insv2:
insch2: pop bx
mov ch,0
mov cl,byte ptr low_rgt ; number of columns on screen
push dx
mov dh,0
sub cx,dx ; compute distance to end
pop dx
or cx,cx
jle insch1 ; le = nothing to move... [dlk]
test usevb,1 ; video board in use?
jz insv3 ; z = no
mov dl,byte ptr low_rgt
dec dl ; last col to move
push ax ; save regs
push es ; ditto
push cx ; save count for Topview
call scrloc ; compute position of end of line-1
push ax ; save offset
std ; remember to move backward
call scroff ; turn off color screen
call scrseg ; get memory address in es:di
pop ax ; recover offset
add di,ax ; source memory address
mov si,di ; align addresses. destination
add di,2 ; is one char over
push di
push ds ; save ds around move
push es ; put es into ds
pop ds ; ds points to screen memory too
rep movsw
pop ds ; recover normal ds
cld ; reset direction to be forward
pop di
pop cx ; count for Topview
call scrsync ; synch Topview
pop es ; restore regs
pop ax ; ditto
call scron ; turn on screen again
cld ; reset direction
jmp short insv4
; use bios calls since Sanyo can't write
; to video RAM [begin jhw]
insv3: mov ah,72h ; Sanyo sideways bios scroll
mov cx,dx ; set left end of scroll region
mov dl,79 ; set right end
mov bh,scbattr ; attributes of cleared region
int screen ; [end jhw]
insv4:
insch1: mov dx,cursor
test usevb,1 ; video board in use?
jnz insv5 ; nz = yes
pop ax ; [jhw]
insv5:
jmp atscu5 ; position cursor
noins: mov insmod,0 ; turn off insert mode
jmp atnorm ; and return
entins: mov insmod,0ffh ; enter insert mode...
jmp atnorm ; and return
ansich proc near ; ANSI insert characters ESC [ @
cmp ansargs,0 ; any arguments?
jne ansic1 ; ne = no, ignore
mov ansargs,1 ; use one
ansic1: push dx ; save cursor
mov insmod,1 ; enter insert mode
push cx
mov cl,ansargs ; get count of inserts
mov ch,0
push ax ; save char
ansic2: push cx ; save counter
mov al,' ' ; character to write
call atnrm ; do display
pop cx ; recover counter
loop ansic2 ; do cx times
pop ax ; restore char
pop cx
mov insmod,0 ; turn off insert mode
pop dx ; get original cursor
jmp atscu5 ; set cursor
ansich endp
; routines supporting scrolling and double width/height chars [jrd]
atscru proc near ; scroll screen up one line
push ax ; assumes dx holds cursor position
push bx ; returns with dx = old row, new col
push cx
xor ch,ch
mov cl,mar_bot ; bottom line to move
xor bh,bh
mov bl,mar_top ; top line to move
sub cx,bx ; cx = number of lines to move
jcxz atscru2 ; cx = 0. nothing to do
atscru1:mov al,linetype[bx+1]
mov linetype[bx],al ; move line types up one line
inc bx
loop atscru1
mov linetype[bx],0 ; clear new line's type
; reindex column of cursor
cmp linetype[bx-1],0 ; was old bottom line double wide?
je atscru2 ; e = no
shr dl,1 ; reindex to single wide columns
atscru2:pop cx
pop bx
pop ax
test anspflg,vtcntp ; controller print active?
jz atscru3 ; z = no, ok to change screen
ret ; else keep screen intact
atscru3:jmp vtscru ; call & ret the msy scroll routine
atscru endp
atscrd proc near ; scroll screen down one line
push ax ; assumes dx holds cursor position
push bx ; returns with dx = old row, new col
push cx
xor ch,ch
mov cl,mar_top ; top line to move
xor bh,bh
mov bl,mar_bot ; bottom line to move
sub cx,bx
neg cx ; cx = number of lines to move
jcxz atscrd2 ; cx = 0. nothing to do
atscrd1:mov al,linetype[bx-1]
mov linetype[bx],al ; move line types down one line
dec bx
loop atscrd1
mov linetype[bx],0 ; clear new line's type
; reindex column of cursor
cmp linetype[bx+1],0 ; was old top line double wide?
je atscrd2 ; e = no
shr dl,1 ; reindex to single wide columns
atscrd2:pop cx
pop bx
pop ax
test anspflg,vtcntp ; controller print active?
jz atscrd3 ; z = no, ok to change screen
ret ; else keep screen intact
atscrd3:jmp vtscrd ; call & ret the msy scroll routine
atscrd endp
linesgl proc near ; convert line to single width char
push ax
push bx
push cx
push dx
mov bx,cursor
mov bl,bh
xor bh,bh ; bx now holds row
cmp linetype [bx],0 ; is line already single width?
je linsglx ; e = yes
mov linetype [bx],0 ; say will be single now.
call scroff ; turn off video
mov dx,cursor
mov dl,0 ; start in column 0
mov cx,40 ; number of columns to do
linsgl1:push cx ; save loop counter
shl dl,1 ; double column number
mov ah,2 ; set cursor
xor bh,bh ; page 0
int screen
mov ah,8 ; read char and attribute
int screen
push ax ; save char and attribute
shr dl,1 ; restore column
mov ah,2 ; set cursor
int screen
pop ax ; recover char and attribute
mov bl,ah ; set attribute
mov cx,1 ; one char
mov ah,9 ; write char and attribute
int screen
inc dl ; next column
pop cx
loop linsgl1
mov cx,40
mov dl,40
mov ah,2 ; set cursor
int screen
mov bl,scbattr ; screen background
mov al,' '
mov ah,9 ; write char
int screen ; write 40 spaces
call scron ; turn on the video
linsglx:pop dx
pop cx
pop bx
pop ax
jmp atscur ; update cursor and return
linesgl endp
linedbl proc near ; convert line to double width char
push ax ; must reset physical cursor
push bx ; to same char as before expansion
push cx ; but does not modify variable cursor
push dx
mov bx,cursor
mov bl,bh
xor bh,bh ; bx now holds row
cmp linetype [bx],0 ; is line single width?
jne lindblx ; ne = no. nothing to do
mov linetype [bx],1 ; say will be double width now.
mov dx,cursor
mov dl,39 ; start with col 39
mov cx,40
call scroff ; turn off the video
lindbl1:push cx ; save loop counter
mov ah,2 ; set cursor
mov bh,0 ; page 0
int screen
mov ah,8 ; read char and attribute
int screen
push ax ; save char and attribute
shl dl,1 ; double the column number
mov ah,2 ; set cursor
int screen
pop ax ; recover char and attribute
mov bl,ah ; set attribute
mov cx,1 ; one char
mov ah,9 ; write char and attribute
int screen
inc dl ; move to second column of double.
mov ah,2 ; set cursor
int screen
mov al,' ' ; space as filler
mov ah,9 ; write that char
int screen
dec dl
shr dl,1
dec dl
pop cx
loop lindbl1
call scron ; turn on the video
lindblx:pop dx
pop cx
pop bx
pop ax
jmp atscur ; update the cursor and return
linedbl endp
anstty endp
ansprt proc near ; printer support routines. [jrd]
cmp ansargs,0 ; 0 (print all/part of screen)?
jne ansprt1 ; ne = no
call pntchk ; check printer
jc ansprtx ; c = printer not ready
call pntext ; do whole screen or scrolling extent
jmp atscu5 ; reposition cursor and return
ansprt1:cmp ansargs,1 ; 1 (print current line)?
jne ansprt4 ; ne = no
call pntchk ; check for printer ready
jc ansprtx ; c = printer not ready
call pntlin ; print current line
anspr1a:jmp atscu5 ; reposition cursor and return
ansprt4:cmp ansargs,4 ; auto print disable?
jne ansprt5 ; ne = no
test ansflgs,decmode ; was it ESC [ ? 4 i
jz anspr4a ; z = no, so it was ESC [ 4 i
test anspflg,vtautop ; check state of print flag
jz anspr4a ; z = off already
call trnprs ; toggle mode line PRN indicator
and anspflg,not vtautop ; auto-print disable
anspr4a:jmp ansprtx
ansprt5:cmp ansargs,5 ; auto print enable?
jne ansprtx ; ne = no
call pntchk ; check printer, ignore carry ret
jc ansprtx ; c = printer not ready
test ansflgs,decmode ; was it ESC [ ? 5 i
jz anspr5a ; z = no
test anspflg,vtautop ; is print already enabled?
jnz ansprtx ; nz = yes, leave trnprs intact
call trnprs ; toggle on mode line PRN indicator
or anspflg,vtautop ; auto-print enabled
jmp short ansprtx
anspr5a:or anspflg,vtcntp ; controller print enabled
ansprtx:jmp atnorm
ansprt endp
; State machine active while Media Copy On (Print Controller ON). Copies all
; chars to the printer until (and excluding) Media Copy Off (ESC [ 4 i) has
; been received or the emulator reset. New char is in al. 6 March 1987 [jrd]
ansmc proc near
mov ah,al ; copy active character
and ah,7fh ; strip high bit
cmp ah,byte ptr mcoff ; start of MC Off sequence?
jne ansmc1 ; ne = no
call ansmc4 ; playback previously matched chars
mov mccnt,1 ; count matched chars (one now)
mov mcoffs,al ; save full character, with high bit
jmp short ansmcx ; and exit
ansmc1: push bx ; check for char in MC Off sequence
mov bx,mccnt ; number of chars matched in MC Off
mov mcoffs[bx],al ; save this char, with high bit
cmp ah,byte ptr mcoff[bx] ; match expected char in sequence?
pop bx
jne ansmc3 ; ne = no, play back partial match
inc mccnt ; count new match
cmp mccnt,mcofflen ; matched all char in sequence?
jne ansmcx ; ne = not yet, wait for more
and anspflg,not vtcntp ; yes, disable print controller
mov mccnt,0 ; clear counter
jmp short ansmcx ; all done
ansmc3: call ansmc4 ; playback previously matched chars
call pntchr ; print current char, ignore errors
mov mccnt,0 ; reset to no match and exit
ansmcx: ret ; common exit
; local worker procedure
ansmc4: push ax ; save break char (in al)
push cx ; playback partial sequence to printer
mov cx,mccnt ; number of chars matched before break
jcxz ansmc4b ; z = none
push si
mov si,offset mcoffs ; string to be played back
cld
ansmc4a:lodsb ; get a char into al
call pntchr ; print it, ignore errors
loop ansmc4a ; do all that came in previously
pop si
ansmc4b:pop cx
pop ax ; recover break char
ret
ansmc endp
; Check for PRN (DOS's printer) being ready. If ready, return with C clear.
; Otherwise, write Not Ready msg on mode line and return with C bit set.
; N.B. DOS Critical Error will occur here if PRN is not ready. [jrd]
pntchk proc near
push dx
push cx
push ax
mov cx,10 ; ten retries before declaring error
pntchk0:mov ah,ioctl ; get printer status, via DOS
mov al,7 ; status for output
push bx
mov bx,4 ; std handle for system printer
int dos
pop bx
jc pntchk1 ; c = call failed
cmp al,0ffh ; code for Ready
je pntchk3 ; e = yes, assume printer is ready.
pntchk1:push cx ; save counter, just in case
mov ax,100 ; wait 100 millisec
call pcwait
pop cx
loop pntchk0 ; and try a few more times
test yflags,modoff ; is mode line off?
jnz pntchk2 ; nz = off, skip msg
push bx
push si
mov si,offset pntmsg ; say printer not ready
mov cx,pntmsgl ; length
call modwrt ; write alternate mode line, in msy
pop si
pop bx
pntchk2:pop ax
pop cx
pop dx
stc ; say printer not ready
ret
pntchk3:pop ax
pop cx
pop dx
clc ; say printer is ready
ret
pntchk endp
; Print on PRN the char in register al. On success return with C bit clear.
; On failure call procedure pntchk and return its C bit (typically C set).
pntchr proc near
push dx
push ax
mov ah,lstout ; uses file handle 4
mov dl,al
int dos
pop ax
pop dx
jnc pntchr2 ; nc = success
call pntchk ; c = error (printer not ready)
pntchr2:ret
pntchr endp
pntlin proc near ; print whole line given by dx
push ax
push bx
push cx
push dx
xor dl,dl ; start in column 0
xor ch,ch
mov cl,byte ptr low_rgt ; number of columns
mov dl,cl ; Bios column counter
inc cl ; actual line length, count it down
pntlin1:mov ah,2 ; set cursor
xor bh,bh ; page 0
int screen
mov ah,8 ; read char (al) and attribute (ah)
int screen
cmp al,' ' ; is this a space?
jne pntlin2 ; no, we have the end of the line
dec dl ; else move left one column
loop pntlin1 ; and keep looking for non-space
pntlin2:jcxz pntlin4 ; z = empty line
xor dl,dl ; start in column 0, do cl chars
pntlin3:mov ah,2 ; set cursor
xor bh,bh ; page 0
int screen
mov ah,8 ; read char and attribute
int screen
inc dl ; inc to next column
call pntchr ; print the char (in al)
jc pntlin5 ; c = printer error
loop pntlin3 ; do cx columns
pntlin4:mov al,cr ; add trailing cr/lf for printer
call pntchr
jc pntlin5
mov al,lf
call pntchr
pntlin5:pop dx
pop cx
pop bx
pop ax
ret ; C bit controlled by pntchr
pntlin endp
pntext proc near ; print an extent of lines, depending
push ax ; on flag bit vtextp.
push bx
push dx
xor dx,dx ; assume starting at top left
mov bx,low_rgt ; and extending to lower right
test anspflg,vtextp ; full screen wanted?
jnz pntext1 ; nz = yes, else scrolling region
mov dh,mar_top ; top of scrolling region
mov bh,mar_bot ; bottom of scrolling region
pntext1:call pntlin ; print a line
jc pntext2 ; c = printer error
inc dh
cmp dh,bh ; done all requested lines?
jbe pntext1 ; be = not yet, do another
test anspflg,vtffp ; form feed needed at end?
jz pntext2 ; z = no.
mov al,ff
call pntchr ; print the form feed char
pntext2:pop dx
pop bx
pop ax
ret
pntext endp
code ends
if1
%out [End of pass 1]
else
%out [End of assembly]
endif
end